diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
 # gitignore for Conjure
 #
-# Part of Conjure, Copyright 2021  Rudy Matela,
+# Part of Conjure, Copyright 2021-2024  Rudy Matela,
 # distribued under the 3-clause BSD license.
 
 # temporary files
@@ -33,6 +33,7 @@
 eg/bools
 eg/count
 eg/dupos
+eg/either
 eg/factorial
 eg/fibonacci
 eg/fib01
@@ -41,6 +42,8 @@
 eg/ints
 eg/gcd
 eg/list
+eg/maybe
+eg/oddeven
 eg/pow
 eg/tapps
 eg/tree
@@ -54,11 +57,11 @@
 bench/longshot
 bench/ill-hit
 bench/take-drop
-bench/lots
 bench/p12
 bench/p30
 bench/candidates
 bench/redundants
+bench/erroneous
 bench/gps
 bench/gps2
 bench/lowtests
@@ -68,6 +71,6 @@
 test/expr
 test/conjurable
 test/utils
-test/cases
 test/defn
 test/derive
+test/red
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2021, Rudy Matela
+Copyright (c) 2021-2024, Rudy Matela
 
 All rights reserved.
 
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,7 @@
   eg/arith \
   eg/count \
   eg/dupos \
+  eg/either \
   eg/factorial \
   eg/fibonacci \
   eg/fib01 \
@@ -23,6 +24,8 @@
   eg/bools \
   eg/gcd \
   eg/list \
+  eg/maybe \
+  eg/oddeven \
   eg/pow \
   eg/replicate \
   eg/setelem \
@@ -34,6 +37,7 @@
   eg/bst \
   bench/candidates \
   bench/redundants \
+  bench/erroneous \
   bench/ill-hit \
   bench/longshot \
   bench/lowtests \
@@ -51,21 +55,30 @@
   test/expr \
   test/defn \
   test/conjurable \
+  test/derive \
+  test/red \
   test/utils
 
 all: mk/toplibs
 
 all-all: all $(EG) $(TESTS)
 
-test: $(TESTS) $(patsubst %,%.run,$(TESTS)) diff-test test-sdist
+test: test-makefile $(TESTS) $(patsubst %,%.run,$(TESTS)) diff-test test-sdist
 
+ghci: src/Conjure.ghci
+
+tags: src test/Test.hs
+	hasktags $^
+
+# Disclaimer: This bench target is not intended to generate paper-grade runtime
+#             datapoints as it runs each benchmark just once.  This target is
+#             meant to track large runtime changes across different git
+#             versions.
 .PHONY: bench
 bench: $(EG) $(patsubst %,%.bench,$(EG))
 	@mkdir -p bench/runtime/$$HOSTNAME
 	./bench/versions | tee bench/runtime/$$HOSTNAME/versions
 
-ghci: src/Conjure.ghci
-
 %.bench: %
 	@mkdir -p bench/runtime/$$HOSTNAME/`dirname $<`
 	@printf "%-18s " $<
@@ -73,13 +86,17 @@
 	python3 -c 'print("%.1f" % float(input()))' | \
 	tee bench/runtime/$$HOSTNAME/$<.runtime
 
-diff-test: $(EG) $(patsubst %,%.diff-test,$(EG))
+diff-test: $(EG) $(patsubst %,%.diff,$(EG))
 
-out: $(EG) $(patsubst %,%.out,$(EG))
+out: txt
 
+txt: $(EG) $(patsubst %,%.txt,$(EG))
+
 test-sdist:
 	./test/sdist
 
+test-makefile: test/mk.run
+
 test-via-cabal:
 	cabal configure --enable-tests --enable-benchmarks --ghc-options="$(GHCFLAGS) -O0"
 	cabal build
@@ -97,15 +114,15 @@
 %.run: %
 	./$<
 
-%.out: %
-	./$< >$<.out
+%.txt: %
+	./$< >$<.txt
 
-%.diff-test: %
-	./$< | diff -rud $<.out -
+%.diff: %
+	./$< | diff -rud $<.txt -
 
 # lists files missing copyright notices
 list-missing-copyright:
-	grep -LRE '(Copyright|\(C\))' `git ls-tree -r master --name-only | grep -vE '(\.(runtime|out)|versions|toplibs|(Toplibs|All)\.hs|depend.mk)$$'` || true
+	grep -LRE '(Copyright|\(C\))' `git ls-tree -r master --name-only | grep -vE '(\.(runtime|txt)|versions|toplibs|(Toplibs|All)\.hs|depend.mk)$$'` || true
 
 # NOTE: (very hacky!) the following target allows parallel compilation (-jN) of
 # eg and test programs so long as they don't share dependencies _not_ stored
@@ -133,5 +150,10 @@
 gps2-each: bench/gps2
 	for i in {1..25}; do ./bench/time ./bench/gps2 $$i; done
 
+ls-eg:
+	@for eg in $(EG); do echo $$eg; done
+
+ls-test:
+	@for test in $(TESTS); do echo $$test; done
 
 include mk/haskell.mk
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -347,7 +347,7 @@
 [PushGP]: https://github.com/lspector/Clojush
 [G3P]: https://github.com/t-h-e/HeuristicLab.CFGGP
 
-[PushGP] (2002) and [G3P] (2017) are genetic programming systems 
+[PushGP] (2002) and [G3P] (2017) are genetic programming systems
 that are able to synthesize programs in Push and Python respectively.
 Differently from Conjure or MagicHaskeller,
 they require around a hundred tests for traning
@@ -368,7 +368,7 @@
 contains more than 60 examples of use.
 
 
-Conjure, Copyright 2021  Rudy Matela,
+Conjure, Copyright 2021-2024  Rudy Matela,
 distribued under the 3-clause BSD license.
 
 
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,5 +1,5 @@
 -- Setup.hs for code-conjure / Conjure
--- Part of Conjure, Copyright 2021  Rudy Matela,
+-- Part of Conjure, Copyright 2021-2024  Rudy Matela,
 -- distribued under the 3-clause BSD license.
 import Distribution.Simple
 main = defaultMain
diff --git a/TODO.md b/TODO.md
--- a/TODO.md
+++ b/TODO.md
@@ -3,29 +3,27 @@
 
 A non-exhaustive list of things TO DO for Conjure.
 
-* Review `bench/redundants.out` and prune redundant candidates.
-  See sections below for ideas.
+* improve documentation of `conjureIsDeconstruction`.
+  Document behaviour outside of function, not inside of it.
 
+* `bench/erroneous`: report number of errors in addition to the example error
 
-## Prune modulo rewriting
+* consider non top-level cases
 
-The following is redundant, as only the second equation is necessary:
 
-	foo 0  =  0
-	foo x  =  x + x
-
-Another example is:
-
-	foo 0  =  1
-	foo x  =  x + 1
+## Non top-level cases
 
-The tricky part is when dealing with multiple arguments:
+Consider allowing non top-level cases,
+so that functions like the following are reachable:
 
-	x ? 0  =  x
-	x ? y  =  x + y
+	last []  =  undefined
+	last [x]  =  x
+	last (x:y:xs)  =  last (y:xs)
 
-One possible path would be to replace 0 in the second equation
-then use the Theory to discover x + 0 is equal to 0.
+Perhaps the negative runtime impact would not be so great
+given the delayed tiers enumeration,
+and we would avoid some `prif` hacks
+needed to conjure some functions.
 
 
 This file is part of Conjure,
diff --git a/bench/avgs.hs b/bench/avgs.hs
--- a/bench/avgs.hs
+++ b/bench/avgs.hs
@@ -1,6 +1,6 @@
 -- Computes averages of several benchmarks
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Data.List
 import Data.Function
diff --git a/bench/bench b/bench/bench
--- a/bench/bench
+++ b/bench/bench
@@ -2,7 +2,7 @@
 #
 # A more elaborate benchmark for p12 and p30
 #
-# Copyright (C) 2021 Rudy Matela
+# Copyright (C) 2021-2024 Rudy Matela
 # Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 run1() {
diff --git a/bench/candidates.hs b/bench/candidates.hs
--- a/bench/candidates.hs
+++ b/bench/candidates.hs
@@ -1,6 +1,6 @@
 -- print candidates
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 import Conjure.Engine
diff --git a/bench/candidates.out b/bench/candidates.out
deleted file mode 100644
--- a/bench/candidates.out
+++ /dev/null
@@ -1,6739 +0,0 @@
-Candidates for: foo :: Int -> Int
-  pruning with 15/35 rules
-  [3,0,7,0,19,0,90,0,454] direct candidates, 0 duplicates
-  [3,3,8,13,29,52,139,212,629] pattern candidates, 0 duplicates
-
-rules:
-x * y == x + y
-x * y == y + x
-x - x == 0
-x + 0 == x
-0 + x == x
-x - 0 == x
-(x + y) + z == x + (y + z)
-(x + y) + z == y + (x + z)
-x - (y - z) == z + (x - y)
-(x - y) - z == x - (y + z)
-(x - y) - z == x - (z + y)
-(x + y) - z == x + (y - z)
-(x + y) - z == y + (x - z)
-x + (y - x) == y
-(x - y) + y == x
-equations:
-y + x == x + y
-y + (x + z) == x + (y + z)
-z + (x + y) == x + (y + z)
-z + (y + x) == x + (y + z)
-y + (x - z) == x + (y - z)
-(x - z) + y == x + (y - z)
-(z - y) + x == (x - y) + z
-y - (x + y) == 0 - x
-y - (y + x) == 0 - x
-z - (y + z) == x - (x + y)
-z - (y + z) == x - (y + x)
-z - (z + y) == x - (x + y)
-z - (z + y) == x - (y + x)
-x + (0 - y) == x - y
-(0 - y) + x == x - y
-x - (x + 1) == 0 - 1
-x - (1 + x) == 0 - 1
-y - (y + 1) == x - (x + 1)
-y - (y + 1) == x - (1 + x)
-y - (1 + y) == x - (1 + x)
-
-direct candidates:
-
-foo x  =  x
-
-foo x  =  0
-
-foo x  =  1
-
-foo x  =  x + x
-
-foo x  =  x + 1
-
-foo x  =  1 + 1
-
-foo x  =  x - 1
-
-foo x  =  0 - x
-
-foo x  =  0 - 1
-
-foo x  =  1 - x
-
-foo x  =  x + (x + x)
-
-foo x  =  x + (x + 1)
-
-foo x  =  x + (1 + 1)
-
-foo x  =  x + (x - 1)
-
-foo x  =  x + (0 - 1)
-
-foo x  =  1 + (x + x)
-
-foo x  =  1 + (x + 1)
-
-foo x  =  1 + (1 + 1)
-
-foo x  =  1 + (0 - x)
-
-foo x  =  1 + (1 - x)
-
-foo x  =  x - (x + x)
-
-foo x  =  x - (x + 1)
-
-foo x  =  x - (1 + 1)
-
-foo x  =  0 - (x + x)
-
-foo x  =  0 - (x + 1)
-
-foo x  =  0 - (1 + 1)
-
-foo x  =  1 - (x + x)
-
-foo x  =  1 - (x + 1)
-
-foo x  =  1 - (1 + 1)
-
-
-pattern candidates:
-
-foo x  =  x
-
-foo x  =  0
-
-foo x  =  1
-
-foo 0  =  0
-foo x  =  1
-
-foo 0  =  1
-foo x  =  x
-
-foo 0  =  1
-foo x  =  0
-
-foo x  =  x + x
-
-foo x  =  x + 1
-
-foo x  =  x - 1
-
-foo x  =  0 - x
-
-foo x  =  1 - x
-
-foo 1  =  0
-foo x  =  x
-
-foo 1  =  0
-foo x  =  1
-
-foo 1  =  1
-foo x  =  0
-
-foo 0  =  0
-foo x  =  x + x
-
-foo 0  =  0
-foo x  =  x + 1
-
-foo 0  =  0
-foo x  =  x - 1
-
-foo 0  =  0
-foo x  =  0 - x
-
-foo 0  =  0
-foo x  =  1 - x
-
-foo 0  =  1
-foo x  =  x + x
-
-foo 0  =  1
-foo x  =  x + 1
-
-foo 0  =  1
-foo x  =  x - 1
-
-foo 0  =  1
-foo x  =  0 - x
-
-foo 0  =  1
-foo x  =  1 - x
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  1
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  x
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  0
-
-foo 0  =  0
-foo x  =  foo (x - 1)
-
-foo 0  =  0
-foo x  =  foo (0 - x)
-
-foo 0  =  0
-foo x  =  foo (1 - x)
-
-foo 0  =  1
-foo x  =  foo (x - 1)
-
-foo 0  =  1
-foo x  =  foo (0 - x)
-
-foo 0  =  1
-foo x  =  foo (1 - x)
-
-foo x  =  x + (x + x)
-
-foo x  =  x + (x + 1)
-
-foo x  =  x + (x - 1)
-
-foo x  =  1 + (x + x)
-
-foo x  =  1 + (x + 1)
-
-foo x  =  1 + (0 - x)
-
-foo x  =  1 + (1 - x)
-
-foo x  =  x - (x + x)
-
-foo x  =  x - (x + 1)
-
-foo x  =  0 - (x + x)
-
-foo x  =  0 - (x + 1)
-
-foo x  =  1 - (x + x)
-
-foo x  =  1 - (x + 1)
-
-foo 1  =  0
-foo x  =  x + x
-
-foo 1  =  0
-foo x  =  x + 1
-
-foo 1  =  0
-foo x  =  x - 1
-
-foo 1  =  0
-foo x  =  0 - x
-
-foo 1  =  0
-foo x  =  1 - x
-
-foo 1  =  1
-foo x  =  x + x
-
-foo 1  =  1
-foo x  =  x + 1
-
-foo 1  =  1
-foo x  =  x - 1
-
-foo 1  =  1
-foo x  =  0 - x
-
-foo 1  =  1
-foo x  =  1 - x
-
-foo 1  =  0
-foo x  =  foo (x - 1)
-
-foo 1  =  0
-foo x  =  foo (0 - x)
-
-foo 1  =  0
-foo x  =  foo (1 - x)
-
-foo 1  =  1
-foo x  =  foo (x - 1)
-
-foo 1  =  1
-foo x  =  foo (0 - x)
-
-foo 1  =  1
-foo x  =  foo (1 - x)
-
-foo 0  =  0
-foo x  =  x + (x + x)
-
-foo 0  =  0
-foo x  =  x + (x + 1)
-
-foo 0  =  0
-foo x  =  x + (x - 1)
-
-foo 0  =  0
-foo x  =  1 + (x + x)
-
-foo 0  =  0
-foo x  =  1 + (x + 1)
-
-foo 0  =  0
-foo x  =  1 + (0 - x)
-
-foo 0  =  0
-foo x  =  1 + (1 - x)
-
-foo 0  =  0
-foo x  =  x - (x + x)
-
-foo 0  =  0
-foo x  =  x - (x + 1)
-
-foo 0  =  0
-foo x  =  0 - (x + x)
-
-foo 0  =  0
-foo x  =  0 - (x + 1)
-
-foo 0  =  0
-foo x  =  1 - (x + x)
-
-foo 0  =  0
-foo x  =  1 - (x + 1)
-
-foo 0  =  1
-foo x  =  x + (x + x)
-
-foo 0  =  1
-foo x  =  x + (x + 1)
-
-foo 0  =  1
-foo x  =  x + (x - 1)
-
-foo 0  =  1
-foo x  =  1 + (x + x)
-
-foo 0  =  1
-foo x  =  1 + (x + 1)
-
-foo 0  =  1
-foo x  =  1 + (0 - x)
-
-foo 0  =  1
-foo x  =  1 + (1 - x)
-
-foo 0  =  1
-foo x  =  x - (x + x)
-
-foo 0  =  1
-foo x  =  x - (x + 1)
-
-foo 0  =  1
-foo x  =  0 - (x + x)
-
-foo 0  =  1
-foo x  =  0 - (x + 1)
-
-foo 0  =  1
-foo x  =  1 - (x + x)
-
-foo 0  =  1
-foo x  =  1 - (x + 1)
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  x + x
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  x + 1
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  x - 1
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  0 - x
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  1 - x
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  x + x
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  x + 1
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  x - 1
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  0 - x
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  1 - x
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  x + x
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  x + 1
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  x - 1
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  0 - x
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  1 - x
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  x + x
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  x + 1
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  x - 1
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  0 - x
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  1 - x
-
-
-Candidates for: ? :: Int -> Int -> Int
-  pruning with 10/23 rules
-  [3,3,6,9,21,39,87,180,390] direct candidates, 0 duplicates
-  [3,7,22,53,129,313,747,1743,4077] pattern candidates, 0 duplicates
-
-rules:
-x * y == x + y
-x * y == y + x
-x + 0 == x
-0 + x == x
-dec (x + y) == x + dec y
-dec (x + y) == y + dec x
-dec (x + y) == dec x + y
-dec (x + y) == dec y + x
-(x + y) + z == x + (y + z)
-(x + y) + z == y + (x + z)
-equations:
-y + x == x + y
-y + dec x == x + dec y
-dec x + y == x + dec y
-dec y + x == dec x + y
-x + dec 0 == dec x
-dec 0 + x == dec x
-y + (x + z) == x + (y + z)
-z + (x + y) == x + (y + z)
-z + (y + x) == x + (y + z)
-y + dec (dec x) == x + dec (dec y)
-dec (dec x) + y == x + dec (dec y)
-x + dec (dec 0) == dec (dec x)
-dec (dec 0) + x == dec (dec x)
-
-direct candidates:
-
-x ? y  =  x
-
-x ? y  =  y
-
-x ? y  =  0
-
-x ? y  =  dec x
-
-x ? y  =  dec y
-
-x ? y  =  dec 0
-
-x ? y  =  x + x
-
-x ? y  =  x + y
-
-x ? y  =  y + y
-
-x ? y  =  dec (dec x)
-
-x ? y  =  dec (dec y)
-
-x ? y  =  dec (dec 0)
-
-x ? y  =  dec (dec (dec x))
-
-x ? y  =  dec (dec (dec y))
-
-x ? y  =  dec (dec (dec 0))
-
-x ? y  =  x + dec x
-
-x ? y  =  x + dec y
-
-x ? y  =  x + dec 0
-
-x ? y  =  y + dec x
-
-x ? y  =  y + dec y
-
-x ? y  =  y + dec 0
-
-x ? y  =  dec (dec (dec (dec x)))
-
-x ? y  =  dec (dec (dec (dec y)))
-
-x ? y  =  dec (dec (dec (dec 0)))
-
-x ? y  =  x + (x + x)
-
-x ? y  =  x + (x + y)
-
-x ? y  =  x + (y + y)
-
-x ? y  =  x + dec (dec x)
-
-x ? y  =  x + dec (dec y)
-
-x ? y  =  x + dec (dec 0)
-
-x ? y  =  y + (x + x)
-
-x ? y  =  y + (x + y)
-
-x ? y  =  y + (y + y)
-
-x ? y  =  y + dec (dec x)
-
-x ? y  =  y + dec (dec y)
-
-x ? y  =  y + dec (dec 0)
-
-x ? y  =  dec x + dec x
-
-x ? y  =  dec x + dec y
-
-x ? y  =  dec x + dec 0
-
-x ? y  =  dec y + dec y
-
-x ? y  =  dec y + dec 0
-
-x ? y  =  dec 0 + dec 0
-
-x ? y  =  dec (dec (dec (dec (dec x))))
-
-x ? y  =  dec (dec (dec (dec (dec y))))
-
-x ? y  =  dec (dec (dec (dec (dec 0))))
-
-x ? y  =  x + dec (dec (dec x))
-
-x ? y  =  x + dec (dec (dec y))
-
-x ? y  =  x + dec (dec (dec 0))
-
-x ? y  =  x + (x + dec x)
-
-x ? y  =  x + (x + dec y)
-
-x ? y  =  x + (x + dec 0)
-
-x ? y  =  x + (y + dec x)
-
-x ? y  =  x + (y + dec y)
-
-x ? y  =  x + (y + dec 0)
-
-x ? y  =  y + dec (dec (dec x))
-
-x ? y  =  y + dec (dec (dec y))
-
-x ? y  =  y + dec (dec (dec 0))
-
-x ? y  =  y + (x + dec x)
-
-x ? y  =  y + (x + dec y)
-
-x ? y  =  y + (x + dec 0)
-
-x ? y  =  y + (y + dec x)
-
-x ? y  =  y + (y + dec y)
-
-x ? y  =  y + (y + dec 0)
-
-x ? y  =  dec x + (x + x)
-
-x ? y  =  dec x + (x + y)
-
-x ? y  =  dec x + (y + y)
-
-x ? y  =  dec x + dec (dec x)
-
-x ? y  =  dec x + dec (dec y)
-
-x ? y  =  dec x + dec (dec 0)
-
-x ? y  =  dec y + (x + x)
-
-x ? y  =  dec y + (x + y)
-
-x ? y  =  dec y + (y + y)
-
-x ? y  =  dec y + dec (dec x)
-
-x ? y  =  dec y + dec (dec y)
-
-x ? y  =  dec y + dec (dec 0)
-
-x ? y  =  dec 0 + (x + x)
-
-x ? y  =  dec 0 + (x + y)
-
-x ? y  =  dec 0 + (y + y)
-
-x ? y  =  dec 0 + dec (dec x)
-
-x ? y  =  dec 0 + dec (dec y)
-
-x ? y  =  dec 0 + dec (dec 0)
-
-
-pattern candidates:
-
-x ? y  =  x
-
-x ? y  =  y
-
-x ? y  =  0
-
-x ? y  =  dec x
-
-x ? y  =  dec y
-
-x ? 0  =  x
-x ? y  =  y
-
-x ? 0  =  x
-x ? y  =  0
-
-x ? 0  =  0
-x ? y  =  x
-
-0 ? x  =  x
-x ? y  =  0
-
-0 ? x  =  0
-x ? y  =  y
-
-x ? y  =  x + x
-
-x ? y  =  x + y
-
-x ? y  =  y + y
-
-x ? y  =  dec (dec x)
-
-x ? y  =  dec (dec y)
-
-x ? 0  =  x
-x ? y  =  dec x
-
-x ? 0  =  x
-x ? y  =  dec y
-
-x ? 0  =  0
-x ? y  =  dec x
-
-x ? 0  =  0
-x ? y  =  dec y
-
-x ? 0  =  dec x
-x ? y  =  x
-
-x ? 0  =  dec x
-x ? y  =  y
-
-x ? 0  =  dec x
-x ? y  =  0
-
-0 ? x  =  x
-x ? y  =  dec x
-
-0 ? x  =  x
-x ? y  =  dec y
-
-0 ? x  =  0
-x ? y  =  dec x
-
-0 ? x  =  0
-x ? y  =  dec y
-
-0 ? x  =  dec x
-x ? y  =  x
-
-0 ? x  =  dec x
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  y
-
-x ? y  =  dec (dec (dec x))
-
-x ? y  =  dec (dec (dec y))
-
-x ? y  =  x + dec x
-
-x ? y  =  x + dec y
-
-x ? y  =  y + dec x
-
-x ? y  =  y + dec y
-
-x ? 0  =  x
-x ? y  =  x + x
-
-x ? 0  =  x
-x ? y  =  x + y
-
-x ? 0  =  x
-x ? y  =  y + y
-
-x ? 0  =  x
-x ? y  =  dec (dec x)
-
-x ? 0  =  x
-x ? y  =  dec (dec y)
-
-x ? 0  =  0
-x ? y  =  x + x
-
-x ? 0  =  0
-x ? y  =  x + y
-
-x ? 0  =  0
-x ? y  =  y + y
-
-x ? 0  =  0
-x ? y  =  dec (dec x)
-
-x ? 0  =  0
-x ? y  =  dec (dec y)
-
-x ? 0  =  dec x
-x ? y  =  dec y
-
-x ? 0  =  x + x
-x ? y  =  x
-
-x ? 0  =  x + x
-x ? y  =  y
-
-x ? 0  =  x + x
-x ? y  =  0
-
-x ? 0  =  dec (dec x)
-x ? y  =  x
-
-x ? 0  =  dec (dec x)
-x ? y  =  y
-
-x ? 0  =  dec (dec x)
-x ? y  =  0
-
-0 ? x  =  x
-x ? y  =  x + x
-
-0 ? x  =  x
-x ? y  =  x + y
-
-0 ? x  =  x
-x ? y  =  y + y
-
-0 ? x  =  x
-x ? y  =  dec (dec x)
-
-0 ? x  =  x
-x ? y  =  dec (dec y)
-
-0 ? x  =  0
-x ? y  =  x + x
-
-0 ? x  =  0
-x ? y  =  x + y
-
-0 ? x  =  0
-x ? y  =  y + y
-
-0 ? x  =  0
-x ? y  =  dec (dec x)
-
-0 ? x  =  0
-x ? y  =  dec (dec y)
-
-0 ? x  =  x + x
-x ? y  =  x
-
-0 ? x  =  x + x
-x ? y  =  y
-
-0 ? x  =  x + x
-x ? y  =  0
-
-0 ? x  =  dec (dec x)
-x ? y  =  x
-
-0 ? x  =  dec (dec x)
-x ? y  =  y
-
-0 ? x  =  dec (dec x)
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec x
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec x
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec y
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  x
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  0
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec x
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec x
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec y
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  0
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  x
-
-x ? 0  =  x
-x ? y  =  x ? dec y
-
-x ? 0  =  x
-x ? y  =  y ? dec y
-
-x ? 0  =  x
-x ? y  =  0 ? dec y
-
-x ? 0  =  x
-x ? y  =  dec x ? x
-
-x ? 0  =  x
-x ? y  =  dec x ? y
-
-x ? 0  =  0
-x ? y  =  x ? dec y
-
-x ? 0  =  0
-x ? y  =  y ? dec y
-
-x ? 0  =  0
-x ? y  =  0 ? dec y
-
-x ? 0  =  0
-x ? y  =  dec x ? x
-
-x ? 0  =  0
-x ? y  =  dec x ? y
-
-0 ? x  =  x
-x ? y  =  x ? dec y
-
-0 ? x  =  x
-x ? y  =  y ? dec y
-
-0 ? x  =  x
-x ? y  =  dec x ? x
-
-0 ? x  =  x
-x ? y  =  dec x ? y
-
-0 ? x  =  x
-x ? y  =  dec x ? 0
-
-0 ? x  =  0
-x ? y  =  x ? dec y
-
-0 ? x  =  0
-x ? y  =  y ? dec y
-
-0 ? x  =  0
-x ? y  =  dec x ? x
-
-0 ? x  =  0
-x ? y  =  dec x ? y
-
-0 ? x  =  0
-x ? y  =  dec x ? 0
-
-x ? y  =  dec (dec (dec (dec x)))
-
-x ? y  =  dec (dec (dec (dec y)))
-
-x ? y  =  x + (x + x)
-
-x ? y  =  x + (x + y)
-
-x ? y  =  x + (y + y)
-
-x ? y  =  x + dec (dec x)
-
-x ? y  =  x + dec (dec y)
-
-x ? y  =  y + (x + x)
-
-x ? y  =  y + (x + y)
-
-x ? y  =  y + (y + y)
-
-x ? y  =  y + dec (dec x)
-
-x ? y  =  y + dec (dec y)
-
-x ? y  =  dec x + dec x
-
-x ? y  =  dec x + dec y
-
-x ? y  =  dec y + dec y
-
-x ? 0  =  x
-x ? y  =  dec (dec (dec x))
-
-x ? 0  =  x
-x ? y  =  dec (dec (dec y))
-
-x ? 0  =  x
-x ? y  =  x + dec x
-
-x ? 0  =  x
-x ? y  =  x + dec y
-
-x ? 0  =  x
-x ? y  =  y + dec x
-
-x ? 0  =  x
-x ? y  =  y + dec y
-
-x ? 0  =  0
-x ? y  =  dec (dec (dec x))
-
-x ? 0  =  0
-x ? y  =  dec (dec (dec y))
-
-x ? 0  =  0
-x ? y  =  x + dec x
-
-x ? 0  =  0
-x ? y  =  x + dec y
-
-x ? 0  =  0
-x ? y  =  y + dec x
-
-x ? 0  =  0
-x ? y  =  y + dec y
-
-x ? 0  =  dec x
-x ? y  =  x + x
-
-x ? 0  =  dec x
-x ? y  =  x + y
-
-x ? 0  =  dec x
-x ? y  =  y + y
-
-x ? 0  =  dec x
-x ? y  =  dec (dec x)
-
-x ? 0  =  dec x
-x ? y  =  dec (dec y)
-
-x ? 0  =  x + x
-x ? y  =  dec x
-
-x ? 0  =  x + x
-x ? y  =  dec y
-
-x ? 0  =  dec (dec x)
-x ? y  =  dec x
-
-x ? 0  =  dec (dec x)
-x ? y  =  dec y
-
-x ? 0  =  dec (dec (dec x))
-x ? y  =  x
-
-x ? 0  =  dec (dec (dec x))
-x ? y  =  y
-
-x ? 0  =  dec (dec (dec x))
-x ? y  =  0
-
-x ? 0  =  x + dec x
-x ? y  =  x
-
-x ? 0  =  x + dec x
-x ? y  =  y
-
-x ? 0  =  x + dec x
-x ? y  =  0
-
-0 ? x  =  x
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  x
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  x
-x ? y  =  x + dec x
-
-0 ? x  =  x
-x ? y  =  x + dec y
-
-0 ? x  =  x
-x ? y  =  y + dec x
-
-0 ? x  =  x
-x ? y  =  y + dec y
-
-0 ? x  =  0
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  0
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  0
-x ? y  =  x + dec x
-
-0 ? x  =  0
-x ? y  =  x + dec y
-
-0 ? x  =  0
-x ? y  =  y + dec x
-
-0 ? x  =  0
-x ? y  =  y + dec y
-
-0 ? x  =  dec x
-x ? y  =  x + x
-
-0 ? x  =  dec x
-x ? y  =  x + y
-
-0 ? x  =  dec x
-x ? y  =  y + y
-
-0 ? x  =  dec x
-x ? y  =  dec (dec x)
-
-0 ? x  =  dec x
-x ? y  =  dec (dec y)
-
-0 ? x  =  x + x
-x ? y  =  dec x
-
-0 ? x  =  x + x
-x ? y  =  dec y
-
-0 ? x  =  dec (dec x)
-x ? y  =  dec x
-
-0 ? x  =  dec (dec x)
-x ? y  =  dec y
-
-0 ? x  =  dec (dec (dec x))
-x ? y  =  x
-
-0 ? x  =  dec (dec (dec x))
-x ? y  =  y
-
-0 ? x  =  dec (dec (dec x))
-x ? y  =  0
-
-0 ? x  =  x + dec x
-x ? y  =  x
-
-0 ? x  =  x + dec x
-x ? y  =  y
-
-0 ? x  =  x + dec x
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  x + x
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  x + y
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  y + y
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec (dec x)
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec (dec y)
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x + x
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x + y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  y + y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec (dec x)
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec (dec y)
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  dec y
-
-0 ? x  =  x
-x ? 0  =  x + x
-x ? y  =  x
-
-0 ? x  =  x
-x ? 0  =  x + x
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  dec (dec x)
-x ? y  =  x
-
-0 ? x  =  x
-x ? 0  =  dec (dec x)
-x ? y  =  0
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  x + x
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  x + y
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  y + y
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec (dec x)
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec (dec y)
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  x + x
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  x + y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  y + y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec (dec x)
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec (dec y)
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  dec y
-
-0 ? x  =  0
-x ? 0  =  x + x
-x ? y  =  y
-
-0 ? x  =  0
-x ? 0  =  dec (dec x)
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  dec x
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  dec x
-
-0 ? x  =  dec x
-x ? 0  =  dec x
-x ? y  =  x
-
-0 ? x  =  dec x
-x ? 0  =  dec x
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  dec x
-x ? y  =  0
-
-0 ? x  =  x + x
-x ? 0  =  x
-x ? y  =  y
-
-0 ? x  =  x + x
-x ? 0  =  x
-x ? y  =  0
-
-0 ? x  =  x + x
-x ? 0  =  0
-x ? y  =  x
-
-0 ? x  =  dec (dec x)
-x ? 0  =  x
-x ? y  =  y
-
-0 ? x  =  dec (dec x)
-x ? 0  =  x
-x ? y  =  0
-
-0 ? x  =  dec (dec x)
-x ? 0  =  0
-x ? y  =  x
-
-0 ? 0  =  0
-0 ? x  =  dec x
-x ? y  =  dec x
-
-x ? 0  =  x
-x ? y  =  x ? dec (dec y)
-
-x ? 0  =  x
-x ? y  =  y ? dec (dec y)
-
-x ? 0  =  x
-x ? y  =  0 ? dec (dec y)
-
-x ? 0  =  x
-x ? y  =  dec x ? dec x
-
-x ? 0  =  x
-x ? y  =  dec x ? dec y
-
-x ? 0  =  x
-x ? y  =  dec y ? dec y
-
-x ? 0  =  x
-x ? y  =  dec (dec x) ? x
-
-x ? 0  =  x
-x ? y  =  dec (dec x) ? y
-
-x ? 0  =  0
-x ? y  =  x ? dec (dec y)
-
-x ? 0  =  0
-x ? y  =  y ? dec (dec y)
-
-x ? 0  =  0
-x ? y  =  0 ? dec (dec y)
-
-x ? 0  =  0
-x ? y  =  dec x ? dec x
-
-x ? 0  =  0
-x ? y  =  dec x ? dec y
-
-x ? 0  =  0
-x ? y  =  dec y ? dec y
-
-x ? 0  =  0
-x ? y  =  dec (dec x) ? x
-
-x ? 0  =  0
-x ? y  =  dec (dec x) ? y
-
-0 ? x  =  x
-x ? y  =  x ? dec (dec y)
-
-0 ? x  =  x
-x ? y  =  y ? dec (dec y)
-
-0 ? x  =  x
-x ? y  =  dec x ? dec x
-
-0 ? x  =  x
-x ? y  =  dec x ? dec y
-
-0 ? x  =  x
-x ? y  =  dec y ? dec y
-
-0 ? x  =  x
-x ? y  =  dec (dec x) ? x
-
-0 ? x  =  x
-x ? y  =  dec (dec x) ? y
-
-0 ? x  =  x
-x ? y  =  dec (dec x) ? 0
-
-0 ? x  =  0
-x ? y  =  x ? dec (dec y)
-
-0 ? x  =  0
-x ? y  =  y ? dec (dec y)
-
-0 ? x  =  0
-x ? y  =  dec x ? dec x
-
-0 ? x  =  0
-x ? y  =  dec x ? dec y
-
-0 ? x  =  0
-x ? y  =  dec y ? dec y
-
-0 ? x  =  0
-x ? y  =  dec (dec x) ? x
-
-0 ? x  =  0
-x ? y  =  dec (dec x) ? y
-
-0 ? x  =  0
-x ? y  =  dec (dec x) ? 0
-
-x ? 0  =  x
-x ? y  =  dec (x ? dec y)
-
-x ? 0  =  x
-x ? y  =  dec (y ? dec y)
-
-x ? 0  =  x
-x ? y  =  dec (0 ? dec y)
-
-x ? 0  =  x
-x ? y  =  dec (dec x ? x)
-
-x ? 0  =  x
-x ? y  =  dec (dec x ? y)
-
-x ? 0  =  0
-x ? y  =  dec (x ? dec y)
-
-x ? 0  =  0
-x ? y  =  dec (y ? dec y)
-
-x ? 0  =  0
-x ? y  =  dec (0 ? dec y)
-
-x ? 0  =  0
-x ? y  =  dec (dec x ? x)
-
-x ? 0  =  0
-x ? y  =  dec (dec x ? y)
-
-x ? 0  =  dec x
-x ? y  =  x ? dec y
-
-x ? 0  =  dec x
-x ? y  =  y ? dec y
-
-x ? 0  =  dec x
-x ? y  =  0 ? dec y
-
-x ? 0  =  dec x
-x ? y  =  dec x ? x
-
-x ? 0  =  dec x
-x ? y  =  dec x ? y
-
-0 ? x  =  x
-x ? y  =  dec (x ? dec y)
-
-0 ? x  =  x
-x ? y  =  dec (y ? dec y)
-
-0 ? x  =  x
-x ? y  =  dec (dec x ? x)
-
-0 ? x  =  x
-x ? y  =  dec (dec x ? y)
-
-0 ? x  =  x
-x ? y  =  dec (dec x ? 0)
-
-0 ? x  =  0
-x ? y  =  dec (x ? dec y)
-
-0 ? x  =  0
-x ? y  =  dec (y ? dec y)
-
-0 ? x  =  0
-x ? y  =  dec (dec x ? x)
-
-0 ? x  =  0
-x ? y  =  dec (dec x ? y)
-
-0 ? x  =  0
-x ? y  =  dec (dec x ? 0)
-
-0 ? x  =  dec x
-x ? y  =  x ? dec y
-
-0 ? x  =  dec x
-x ? y  =  y ? dec y
-
-0 ? x  =  dec x
-x ? y  =  dec x ? x
-
-0 ? x  =  dec x
-x ? y  =  dec x ? y
-
-0 ? x  =  dec x
-x ? y  =  dec x ? 0
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  x ? dec y
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  y ? dec y
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec x ? x
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec x ? y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x ? dec y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  y ? dec y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec x ? x
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec x ? y
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  x ? dec y
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  y ? dec y
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec x ? x
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec x ? y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  x ? dec y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  y ? dec y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec x ? x
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec x ? y
-
-x ? y  =  dec (dec (dec (dec (dec x))))
-
-x ? y  =  dec (dec (dec (dec (dec y))))
-
-x ? y  =  x + dec (dec (dec x))
-
-x ? y  =  x + dec (dec (dec y))
-
-x ? y  =  x + (x + dec x)
-
-x ? y  =  x + (x + dec y)
-
-x ? y  =  x + (y + dec x)
-
-x ? y  =  x + (y + dec y)
-
-x ? y  =  y + dec (dec (dec x))
-
-x ? y  =  y + dec (dec (dec y))
-
-x ? y  =  y + (x + dec x)
-
-x ? y  =  y + (x + dec y)
-
-x ? y  =  y + (y + dec x)
-
-x ? y  =  y + (y + dec y)
-
-x ? y  =  dec x + (x + x)
-
-x ? y  =  dec x + (x + y)
-
-x ? y  =  dec x + (y + y)
-
-x ? y  =  dec x + dec (dec x)
-
-x ? y  =  dec x + dec (dec y)
-
-x ? y  =  dec y + (x + x)
-
-x ? y  =  dec y + (x + y)
-
-x ? y  =  dec y + (y + y)
-
-x ? y  =  dec y + dec (dec x)
-
-x ? y  =  dec y + dec (dec y)
-
-x ? 0  =  x
-x ? y  =  dec (dec (dec (dec x)))
-
-x ? 0  =  x
-x ? y  =  dec (dec (dec (dec y)))
-
-x ? 0  =  x
-x ? y  =  x + (x + x)
-
-x ? 0  =  x
-x ? y  =  x + (x + y)
-
-x ? 0  =  x
-x ? y  =  x + (y + y)
-
-x ? 0  =  x
-x ? y  =  x + dec (dec x)
-
-x ? 0  =  x
-x ? y  =  x + dec (dec y)
-
-x ? 0  =  x
-x ? y  =  y + (x + x)
-
-x ? 0  =  x
-x ? y  =  y + (x + y)
-
-x ? 0  =  x
-x ? y  =  y + (y + y)
-
-x ? 0  =  x
-x ? y  =  y + dec (dec x)
-
-x ? 0  =  x
-x ? y  =  y + dec (dec y)
-
-x ? 0  =  x
-x ? y  =  dec x + dec x
-
-x ? 0  =  x
-x ? y  =  dec x + dec y
-
-x ? 0  =  x
-x ? y  =  dec y + dec y
-
-x ? 0  =  0
-x ? y  =  dec (dec (dec (dec x)))
-
-x ? 0  =  0
-x ? y  =  dec (dec (dec (dec y)))
-
-x ? 0  =  0
-x ? y  =  x + (x + x)
-
-x ? 0  =  0
-x ? y  =  x + (x + y)
-
-x ? 0  =  0
-x ? y  =  x + (y + y)
-
-x ? 0  =  0
-x ? y  =  x + dec (dec x)
-
-x ? 0  =  0
-x ? y  =  x + dec (dec y)
-
-x ? 0  =  0
-x ? y  =  y + (x + x)
-
-x ? 0  =  0
-x ? y  =  y + (x + y)
-
-x ? 0  =  0
-x ? y  =  y + (y + y)
-
-x ? 0  =  0
-x ? y  =  y + dec (dec x)
-
-x ? 0  =  0
-x ? y  =  y + dec (dec y)
-
-x ? 0  =  0
-x ? y  =  dec x + dec x
-
-x ? 0  =  0
-x ? y  =  dec x + dec y
-
-x ? 0  =  0
-x ? y  =  dec y + dec y
-
-x ? 0  =  dec x
-x ? y  =  dec (dec (dec x))
-
-x ? 0  =  dec x
-x ? y  =  dec (dec (dec y))
-
-x ? 0  =  dec x
-x ? y  =  x + dec x
-
-x ? 0  =  dec x
-x ? y  =  x + dec y
-
-x ? 0  =  dec x
-x ? y  =  y + dec x
-
-x ? 0  =  dec x
-x ? y  =  y + dec y
-
-x ? 0  =  x + x
-x ? y  =  x + y
-
-x ? 0  =  x + x
-x ? y  =  y + y
-
-x ? 0  =  x + x
-x ? y  =  dec (dec x)
-
-x ? 0  =  x + x
-x ? y  =  dec (dec y)
-
-x ? 0  =  dec (dec x)
-x ? y  =  x + x
-
-x ? 0  =  dec (dec x)
-x ? y  =  x + y
-
-x ? 0  =  dec (dec x)
-x ? y  =  y + y
-
-x ? 0  =  dec (dec x)
-x ? y  =  dec (dec y)
-
-x ? 0  =  dec (dec (dec x))
-x ? y  =  dec x
-
-x ? 0  =  dec (dec (dec x))
-x ? y  =  dec y
-
-x ? 0  =  x + dec x
-x ? y  =  dec x
-
-x ? 0  =  x + dec x
-x ? y  =  dec y
-
-x ? 0  =  dec (dec (dec (dec x)))
-x ? y  =  x
-
-x ? 0  =  dec (dec (dec (dec x)))
-x ? y  =  y
-
-x ? 0  =  dec (dec (dec (dec x)))
-x ? y  =  0
-
-x ? 0  =  x + (x + x)
-x ? y  =  x
-
-x ? 0  =  x + (x + x)
-x ? y  =  y
-
-x ? 0  =  x + (x + x)
-x ? y  =  0
-
-x ? 0  =  x + dec (dec x)
-x ? y  =  x
-
-x ? 0  =  x + dec (dec x)
-x ? y  =  y
-
-x ? 0  =  x + dec (dec x)
-x ? y  =  0
-
-x ? 0  =  dec x + dec x
-x ? y  =  x
-
-x ? 0  =  dec x + dec x
-x ? y  =  y
-
-x ? 0  =  dec x + dec x
-x ? y  =  0
-
-0 ? x  =  x
-x ? y  =  dec (dec (dec (dec x)))
-
-0 ? x  =  x
-x ? y  =  dec (dec (dec (dec y)))
-
-0 ? x  =  x
-x ? y  =  x + (x + x)
-
-0 ? x  =  x
-x ? y  =  x + (x + y)
-
-0 ? x  =  x
-x ? y  =  x + (y + y)
-
-0 ? x  =  x
-x ? y  =  x + dec (dec x)
-
-0 ? x  =  x
-x ? y  =  x + dec (dec y)
-
-0 ? x  =  x
-x ? y  =  y + (x + x)
-
-0 ? x  =  x
-x ? y  =  y + (x + y)
-
-0 ? x  =  x
-x ? y  =  y + (y + y)
-
-0 ? x  =  x
-x ? y  =  y + dec (dec x)
-
-0 ? x  =  x
-x ? y  =  y + dec (dec y)
-
-0 ? x  =  x
-x ? y  =  dec x + dec x
-
-0 ? x  =  x
-x ? y  =  dec x + dec y
-
-0 ? x  =  x
-x ? y  =  dec y + dec y
-
-0 ? x  =  0
-x ? y  =  dec (dec (dec (dec x)))
-
-0 ? x  =  0
-x ? y  =  dec (dec (dec (dec y)))
-
-0 ? x  =  0
-x ? y  =  x + (x + x)
-
-0 ? x  =  0
-x ? y  =  x + (x + y)
-
-0 ? x  =  0
-x ? y  =  x + (y + y)
-
-0 ? x  =  0
-x ? y  =  x + dec (dec x)
-
-0 ? x  =  0
-x ? y  =  x + dec (dec y)
-
-0 ? x  =  0
-x ? y  =  y + (x + x)
-
-0 ? x  =  0
-x ? y  =  y + (x + y)
-
-0 ? x  =  0
-x ? y  =  y + (y + y)
-
-0 ? x  =  0
-x ? y  =  y + dec (dec x)
-
-0 ? x  =  0
-x ? y  =  y + dec (dec y)
-
-0 ? x  =  0
-x ? y  =  dec x + dec x
-
-0 ? x  =  0
-x ? y  =  dec x + dec y
-
-0 ? x  =  0
-x ? y  =  dec y + dec y
-
-0 ? x  =  dec x
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  dec x
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  dec x
-x ? y  =  x + dec x
-
-0 ? x  =  dec x
-x ? y  =  x + dec y
-
-0 ? x  =  dec x
-x ? y  =  y + dec x
-
-0 ? x  =  dec x
-x ? y  =  y + dec y
-
-0 ? x  =  x + x
-x ? y  =  x + y
-
-0 ? x  =  x + x
-x ? y  =  dec (dec x)
-
-0 ? x  =  x + x
-x ? y  =  dec (dec y)
-
-0 ? x  =  dec (dec x)
-x ? y  =  x + x
-
-0 ? x  =  dec (dec x)
-x ? y  =  x + y
-
-0 ? x  =  dec (dec x)
-x ? y  =  y + y
-
-0 ? x  =  dec (dec (dec x))
-x ? y  =  dec x
-
-0 ? x  =  dec (dec (dec x))
-x ? y  =  dec y
-
-0 ? x  =  x + dec x
-x ? y  =  dec x
-
-0 ? x  =  x + dec x
-x ? y  =  dec y
-
-0 ? x  =  dec (dec (dec (dec x)))
-x ? y  =  x
-
-0 ? x  =  dec (dec (dec (dec x)))
-x ? y  =  y
-
-0 ? x  =  dec (dec (dec (dec x)))
-x ? y  =  0
-
-0 ? x  =  x + (x + x)
-x ? y  =  x
-
-0 ? x  =  x + (x + x)
-x ? y  =  y
-
-0 ? x  =  x + (x + x)
-x ? y  =  0
-
-0 ? x  =  x + dec (dec x)
-x ? y  =  x
-
-0 ? x  =  x + dec (dec x)
-x ? y  =  y
-
-0 ? x  =  x + dec (dec x)
-x ? y  =  0
-
-0 ? x  =  dec x + dec x
-x ? y  =  x
-
-0 ? x  =  dec x + dec x
-x ? y  =  y
-
-0 ? x  =  dec x + dec x
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  x + dec x
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  x + dec y
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  y + dec x
-
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  y + dec y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x + dec x
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x + dec y
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  y + dec x
-
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  y + dec y
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  x + x
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  x + y
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  y + y
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  dec (dec x)
-
-0 ? x  =  x
-x ? 0  =  dec x
-x ? y  =  dec (dec y)
-
-0 ? x  =  x
-x ? 0  =  x + x
-x ? y  =  dec x
-
-0 ? x  =  x
-x ? 0  =  x + x
-x ? y  =  dec y
-
-0 ? x  =  x
-x ? 0  =  dec (dec x)
-x ? y  =  dec x
-
-0 ? x  =  x
-x ? 0  =  dec (dec x)
-x ? y  =  dec y
-
-0 ? x  =  x
-x ? 0  =  dec (dec (dec x))
-x ? y  =  x
-
-0 ? x  =  x
-x ? 0  =  dec (dec (dec x))
-x ? y  =  0
-
-0 ? x  =  x
-x ? 0  =  x + dec x
-x ? y  =  x
-
-0 ? x  =  x
-x ? 0  =  x + dec x
-x ? y  =  0
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  x + dec x
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  x + dec y
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  y + dec x
-
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  y + dec y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec (dec (dec x))
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  dec (dec (dec y))
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  x + dec x
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  x + dec y
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  y + dec x
-
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  y + dec y
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  x + x
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  x + y
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  y + y
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  dec (dec x)
-
-0 ? x  =  0
-x ? 0  =  dec x
-x ? y  =  dec (dec y)
-
-0 ? x  =  0
-x ? 0  =  x + x
-x ? y  =  dec x
-
-0 ? x  =  0
-x ? 0  =  x + x
-x ? y  =  dec y
-
-0 ? x  =  0
-x ? 0  =  dec (dec x)
-x ? y  =  dec x
-
-0 ? x  =  0
-x ? 0  =  dec (dec x)
-x ? y  =  dec y
-
-0 ? x  =  0
-x ? 0  =  dec (dec (dec x))
-x ? y  =  y
-
-0 ? x  =  0
-x ? 0  =  x + dec x
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  x + x
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  x + y
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  y + y
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  dec (dec x)
-
-0 ? x  =  dec x
-x ? 0  =  x
-x ? y  =  dec (dec y)
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  x + x
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  x + y
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  y + y
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  dec (dec x)
-
-0 ? x  =  dec x
-x ? 0  =  0
-x ? y  =  dec (dec y)
-
-0 ? x  =  dec x
-x ? 0  =  x + x
-x ? y  =  x
-
-0 ? x  =  dec x
-x ? 0  =  x + x
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  x + x
-x ? y  =  0
-
-0 ? x  =  dec x
-x ? 0  =  dec (dec x)
-x ? y  =  x
-
-0 ? x  =  dec x
-x ? 0  =  dec (dec x)
-x ? y  =  y
-
-0 ? x  =  dec x
-x ? 0  =  dec (dec x)
-x ? y  =  0
-
-0 ? x  =  x + x
-x ? 0  =  x
-x ? y  =  dec x
-
-0 ? x  =  x + x
-x ? 0  =  x
-x ? y  =  dec y
-
-0 ? x  =  x + x
-x ? 0  =  0
-x ? y  =  dec x
-
-0 ? x  =  x + x
-x ? 0  =  0
-x ? y  =  dec y
-
-0 ? x  =  x + x
-x ? 0  =  dec x
-x ? y  =  x
-
-0 ? x  =  x + x
-x ? 0  =  dec x
-x ? y  =  y
-
-0 ? x  =  x + x
-x ? 0  =  dec x
-x ? y  =  0
-
-0 ? x  =  dec (dec x)
-x ? 0  =  x
-x ? y  =  dec x
-
-0 ? x  =  dec (dec x)
-x ? 0  =  x
-x ? y  =  dec y
-
-0 ? x  =  dec (dec x)
-x ? 0  =  0
-x ? y  =  dec x
-
-0 ? x  =  dec (dec x)
-x ? 0  =  0
-x ? y  =  dec y
-
-0 ? x  =  dec (dec x)
-x ? 0  =  dec x
-x ? y  =  x
-
-0 ? x  =  dec (dec x)
-x ? 0  =  dec x
-x ? y  =  y
-
-0 ? x  =  dec (dec x)
-x ? 0  =  dec x
-x ? y  =  0
-
-0 ? x  =  dec (dec (dec x))
-x ? 0  =  x
-x ? y  =  y
-
-0 ? x  =  dec (dec (dec x))
-x ? 0  =  x
-x ? y  =  0
-
-0 ? x  =  dec (dec (dec x))
-x ? 0  =  0
-x ? y  =  x
-
-0 ? x  =  x + dec x
-x ? 0  =  x
-x ? y  =  y
-
-0 ? x  =  x + dec x
-x ? 0  =  x
-x ? y  =  0
-
-0 ? x  =  x + dec x
-x ? 0  =  0
-x ? y  =  x
-
-0 ? 0  =  0
-0 ? x  =  dec x
-x ? y  =  x + x
-
-0 ? 0  =  0
-0 ? x  =  dec x
-x ? y  =  x + y
-
-0 ? 0  =  0
-0 ? x  =  dec x
-x ? y  =  y + y
-
-0 ? 0  =  0
-0 ? x  =  dec x
-x ? y  =  dec (dec x)
-
-0 ? 0  =  0
-0 ? x  =  dec x
-x ? y  =  dec (dec y)
-
-0 ? 0  =  0
-0 ? x  =  x + x
-x ? y  =  dec x
-
-0 ? 0  =  0
-0 ? x  =  x + x
-x ? y  =  dec y
-
-0 ? 0  =  0
-0 ? x  =  dec (dec x)
-x ? y  =  dec x
-
-0 ? 0  =  0
-0 ? x  =  dec (dec x)
-x ? y  =  dec y
-
-
-Candidates for: goo :: [Int] -> [Int]
-  pruning with 4/4 rules
-  [2,0,1,0,1,0,1,0,1] direct candidates, 0 duplicates
-  [2,1,2,3,4,7,10,17,26] pattern candidates, 0 duplicates
-
-rules:
-xs ++ [] == xs
-[] ++ xs == xs
-(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
-(x:xs) ++ ys == x:(xs ++ ys)
-
-direct candidates:
-
-goo xs  =  xs
-
-goo xs  =  []
-
-goo xs  =  xs ++ xs
-
-goo xs  =  xs ++ (xs ++ xs)
-
-
-pattern candidates:
-
-goo xs  =  xs
-
-goo xs  =  []
-
-goo []  =  []
-goo (x:xs)  =  xs
-
-goo []  =  []
-goo (x:xs)  =  goo xs
-
-goo xs  =  xs ++ xs
-
-goo []  =  []
-goo (x:xs)  =  x:xs
-
-goo []  =  []
-goo (x:xs)  =  [x]
-
-goo []  =  []
-goo (x:xs)  =  xs ++ xs
-
-goo []  =  []
-goo (x:xs)  =  x:goo xs
-
-goo []  =  []
-goo (x:xs)  =  xs ++ goo xs
-
-goo []  =  []
-goo (x:xs)  =  goo xs ++ xs
-
-goo xs  =  xs ++ (xs ++ xs)
-
-goo []  =  []
-goo (x:xs)  =  goo xs ++ goo xs
-
-goo []  =  []
-goo (x:xs)  =  x:x:xs
-
-goo []  =  []
-goo (x:xs)  =  [x,x]
-
-goo []  =  []
-goo (x:xs)  =  x:(xs ++ xs)
-
-goo []  =  []
-goo (x:xs)  =  xs ++ (x:xs)
-
-goo []  =  []
-goo (x:xs)  =  xs ++ [x]
-
-goo []  =  []
-goo (x:xs)  =  xs ++ (xs ++ xs)
-
-
-Candidates for: ?? :: [Int] -> [Int] -> [Int]
-  pruning with 4/4 rules
-  [3,0,4,0,8,0,16,0,32] direct candidates, 0 duplicates
-  [3,7,15,59,139,331,987,2016,6970] pattern candidates, 0 duplicates
-
-rules:
-xs ++ [] == xs
-[] ++ xs == xs
-(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
-(x:xs) ++ ys == x:(xs ++ ys)
-
-direct candidates:
-
-xs ?? ys  =  xs
-
-xs ?? ys  =  ys
-
-xs ?? ys  =  []
-
-xs ?? ys  =  xs ++ xs
-
-xs ?? ys  =  xs ++ ys
-
-xs ?? ys  =  ys ++ xs
-
-xs ?? ys  =  ys ++ ys
-
-xs ?? ys  =  xs ++ (xs ++ xs)
-
-xs ?? ys  =  xs ++ (xs ++ ys)
-
-xs ?? ys  =  xs ++ (ys ++ xs)
-
-xs ?? ys  =  xs ++ (ys ++ ys)
-
-xs ?? ys  =  ys ++ (xs ++ xs)
-
-xs ?? ys  =  ys ++ (xs ++ ys)
-
-xs ?? ys  =  ys ++ (ys ++ xs)
-
-xs ?? ys  =  ys ++ (ys ++ ys)
-
-
-pattern candidates:
-
-xs ?? ys  =  xs
-
-xs ?? ys  =  ys
-
-xs ?? ys  =  []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  []
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys
-
-xs ?? ys  =  xs ++ xs
-
-xs ?? ys  =  xs ++ ys
-
-xs ?? ys  =  ys ++ xs
-
-xs ?? ys  =  ys ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [x]
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [x]
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  xs
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  [x]
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  xs
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ?? []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  xs ?? xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  xs ?? ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  xs ?? []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  ys ?? xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  ys ?? ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  ys ?? []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  [] ?? xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  [] ?? ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? xs
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? []
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [] ?? xs
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? xs
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? []
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [] ?? xs
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? xs
-(x:xs) ?? ys  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? []
-(x:xs) ?? ys  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [] ?? xs
-(x:xs) ?? ys  =  []
-
-xs ?? ys  =  xs ++ (xs ++ xs)
-
-xs ?? ys  =  xs ++ (xs ++ ys)
-
-xs ?? ys  =  xs ++ (ys ++ xs)
-
-xs ?? ys  =  xs ++ (ys ++ ys)
-
-xs ?? ys  =  ys ++ (xs ++ xs)
-
-xs ?? ys  =  ys ++ (xs ++ ys)
-
-xs ?? ys  =  ys ++ (ys ++ xs)
-
-xs ?? ys  =  ys ++ (ys ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  x:xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  x:ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  y:xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  y:ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [y]
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  x:xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  x:ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  y:xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  y:ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  [y]
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  x:xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  x:ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [x]
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  y:xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  y:ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [y]
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  x:xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  x:ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  [x]
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  y:xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  y:ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  [y]
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  []
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  x:xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  x:ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  [x]
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  xs ++ xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  xs ++ ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  ys ++ xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? ys  =  ys ++ ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  x:xs
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  x:xs
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  x:xs
-(x:xs) ?? ys  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [x]
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [x]
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [x]
-(x:xs) ?? ys  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ++ xs
-(x:xs) ?? ys  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ++ xs
-(x:xs) ?? ys  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ++ xs
-(x:xs) ?? ys  =  []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (x:xs) ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (x:xs) ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (x:ys) ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (x:ys) ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [x] ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [x] ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (xs ++ xs) ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (xs ++ xs) ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (xs ++ ys) ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (xs ++ ys) ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (ys ++ xs) ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (ys ++ xs) ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (ys ++ ys) ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  (ys ++ ys) ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (x:xs) ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (x:xs) ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (x:ys) ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (x:ys) ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [x] ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [x] ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (xs ++ xs) ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (xs ++ xs) ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (xs ++ ys) ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (xs ++ ys) ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (ys ++ xs) ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (ys ++ xs) ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (ys ++ ys) ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  (ys ++ ys) ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? (x:xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? (x:ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? (xs ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? (xs ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? (ys ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? (ys ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? (x:xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? (x:ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? (xs ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? (xs ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? (ys ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? (ys ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? (x:xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? (x:ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? [x]
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? (xs ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? (xs ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? (ys ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? (ys ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? (x:xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? (x:ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? [x]
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? (xs ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? (xs ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? (ys ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? (ys ++ ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:xs ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:xs ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:ys ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:ys ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:[] ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:[] ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ xs ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ xs ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ ys ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ ys ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ [] ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ [] ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ xs ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ xs ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ ys ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ ys ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ [] ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ [] ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? xs ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? ys ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? xs ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? ys ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? xs ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? ys ++ xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? xs ++ ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? ys ++ ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? xs ++ ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? ys ++ ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? xs ++ ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? ys ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:xs ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:xs ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:ys ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:ys ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:[] ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:[] ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ xs ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ xs ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ ys ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ ys ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ [] ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ [] ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ xs ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ xs ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ ys ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ ys ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ [] ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ [] ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? xs ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? ys ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? xs ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? ys ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? xs ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? ys ++ xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? xs ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? ys ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? xs ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? ys ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? xs ++ ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? ys ++ ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  xs ?? xs
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  xs ?? ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  ys ?? xs
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  ys ?? ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  [] ?? xs
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  [] ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:xs ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:xs ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:xs ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:ys ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:ys ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:ys ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ xs ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ xs ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ xs ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ ys ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ ys ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ ys ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ xs ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ xs ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ xs ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ ys ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ ys ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ ys ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? xs ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? ys ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? [] ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? xs ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? ys ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? [] ++ xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? xs ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? ys ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ?? [] ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? xs ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? ys ++ ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ?? [] ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:xs ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:xs ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ xs ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ xs ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ xs ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ xs ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? xs ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? ys ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? [] ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? xs ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? ys ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? [] ++ xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? xs ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? ys ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ?? [] ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? xs ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? ys ++ ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? [] ++ ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  xs ?? xs
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  xs ?? ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  xs ?? []
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  ys ?? xs
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  ys ?? ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  ys ?? []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ?? []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ?? []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [] ?? xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [] ?? ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  [] ?? xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs ?? xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs ?? []
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  [] ?? xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [] ?? xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ?? []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [] ?? xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:x:xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:x:ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [x,x]
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:(xs ++ xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:(xs ++ ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:(ys ++ xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  x:(ys ++ ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ (x:xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ (x:ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ [x]
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ (xs ++ xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ (xs ++ ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ (ys ++ xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ++ (ys ++ ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ (x:xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ (x:ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ [x]
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ (xs ++ xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ (xs ++ ys)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ (ys ++ xs)
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ++ (ys ++ ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:x:xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:x:ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [x,x]
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:(xs ++ xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:(xs ++ ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:(ys ++ xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  x:(ys ++ ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ (x:xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ (x:ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ [x]
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ (xs ++ xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ (xs ++ ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ (ys ++ xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ++ (ys ++ ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ (x:xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ (x:ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ [x]
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ (xs ++ xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ (xs ++ ys)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ (ys ++ xs)
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ++ (ys ++ ys)
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  x:xs
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  x:ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  [x]
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  xs ++ ys
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  ys ++ xs
-
-xs ?? []  =  xs ++ xs
-xs ?? (x:ys)  =  ys ++ ys
-
-xs ?? []  =  xs ++ (xs ++ xs)
-xs ?? (x:ys)  =  xs
-
-xs ?? []  =  xs ++ (xs ++ xs)
-xs ?? (x:ys)  =  ys
-
-xs ?? []  =  xs ++ (xs ++ xs)
-xs ?? (x:ys)  =  []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:x:xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:x:ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  [x,x]
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:(xs ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:(xs ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:(ys ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  x:(ys ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ (x:xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ (x:ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ (xs ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ (xs ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ (ys ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  xs ++ (ys ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ (x:xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ (x:ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ [x]
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ (xs ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ (xs ++ ys)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ (ys ++ xs)
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  ys ++ (ys ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:x:xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:x:ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  [x,x]
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:(xs ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:(xs ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:(ys ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  x:(ys ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ (x:xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ (x:ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ [x]
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ (xs ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ (xs ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ (ys ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  xs ++ (ys ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ (x:xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ (x:ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ [x]
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ (xs ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ (xs ++ ys)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ (ys ++ xs)
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ++ (ys ++ ys)
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  x:xs
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  x:ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  [x]
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  xs ++ ys
-
-[] ?? xs  =  xs ++ xs
-(x:xs) ?? ys  =  ys ++ xs
-
-[] ?? xs  =  xs ++ (xs ++ xs)
-(x:xs) ?? ys  =  xs
-
-[] ?? xs  =  xs ++ (xs ++ xs)
-(x:xs) ?? ys  =  ys
-
-[] ?? xs  =  xs ++ (xs ++ xs)
-(x:xs) ?? ys  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  x:xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  x:ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [x]
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  y:xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  y:ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  [y]
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ++ xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs ++ ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ++ xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys ++ ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  x:xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  [x]
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  xs ++ xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  x:xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  x:xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [x]
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  [x]
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ++ xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs ++ xs
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-
-Candidates for: ton :: Bool -> Bool
-  pruning with 39/49 rules
-  [3,1,0,2,6,10,22,40,76] direct candidates, 0 duplicates
-  [3,3,0,0,0,0,0,0,0] pattern candidates, 0 duplicates
-
-rules:
-not False == True
-not True == False
-p && p == p
-p || p == p
-not (not p) == p
-p && False == False
-p && True == p
-False && p == False
-True && p == p
-p || False == p
-p || True == True
-False || p == p
-True || p == True
-not (p && q) == not p || not q
-not (p && q) == not q || not p
-not (p || q) == not p && not q
-not (p || q) == not q && not p
-p && not p == False
-not p && p == False
-p || not p == True
-not p || p == True
-(p && q) && r == p && (q && r)
-(p && q) && r == q && (p && r)
-(p || q) || r == p || (q || r)
-(p || q) || r == q || (p || r)
-p && (p && q) == p && q
-p && (q && p) == p && q
-p && (q && p) == q && p
-p || (p || q) == p || q
-p || (q || p) == p || q
-p || (q || p) == q || p
-p && (p || q) == p
-p && (q || p) == p
-(p || q) && p == p
-(p || q) && q == q
-p || p && q == p
-p || q && p == p
-p && q || p == p
-p && q || q == q
-equations:
-q && p == p && q
-q || p == p || q
-q && (p && r) == p && (q && r)
-r && (p && q) == p && (q && r)
-r && (q && p) == p && (q && r)
-q || (p || r) == p || (q || r)
-r || (p || q) == p || (q || r)
-r || (q || p) == p || (q || r)
-(r || q) && p == p && (q || r)
-r && q || p == p || q && r
-
-direct candidates:
-
-ton p  =  p
-
-ton p  =  False
-
-ton p  =  True
-
-ton p  =  not p
-
-ton p  =  p && ton p
-
-ton p  =  p || ton p
-
-ton p  =  p && ton (not p)
-
-ton p  =  p || ton (not p)
-
-ton p  =  p && not (ton p)
-
-ton p  =  not p && ton p
-
-ton p  =  p || not (ton p)
-
-ton p  =  not p || ton p
-
-ton p  =  p && not (ton (not p))
-
-ton p  =  not p && ton (not p)
-
-ton p  =  p || not (ton (not p))
-
-ton p  =  not p || ton (not p)
-
-ton p  =  p && (p && ton p)
-
-ton p  =  p && (p || ton p)
-
-ton p  =  not p && not (ton p)
-
-ton p  =  p || p && ton p
-
-ton p  =  p || (p || ton p)
-
-ton p  =  not p || not (ton p)
-
-
-pattern candidates:
-
-ton p  =  p
-
-ton p  =  False
-
-ton p  =  True
-
-ton p  =  not p
-
-ton False  =  False
-ton True  =  True
-
-ton False  =  True
-ton True  =  False
-
-
-Candidates for: &| :: Bool -> Bool -> Bool
-  pruning with 39/49 rules
-  [4,2,2,4,30,112,342,1032,2852] direct candidates, 0 duplicates
-  [4,14,26,10,2,16,18,60,120] pattern candidates, 0 duplicates
-
-rules:
-not False == True
-not True == False
-p && p == p
-p || p == p
-not (not p) == p
-p && False == False
-p && True == p
-False && p == False
-True && p == p
-p || False == p
-p || True == True
-False || p == p
-True || p == True
-not (p && q) == not p || not q
-not (p && q) == not q || not p
-not (p || q) == not p && not q
-not (p || q) == not q && not p
-p && not p == False
-not p && p == False
-p || not p == True
-not p || p == True
-(p && q) && r == p && (q && r)
-(p && q) && r == q && (p && r)
-(p || q) || r == p || (q || r)
-(p || q) || r == q || (p || r)
-p && (p && q) == p && q
-p && (q && p) == p && q
-p && (q && p) == q && p
-p || (p || q) == p || q
-p || (q || p) == p || q
-p || (q || p) == q || p
-p && (p || q) == p
-p && (q || p) == p
-(p || q) && p == p
-(p || q) && q == q
-p || p && q == p
-p || q && p == p
-p && q || p == p
-p && q || q == q
-equations:
-q && p == p && q
-q || p == p || q
-q && (p && r) == p && (q && r)
-r && (p && q) == p && (q && r)
-r && (q && p) == p && (q && r)
-q || (p || r) == p || (q || r)
-r || (p || q) == p || (q || r)
-r || (q || p) == p || (q || r)
-(r || q) && p == p && (q || r)
-r && q || p == p || q && r
-
-direct candidates:
-
-p &| q  =  p
-
-p &| q  =  q
-
-p &| q  =  False
-
-p &| q  =  True
-
-p &| q  =  not p
-
-p &| q  =  not q
-
-p &| q  =  p && q
-
-p &| q  =  p || q
-
-p &| q  =  p && not q
-
-p &| q  =  q && not p
-
-p &| q  =  p || not q
-
-p &| q  =  q || not p
-
-p &| q  =  not p && not q
-
-p &| q  =  not p || not q
-
-p &| q  =  p && p &| p
-
-p &| q  =  p && p &| q
-
-p &| q  =  p && p &| False
-
-p &| q  =  p && p &| True
-
-p &| q  =  p && q &| q
-
-p &| q  =  p && False &| q
-
-p &| q  =  p && True &| q
-
-p &| q  =  q && p &| p
-
-p &| q  =  q && p &| q
-
-p &| q  =  q && p &| False
-
-p &| q  =  q && p &| True
-
-p &| q  =  q && q &| q
-
-p &| q  =  q && False &| q
-
-p &| q  =  q && True &| q
-
-p &| q  =  p || p &| p
-
-p &| q  =  p || p &| q
-
-p &| q  =  p || p &| False
-
-p &| q  =  p || p &| True
-
-p &| q  =  p || q &| q
-
-p &| q  =  p || False &| q
-
-p &| q  =  p || True &| q
-
-p &| q  =  q || p &| p
-
-p &| q  =  q || p &| q
-
-p &| q  =  q || p &| False
-
-p &| q  =  q || p &| True
-
-p &| q  =  q || q &| q
-
-p &| q  =  q || False &| q
-
-p &| q  =  q || True &| q
-
-p &| q  =  p && (q && not p)
-
-p &| q  =  p && (q || not p)
-
-p &| q  =  q && (p && not q)
-
-p &| q  =  q && (p || not q)
-
-p &| q  =  p || q && not p
-
-p &| q  =  p || (q || not p)
-
-p &| q  =  q || p && not q
-
-p &| q  =  q || (p || not q)
-
-p &| q  =  not p && (p && q)
-
-p &| q  =  not p && (p || q)
-
-p &| q  =  not q && (p && q)
-
-p &| q  =  not q && (p || q)
-
-p &| q  =  not p || p && q
-
-p &| q  =  not p || (p || q)
-
-p &| q  =  not q || p && q
-
-p &| q  =  not q || (p || q)
-
-p &| q  =  p && p &| not p
-
-p &| q  =  p && p &| not q
-
-p &| q  =  p && q &| not q
-
-p &| q  =  p && False &| not q
-
-p &| q  =  p && True &| not q
-
-p &| q  =  p && not p &| p
-
-p &| q  =  p && not p &| q
-
-p &| q  =  p && not p &| False
-
-p &| q  =  p && not p &| True
-
-p &| q  =  p && not q &| q
-
-p &| q  =  q && p &| not p
-
-p &| q  =  q && p &| not q
-
-p &| q  =  q && q &| not q
-
-p &| q  =  q && False &| not q
-
-p &| q  =  q && True &| not q
-
-p &| q  =  q && not p &| p
-
-p &| q  =  q && not p &| q
-
-p &| q  =  q && not p &| False
-
-p &| q  =  q && not p &| True
-
-p &| q  =  q && not q &| q
-
-p &| q  =  p || p &| not p
-
-p &| q  =  p || p &| not q
-
-p &| q  =  p || q &| not q
-
-p &| q  =  p || False &| not q
-
-p &| q  =  p || True &| not q
-
-p &| q  =  p || not p &| p
-
-p &| q  =  p || not p &| q
-
-p &| q  =  p || not p &| False
-
-p &| q  =  p || not p &| True
-
-p &| q  =  p || not q &| q
-
-p &| q  =  q || p &| not p
-
-p &| q  =  q || p &| not q
-
-p &| q  =  q || q &| not q
-
-p &| q  =  q || False &| not q
-
-p &| q  =  q || True &| not q
-
-p &| q  =  q || not p &| p
-
-p &| q  =  q || not p &| q
-
-p &| q  =  q || not p &| False
-
-p &| q  =  q || not p &| True
-
-p &| q  =  q || not q &| q
-
-p &| q  =  p && not (p &| p)
-
-p &| q  =  p && not (p &| q)
-
-p &| q  =  p && not (p &| False)
-
-p &| q  =  p && not (p &| True)
-
-p &| q  =  p && not (q &| q)
-
-p &| q  =  p && not (False &| q)
-
-p &| q  =  p && not (True &| q)
-
-p &| q  =  q && not (p &| p)
-
-p &| q  =  q && not (p &| q)
-
-p &| q  =  q && not (p &| False)
-
-p &| q  =  q && not (p &| True)
-
-p &| q  =  q && not (q &| q)
-
-p &| q  =  q && not (False &| q)
-
-p &| q  =  q && not (True &| q)
-
-p &| q  =  not p && p &| p
-
-p &| q  =  not p && p &| q
-
-p &| q  =  not p && p &| False
-
-p &| q  =  not p && p &| True
-
-p &| q  =  not p && q &| q
-
-p &| q  =  not p && False &| q
-
-p &| q  =  not p && True &| q
-
-p &| q  =  not q && p &| p
-
-p &| q  =  not q && p &| q
-
-p &| q  =  not q && p &| False
-
-p &| q  =  not q && p &| True
-
-p &| q  =  not q && q &| q
-
-p &| q  =  not q && False &| q
-
-p &| q  =  not q && True &| q
-
-p &| q  =  p || not (p &| p)
-
-p &| q  =  p || not (p &| q)
-
-p &| q  =  p || not (p &| False)
-
-p &| q  =  p || not (p &| True)
-
-p &| q  =  p || not (q &| q)
-
-p &| q  =  p || not (False &| q)
-
-p &| q  =  p || not (True &| q)
-
-p &| q  =  q || not (p &| p)
-
-p &| q  =  q || not (p &| q)
-
-p &| q  =  q || not (p &| False)
-
-p &| q  =  q || not (p &| True)
-
-p &| q  =  q || not (q &| q)
-
-p &| q  =  q || not (False &| q)
-
-p &| q  =  q || not (True &| q)
-
-p &| q  =  not p || p &| p
-
-p &| q  =  not p || p &| q
-
-p &| q  =  not p || p &| False
-
-p &| q  =  not p || p &| True
-
-p &| q  =  not p || q &| q
-
-p &| q  =  not p || False &| q
-
-p &| q  =  not p || True &| q
-
-p &| q  =  not q || p &| p
-
-p &| q  =  not q || p &| q
-
-p &| q  =  not q || p &| False
-
-p &| q  =  not q || p &| True
-
-p &| q  =  not q || q &| q
-
-p &| q  =  not q || False &| q
-
-p &| q  =  not q || True &| q
-
-
-pattern candidates:
-
-p &| q  =  p
-
-p &| q  =  q
-
-p &| q  =  False
-
-p &| q  =  True
-
-p &| q  =  not p
-
-p &| q  =  not q
-
-p &| False  =  p
-p &| True  =  False
-
-p &| False  =  p
-p &| True  =  True
-
-p &| False  =  False
-p &| True  =  p
-
-p &| False  =  False
-p &| True  =  True
-
-p &| False  =  True
-p &| True  =  p
-
-p &| False  =  True
-p &| True  =  False
-
-False &| p  =  p
-True &| p  =  False
-
-False &| p  =  p
-True &| p  =  True
-
-False &| p  =  False
-True &| p  =  p
-
-False &| p  =  False
-True &| p  =  True
-
-False &| p  =  True
-True &| p  =  p
-
-False &| p  =  True
-True &| p  =  False
-
-p &| q  =  p && q
-
-p &| q  =  p || q
-
-p &| False  =  p
-p &| True  =  not p
-
-p &| False  =  False
-p &| True  =  not p
-
-p &| False  =  True
-p &| True  =  not p
-
-p &| False  =  not p
-p &| True  =  p
-
-p &| False  =  not p
-p &| True  =  False
-
-p &| False  =  not p
-p &| True  =  True
-
-False &| p  =  p
-True &| p  =  not p
-
-False &| p  =  False
-True &| p  =  not p
-
-False &| p  =  True
-True &| p  =  not p
-
-False &| p  =  not p
-True &| p  =  p
-
-False &| p  =  not p
-True &| p  =  False
-
-False &| p  =  not p
-True &| p  =  True
-
-False &| p  =  p
-True &| False  =  False
-True &| True  =  True
-
-False &| p  =  p
-True &| False  =  True
-True &| True  =  False
-
-False &| p  =  False
-True &| False  =  False
-True &| True  =  True
-
-False &| p  =  False
-True &| False  =  True
-True &| True  =  False
-
-False &| p  =  True
-True &| False  =  False
-True &| True  =  True
-
-False &| p  =  True
-True &| False  =  True
-True &| True  =  False
-
-False &| False  =  False
-False &| True  =  True
-True &| p  =  p
-
-False &| False  =  False
-False &| True  =  True
-True &| p  =  False
-
-False &| False  =  False
-False &| True  =  True
-True &| p  =  True
-
-False &| False  =  True
-False &| True  =  False
-True &| p  =  p
-
-False &| False  =  True
-False &| True  =  False
-True &| p  =  False
-
-False &| False  =  True
-False &| True  =  False
-True &| p  =  True
-
-p &| q  =  p && not q
-
-p &| q  =  q && not p
-
-p &| q  =  p || not q
-
-p &| q  =  q || not p
-
-False &| p  =  not p
-True &| False  =  False
-True &| True  =  True
-
-False &| p  =  not p
-True &| False  =  True
-True &| True  =  False
-
-False &| False  =  False
-False &| True  =  True
-True &| p  =  not p
-
-False &| False  =  True
-False &| True  =  False
-True &| p  =  not p
-
-False &| False  =  False
-False &| True  =  True
-True &| False  =  True
-True &| True  =  False
-
-False &| False  =  True
-False &| True  =  False
-True &| False  =  False
-True &| True  =  True
-
-p &| q  =  not p && not q
-
-p &| q  =  not p || not q
-
-p &| q  =  p && (q && not p)
-
-p &| q  =  p && (q || not p)
-
-p &| q  =  q && (p && not q)
-
-p &| q  =  q && (p || not q)
-
-p &| q  =  p || q && not p
-
-p &| q  =  p || (q || not p)
-
-p &| q  =  q || p && not q
-
-p &| q  =  q || (p || not q)
-
-p &| q  =  not p && (p && q)
-
-p &| q  =  not p && (p || q)
-
-p &| q  =  not q && (p && q)
-
-p &| q  =  not q && (p || q)
-
-p &| q  =  not p || p && q
-
-p &| q  =  not p || (p || q)
-
-p &| q  =  not q || p && q
-
-p &| q  =  not q || (p || q)
-
-
-Candidates for: gcd :: Int -> Int -> Int
-  pruning with 0/0 rules
-  [3,0,9,0,54,0,405,0,3402] direct candidates, 0 duplicates
-  [3,5,11,50,98,359,786,2836,6723] pattern candidates, 0 duplicates
-
-no rules.
-
-direct candidates:
-
-gcd x y  =  x
-
-gcd x y  =  y
-
-gcd x y  =  0
-
-gcd x y  =  x `mod` x
-
-gcd x y  =  x `mod` y
-
-gcd x y  =  x `mod` 0
-
-gcd x y  =  y `mod` x
-
-gcd x y  =  y `mod` y
-
-gcd x y  =  y `mod` 0
-
-gcd x y  =  0 `mod` x
-
-gcd x y  =  0 `mod` y
-
-gcd x y  =  0 `mod` 0
-
-gcd x y  =  (x `mod` x) `mod` x
-
-gcd x y  =  (x `mod` x) `mod` y
-
-gcd x y  =  (x `mod` x) `mod` 0
-
-gcd x y  =  (x `mod` y) `mod` x
-
-gcd x y  =  (x `mod` y) `mod` y
-
-gcd x y  =  (x `mod` y) `mod` 0
-
-gcd x y  =  (x `mod` 0) `mod` x
-
-gcd x y  =  (x `mod` 0) `mod` y
-
-gcd x y  =  (x `mod` 0) `mod` 0
-
-gcd x y  =  (y `mod` x) `mod` x
-
-gcd x y  =  (y `mod` x) `mod` y
-
-gcd x y  =  (y `mod` x) `mod` 0
-
-gcd x y  =  (y `mod` y) `mod` x
-
-gcd x y  =  (y `mod` y) `mod` y
-
-gcd x y  =  (y `mod` y) `mod` 0
-
-gcd x y  =  (y `mod` 0) `mod` x
-
-gcd x y  =  (y `mod` 0) `mod` y
-
-gcd x y  =  (y `mod` 0) `mod` 0
-
-gcd x y  =  (0 `mod` x) `mod` x
-
-gcd x y  =  (0 `mod` x) `mod` y
-
-gcd x y  =  (0 `mod` x) `mod` 0
-
-gcd x y  =  (0 `mod` y) `mod` x
-
-gcd x y  =  (0 `mod` y) `mod` y
-
-gcd x y  =  (0 `mod` y) `mod` 0
-
-gcd x y  =  (0 `mod` 0) `mod` x
-
-gcd x y  =  (0 `mod` 0) `mod` y
-
-gcd x y  =  (0 `mod` 0) `mod` 0
-
-gcd x y  =  x `mod` (x `mod` x)
-
-gcd x y  =  x `mod` (x `mod` y)
-
-gcd x y  =  x `mod` (x `mod` 0)
-
-gcd x y  =  x `mod` (y `mod` x)
-
-gcd x y  =  x `mod` (y `mod` y)
-
-gcd x y  =  x `mod` (y `mod` 0)
-
-gcd x y  =  x `mod` (0 `mod` x)
-
-gcd x y  =  x `mod` (0 `mod` y)
-
-gcd x y  =  x `mod` (0 `mod` 0)
-
-gcd x y  =  y `mod` (x `mod` x)
-
-gcd x y  =  y `mod` (x `mod` y)
-
-gcd x y  =  y `mod` (x `mod` 0)
-
-gcd x y  =  y `mod` (y `mod` x)
-
-gcd x y  =  y `mod` (y `mod` y)
-
-gcd x y  =  y `mod` (y `mod` 0)
-
-gcd x y  =  y `mod` (0 `mod` x)
-
-gcd x y  =  y `mod` (0 `mod` y)
-
-gcd x y  =  y `mod` (0 `mod` 0)
-
-gcd x y  =  0 `mod` (x `mod` x)
-
-gcd x y  =  0 `mod` (x `mod` y)
-
-gcd x y  =  0 `mod` (x `mod` 0)
-
-gcd x y  =  0 `mod` (y `mod` x)
-
-gcd x y  =  0 `mod` (y `mod` y)
-
-gcd x y  =  0 `mod` (y `mod` 0)
-
-gcd x y  =  0 `mod` (0 `mod` x)
-
-gcd x y  =  0 `mod` (0 `mod` y)
-
-gcd x y  =  0 `mod` (0 `mod` 0)
-
-
-pattern candidates:
-
-gcd x y  =  x
-
-gcd x y  =  y
-
-gcd x y  =  0
-
-gcd x 0  =  x
-gcd x y  =  y
-
-gcd x 0  =  x
-gcd x y  =  0
-
-gcd x 0  =  0
-gcd x y  =  x
-
-gcd 0 x  =  x
-gcd x y  =  0
-
-gcd 0 x  =  0
-gcd x y  =  y
-
-gcd x y  =  x `mod` x
-
-gcd x y  =  x `mod` y
-
-gcd x y  =  x `mod` 0
-
-gcd x y  =  y `mod` x
-
-gcd x y  =  y `mod` y
-
-gcd x y  =  y `mod` 0
-
-gcd x y  =  0 `mod` x
-
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  0
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  x
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  y
-
-gcd x 0  =  x
-gcd x y  =  x `mod` x
-
-gcd x 0  =  x
-gcd x y  =  x `mod` y
-
-gcd x 0  =  x
-gcd x y  =  x `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  y `mod` x
-
-gcd x 0  =  x
-gcd x y  =  y `mod` y
-
-gcd x 0  =  x
-gcd x y  =  y `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` x
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` y
-
-gcd x 0  =  0
-gcd x y  =  x `mod` x
-
-gcd x 0  =  0
-gcd x y  =  x `mod` y
-
-gcd x 0  =  0
-gcd x y  =  x `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  y `mod` x
-
-gcd x 0  =  0
-gcd x y  =  y `mod` y
-
-gcd x 0  =  0
-gcd x y  =  y `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` x
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` y
-
-gcd x 0  =  x `mod` x
-gcd x y  =  x
-
-gcd x 0  =  x `mod` x
-gcd x y  =  y
-
-gcd x 0  =  x `mod` x
-gcd x y  =  0
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  x
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  y
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  0
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  x
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  y
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  x
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  0
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  0
-
-gcd x y  =  (x `mod` x) `mod` x
-
-gcd x y  =  (x `mod` x) `mod` y
-
-gcd x y  =  (x `mod` x) `mod` 0
-
-gcd x y  =  (x `mod` y) `mod` x
-
-gcd x y  =  (x `mod` y) `mod` y
-
-gcd x y  =  (x `mod` y) `mod` 0
-
-gcd x y  =  (x `mod` 0) `mod` x
-
-gcd x y  =  (x `mod` 0) `mod` y
-
-gcd x y  =  (x `mod` 0) `mod` 0
-
-gcd x y  =  (y `mod` x) `mod` x
-
-gcd x y  =  (y `mod` x) `mod` y
-
-gcd x y  =  (y `mod` x) `mod` 0
-
-gcd x y  =  (y `mod` y) `mod` x
-
-gcd x y  =  (y `mod` y) `mod` y
-
-gcd x y  =  (y `mod` y) `mod` 0
-
-gcd x y  =  (y `mod` 0) `mod` x
-
-gcd x y  =  (y `mod` 0) `mod` y
-
-gcd x y  =  (y `mod` 0) `mod` 0
-
-gcd x y  =  (0 `mod` x) `mod` x
-
-gcd x y  =  (0 `mod` x) `mod` y
-
-gcd x y  =  (0 `mod` x) `mod` 0
-
-gcd x y  =  (0 `mod` y) `mod` x
-
-gcd x y  =  (0 `mod` y) `mod` y
-
-gcd x y  =  (0 `mod` y) `mod` 0
-
-gcd x y  =  x `mod` (x `mod` x)
-
-gcd x y  =  x `mod` (x `mod` y)
-
-gcd x y  =  x `mod` (x `mod` 0)
-
-gcd x y  =  x `mod` (y `mod` x)
-
-gcd x y  =  x `mod` (y `mod` y)
-
-gcd x y  =  x `mod` (y `mod` 0)
-
-gcd x y  =  x `mod` (0 `mod` x)
-
-gcd x y  =  x `mod` (0 `mod` y)
-
-gcd x y  =  y `mod` (x `mod` x)
-
-gcd x y  =  y `mod` (x `mod` y)
-
-gcd x y  =  y `mod` (x `mod` 0)
-
-gcd x y  =  y `mod` (y `mod` x)
-
-gcd x y  =  y `mod` (y `mod` y)
-
-gcd x y  =  y `mod` (y `mod` 0)
-
-gcd x y  =  y `mod` (0 `mod` x)
-
-gcd x y  =  y `mod` (0 `mod` y)
-
-gcd x y  =  0 `mod` (x `mod` x)
-
-gcd x y  =  0 `mod` (x `mod` y)
-
-gcd x y  =  0 `mod` (x `mod` 0)
-
-gcd x y  =  0 `mod` (y `mod` x)
-
-gcd x y  =  0 `mod` (y `mod` y)
-
-gcd x y  =  0 `mod` (y `mod` 0)
-
-gcd x y  =  0 `mod` (0 `mod` x)
-
-gcd x y  =  0 `mod` (0 `mod` y)
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  x
-gcd x 0  =  x
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  x
-gcd x 0  =  0
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  x
-gcd x 0  =  x `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  x
-gcd x 0  =  x `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  x
-gcd x 0  =  x `mod` 0
-gcd x y  =  x
-
-gcd 0 x  =  x
-gcd x 0  =  x `mod` 0
-gcd x y  =  0
-
-gcd 0 x  =  x
-gcd x 0  =  0 `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  x
-gcd x 0  =  0 `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  0
-gcd x 0  =  x
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  0
-gcd x 0  =  0
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  0
-gcd x 0  =  x `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  0
-gcd x 0  =  x `mod` 0
-gcd x y  =  y
-
-gcd 0 x  =  0
-gcd x 0  =  0 `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` x
-gcd x 0  =  x
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` x
-gcd x 0  =  x
-gcd x y  =  0
-
-gcd 0 x  =  x `mod` x
-gcd x 0  =  0
-gcd x y  =  x
-
-gcd 0 x  =  x `mod` 0
-gcd x 0  =  x
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` 0
-gcd x 0  =  x
-gcd x y  =  0
-
-gcd 0 x  =  x `mod` 0
-gcd x 0  =  0
-gcd x y  =  x
-
-gcd 0 x  =  0 `mod` x
-gcd x 0  =  x
-gcd x y  =  y
-
-gcd 0 x  =  0 `mod` x
-gcd x 0  =  x
-gcd x y  =  0
-
-gcd 0 x  =  0 `mod` x
-gcd x 0  =  0
-gcd x y  =  x
-
-gcd x 0  =  x
-gcd x y  =  gcd x (x `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd x (y `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd x (0 `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd y (x `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd y (y `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd y (0 `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd 0 (x `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd 0 (y `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd 0 (0 `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  gcd (x `mod` x) x
-
-gcd x 0  =  x
-gcd x y  =  gcd (x `mod` x) y
-
-gcd x 0  =  x
-gcd x y  =  gcd (y `mod` x) x
-
-gcd x 0  =  x
-gcd x y  =  gcd (y `mod` x) y
-
-gcd x 0  =  x
-gcd x y  =  gcd (0 `mod` x) x
-
-gcd x 0  =  x
-gcd x y  =  gcd (0 `mod` x) y
-
-gcd x 0  =  0
-gcd x y  =  gcd x (x `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd x (y `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd x (0 `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd y (x `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd y (y `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd y (0 `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd 0 (x `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd 0 (y `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd 0 (0 `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  gcd (x `mod` x) x
-
-gcd x 0  =  0
-gcd x y  =  gcd (x `mod` x) y
-
-gcd x 0  =  0
-gcd x y  =  gcd (y `mod` x) x
-
-gcd x 0  =  0
-gcd x y  =  gcd (y `mod` x) y
-
-gcd x 0  =  0
-gcd x y  =  gcd (0 `mod` x) x
-
-gcd x 0  =  0
-gcd x y  =  gcd (0 `mod` x) y
-
-gcd 0 x  =  x
-gcd x y  =  gcd x (x `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  gcd x (y `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  gcd x (0 `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  gcd y (x `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  gcd y (y `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  gcd y (0 `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  gcd (x `mod` x) x
-
-gcd 0 x  =  x
-gcd x y  =  gcd (x `mod` x) y
-
-gcd 0 x  =  x
-gcd x y  =  gcd (x `mod` x) 0
-
-gcd 0 x  =  x
-gcd x y  =  gcd (y `mod` x) x
-
-gcd 0 x  =  x
-gcd x y  =  gcd (y `mod` x) y
-
-gcd 0 x  =  x
-gcd x y  =  gcd (y `mod` x) 0
-
-gcd 0 x  =  x
-gcd x y  =  gcd (0 `mod` x) x
-
-gcd 0 x  =  x
-gcd x y  =  gcd (0 `mod` x) y
-
-gcd 0 x  =  x
-gcd x y  =  gcd (0 `mod` x) 0
-
-gcd 0 x  =  0
-gcd x y  =  gcd x (x `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  gcd x (y `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  gcd x (0 `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  gcd y (x `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  gcd y (y `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  gcd y (0 `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  gcd (x `mod` x) x
-
-gcd 0 x  =  0
-gcd x y  =  gcd (x `mod` x) y
-
-gcd 0 x  =  0
-gcd x y  =  gcd (x `mod` x) 0
-
-gcd 0 x  =  0
-gcd x y  =  gcd (y `mod` x) x
-
-gcd 0 x  =  0
-gcd x y  =  gcd (y `mod` x) y
-
-gcd 0 x  =  0
-gcd x y  =  gcd (y `mod` x) 0
-
-gcd 0 x  =  0
-gcd x y  =  gcd (0 `mod` x) x
-
-gcd 0 x  =  0
-gcd x y  =  gcd (0 `mod` x) y
-
-gcd 0 x  =  0
-gcd x y  =  gcd (0 `mod` x) 0
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` x) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` x) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` x) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` y) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` y) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` y) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` 0) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` 0) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (x `mod` 0) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` x) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` x) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` x) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` y) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` y) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` y) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` 0) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` 0) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (y `mod` 0) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (0 `mod` x) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (0 `mod` x) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (0 `mod` x) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  (0 `mod` y) `mod` x
-
-gcd x 0  =  x
-gcd x y  =  (0 `mod` y) `mod` y
-
-gcd x 0  =  x
-gcd x y  =  (0 `mod` y) `mod` 0
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (x `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (x `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (x `mod` 0)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (y `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (y `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (y `mod` 0)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (0 `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  x `mod` (0 `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (x `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (x `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (x `mod` 0)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (y `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (y `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (y `mod` 0)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (0 `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  y `mod` (0 `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (x `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (x `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (x `mod` 0)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (y `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (y `mod` y)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (y `mod` 0)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (0 `mod` x)
-
-gcd x 0  =  x
-gcd x y  =  0 `mod` (0 `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` x) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` x) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` x) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` y) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` y) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` y) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` 0) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` 0) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (x `mod` 0) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` x) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` x) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` x) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` y) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` y) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` y) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` 0) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` 0) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (y `mod` 0) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (0 `mod` x) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (0 `mod` x) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (0 `mod` x) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  (0 `mod` y) `mod` x
-
-gcd x 0  =  0
-gcd x y  =  (0 `mod` y) `mod` y
-
-gcd x 0  =  0
-gcd x y  =  (0 `mod` y) `mod` 0
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (x `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (x `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (x `mod` 0)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (y `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (y `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (y `mod` 0)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (0 `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  x `mod` (0 `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (x `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (x `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (x `mod` 0)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (y `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (y `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (y `mod` 0)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (0 `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  y `mod` (0 `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (x `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (x `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (x `mod` 0)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (y `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (y `mod` y)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (y `mod` 0)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (0 `mod` x)
-
-gcd x 0  =  0
-gcd x y  =  0 `mod` (0 `mod` y)
-
-gcd x 0  =  x `mod` x
-gcd x y  =  x `mod` y
-
-gcd x 0  =  x `mod` x
-gcd x y  =  x `mod` 0
-
-gcd x 0  =  x `mod` x
-gcd x y  =  y `mod` x
-
-gcd x 0  =  x `mod` x
-gcd x y  =  y `mod` y
-
-gcd x 0  =  x `mod` x
-gcd x y  =  y `mod` 0
-
-gcd x 0  =  x `mod` x
-gcd x y  =  0 `mod` x
-
-gcd x 0  =  x `mod` x
-gcd x y  =  0 `mod` y
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  x `mod` x
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  y `mod` x
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  y `mod` y
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  y `mod` 0
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  0 `mod` x
-
-gcd x 0  =  x `mod` 0
-gcd x y  =  0 `mod` y
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  x `mod` x
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  x `mod` y
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  x `mod` 0
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  y `mod` y
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  y `mod` 0
-
-gcd x 0  =  0 `mod` x
-gcd x y  =  0 `mod` y
-
-gcd x 0  =  (x `mod` x) `mod` x
-gcd x y  =  x
-
-gcd x 0  =  (x `mod` x) `mod` x
-gcd x y  =  y
-
-gcd x 0  =  (x `mod` x) `mod` x
-gcd x y  =  0
-
-gcd x 0  =  (x `mod` x) `mod` 0
-gcd x y  =  x
-
-gcd x 0  =  (x `mod` x) `mod` 0
-gcd x y  =  y
-
-gcd x 0  =  (x `mod` x) `mod` 0
-gcd x y  =  0
-
-gcd x 0  =  (x `mod` 0) `mod` x
-gcd x y  =  x
-
-gcd x 0  =  (x `mod` 0) `mod` x
-gcd x y  =  y
-
-gcd x 0  =  (x `mod` 0) `mod` x
-gcd x y  =  0
-
-gcd x 0  =  (x `mod` 0) `mod` 0
-gcd x y  =  x
-
-gcd x 0  =  (x `mod` 0) `mod` 0
-gcd x y  =  y
-
-gcd x 0  =  (x `mod` 0) `mod` 0
-gcd x y  =  0
-
-gcd x 0  =  (0 `mod` x) `mod` x
-gcd x y  =  x
-
-gcd x 0  =  (0 `mod` x) `mod` x
-gcd x y  =  y
-
-gcd x 0  =  (0 `mod` x) `mod` x
-gcd x y  =  0
-
-gcd x 0  =  (0 `mod` x) `mod` 0
-gcd x y  =  x
-
-gcd x 0  =  (0 `mod` x) `mod` 0
-gcd x y  =  y
-
-gcd x 0  =  (0 `mod` x) `mod` 0
-gcd x y  =  0
-
-gcd x 0  =  x `mod` (x `mod` x)
-gcd x y  =  x
-
-gcd x 0  =  x `mod` (x `mod` x)
-gcd x y  =  y
-
-gcd x 0  =  x `mod` (x `mod` x)
-gcd x y  =  0
-
-gcd x 0  =  x `mod` (x `mod` 0)
-gcd x y  =  x
-
-gcd x 0  =  x `mod` (x `mod` 0)
-gcd x y  =  y
-
-gcd x 0  =  x `mod` (x `mod` 0)
-gcd x y  =  0
-
-gcd x 0  =  x `mod` (0 `mod` x)
-gcd x y  =  x
-
-gcd x 0  =  x `mod` (0 `mod` x)
-gcd x y  =  y
-
-gcd x 0  =  x `mod` (0 `mod` x)
-gcd x y  =  0
-
-gcd x 0  =  0 `mod` (x `mod` x)
-gcd x y  =  x
-
-gcd x 0  =  0 `mod` (x `mod` x)
-gcd x y  =  y
-
-gcd x 0  =  0 `mod` (x `mod` x)
-gcd x y  =  0
-
-gcd x 0  =  0 `mod` (x `mod` 0)
-gcd x y  =  x
-
-gcd x 0  =  0 `mod` (x `mod` 0)
-gcd x y  =  y
-
-gcd x 0  =  0 `mod` (x `mod` 0)
-gcd x y  =  0
-
-gcd x 0  =  0 `mod` (0 `mod` x)
-gcd x y  =  x
-
-gcd x 0  =  0 `mod` (0 `mod` x)
-gcd x y  =  y
-
-gcd x 0  =  0 `mod` (0 `mod` x)
-gcd x y  =  0
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` x) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` x) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` x) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` y) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` y) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` y) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` 0) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` 0) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (x `mod` 0) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` x) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` x) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` x) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` y) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` y) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` y) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` 0) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` 0) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (y `mod` 0) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (0 `mod` x) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (0 `mod` x) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (0 `mod` x) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  (0 `mod` y) `mod` x
-
-gcd 0 x  =  x
-gcd x y  =  (0 `mod` y) `mod` y
-
-gcd 0 x  =  x
-gcd x y  =  (0 `mod` y) `mod` 0
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (x `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (x `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (x `mod` 0)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (y `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (y `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (y `mod` 0)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (0 `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  x `mod` (0 `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (x `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (x `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (x `mod` 0)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (y `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (y `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (y `mod` 0)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (0 `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  y `mod` (0 `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (x `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (x `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (x `mod` 0)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (y `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (y `mod` y)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (y `mod` 0)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (0 `mod` x)
-
-gcd 0 x  =  x
-gcd x y  =  0 `mod` (0 `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` x) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` x) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` x) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` y) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` y) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` y) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` 0) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` 0) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (x `mod` 0) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` x) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` x) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` x) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` y) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` y) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` y) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` 0) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` 0) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (y `mod` 0) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (0 `mod` x) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (0 `mod` x) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (0 `mod` x) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  (0 `mod` y) `mod` x
-
-gcd 0 x  =  0
-gcd x y  =  (0 `mod` y) `mod` y
-
-gcd 0 x  =  0
-gcd x y  =  (0 `mod` y) `mod` 0
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (x `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (x `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (x `mod` 0)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (y `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (y `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (y `mod` 0)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (0 `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  x `mod` (0 `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (x `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (x `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (x `mod` 0)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (y `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (y `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (y `mod` 0)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (0 `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  y `mod` (0 `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (x `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (x `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (x `mod` 0)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (y `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (y `mod` y)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (y `mod` 0)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (0 `mod` x)
-
-gcd 0 x  =  0
-gcd x y  =  0 `mod` (0 `mod` y)
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  x `mod` x
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  x `mod` y
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  0 `mod` x
-
-gcd 0 x  =  x `mod` 0
-gcd x y  =  0 `mod` y
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  x `mod` x
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  x `mod` 0
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  y `mod` x
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  y `mod` y
-
-gcd 0 x  =  0 `mod` x
-gcd x y  =  y `mod` 0
-
-gcd 0 x  =  (x `mod` x) `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  (x `mod` x) `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  (x `mod` x) `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  (x `mod` x) `mod` 0
-gcd x y  =  x
-
-gcd 0 x  =  (x `mod` x) `mod` 0
-gcd x y  =  y
-
-gcd 0 x  =  (x `mod` x) `mod` 0
-gcd x y  =  0
-
-gcd 0 x  =  (x `mod` 0) `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  (x `mod` 0) `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  (x `mod` 0) `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  (x `mod` 0) `mod` 0
-gcd x y  =  x
-
-gcd 0 x  =  (x `mod` 0) `mod` 0
-gcd x y  =  y
-
-gcd 0 x  =  (x `mod` 0) `mod` 0
-gcd x y  =  0
-
-gcd 0 x  =  (0 `mod` x) `mod` x
-gcd x y  =  x
-
-gcd 0 x  =  (0 `mod` x) `mod` x
-gcd x y  =  y
-
-gcd 0 x  =  (0 `mod` x) `mod` x
-gcd x y  =  0
-
-gcd 0 x  =  (0 `mod` x) `mod` 0
-gcd x y  =  x
-
-gcd 0 x  =  (0 `mod` x) `mod` 0
-gcd x y  =  y
-
-gcd 0 x  =  (0 `mod` x) `mod` 0
-gcd x y  =  0
-
-gcd 0 x  =  x `mod` (x `mod` x)
-gcd x y  =  x
-
-gcd 0 x  =  x `mod` (x `mod` x)
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` (x `mod` x)
-gcd x y  =  0
-
-gcd 0 x  =  x `mod` (x `mod` 0)
-gcd x y  =  x
-
-gcd 0 x  =  x `mod` (x `mod` 0)
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` (x `mod` 0)
-gcd x y  =  0
-
-gcd 0 x  =  x `mod` (0 `mod` x)
-gcd x y  =  x
-
-gcd 0 x  =  x `mod` (0 `mod` x)
-gcd x y  =  y
-
-gcd 0 x  =  x `mod` (0 `mod` x)
-gcd x y  =  0
-
-gcd 0 x  =  0 `mod` (x `mod` x)
-gcd x y  =  x
-
-gcd 0 x  =  0 `mod` (x `mod` x)
-gcd x y  =  y
-
-gcd 0 x  =  0 `mod` (x `mod` x)
-gcd x y  =  0
-
-gcd 0 x  =  0 `mod` (x `mod` 0)
-gcd x y  =  x
-
-gcd 0 x  =  0 `mod` (x `mod` 0)
-gcd x y  =  y
-
-gcd 0 x  =  0 `mod` (x `mod` 0)
-gcd x y  =  0
-
-gcd 0 x  =  0 `mod` (0 `mod` x)
-gcd x y  =  x
-
-gcd 0 x  =  0 `mod` (0 `mod` x)
-gcd x y  =  y
-
-gcd 0 x  =  0 `mod` (0 `mod` x)
-gcd x y  =  0
-
-
diff --git a/bench/candidates.txt b/bench/candidates.txt
new file mode 100644
--- /dev/null
+++ b/bench/candidates.txt
@@ -0,0 +1,5920 @@
+Candidates for: foo :: Int -> Int
+  pruning with 15/35 rules
+  [3,0,7,0,19,0,90,0,454] direct candidates, 0 duplicates
+  [3,3,8,9,21,27,98,133,461] pattern candidates, 0 duplicates
+
+rules:
+x * y == x + y
+x * y == y + x
+x - x == 0
+x + 0 == x
+0 + x == x
+x - 0 == x
+(x + y) + z == x + (y + z)
+(x + y) + z == y + (x + z)
+x - (y - z) == z + (x - y)
+(x - y) - z == x - (y + z)
+(x - y) - z == x - (z + y)
+(x + y) - z == x + (y - z)
+(x + y) - z == y + (x - z)
+x + (y - x) == y
+(x - y) + y == x
+equations:
+y + x == x + y
+y + (x + z) == x + (y + z)
+z + (x + y) == x + (y + z)
+z + (y + x) == x + (y + z)
+y + (x - z) == x + (y - z)
+(x - z) + y == x + (y - z)
+(z - y) + x == (x - y) + z
+y - (x + y) == 0 - x
+y - (y + x) == 0 - x
+z - (y + z) == x - (x + y)
+z - (y + z) == x - (y + x)
+z - (z + y) == x - (x + y)
+z - (z + y) == x - (y + x)
+x + (0 - y) == x - y
+(0 - y) + x == x - y
+x - (x + 1) == 0 - 1
+x - (1 + x) == 0 - 1
+y - (y + 1) == x - (x + 1)
+y - (y + 1) == x - (1 + x)
+y - (1 + y) == x - (1 + x)
+
+direct candidates:
+
+foo x  =  x
+
+foo x  =  0
+
+foo x  =  1
+
+foo x  =  x + x
+
+foo x  =  x + 1
+
+foo x  =  1 + 1
+
+foo x  =  x - 1
+
+foo x  =  0 - x
+
+foo x  =  0 - 1
+
+foo x  =  1 - x
+
+foo x  =  x + (x + x)
+
+foo x  =  x + (x + 1)
+
+foo x  =  x + (1 + 1)
+
+foo x  =  x + (x - 1)
+
+foo x  =  x + (0 - 1)
+
+foo x  =  1 + (x + x)
+
+foo x  =  1 + (x + 1)
+
+foo x  =  1 + (1 + 1)
+
+foo x  =  1 + (0 - x)
+
+foo x  =  1 + (1 - x)
+
+foo x  =  x - (x + x)
+
+foo x  =  x - (x + 1)
+
+foo x  =  x - (1 + 1)
+
+foo x  =  0 - (x + x)
+
+foo x  =  0 - (x + 1)
+
+foo x  =  0 - (1 + 1)
+
+foo x  =  1 - (x + x)
+
+foo x  =  1 - (x + 1)
+
+foo x  =  1 - (1 + 1)
+
+
+pattern candidates:
+
+foo x  =  x
+
+foo x  =  0
+
+foo x  =  1
+
+foo 0  =  0
+foo x  =  1
+
+foo 0  =  1
+foo x  =  x
+
+foo 0  =  1
+foo x  =  0
+
+foo x  =  x + x
+
+foo x  =  x + 1
+
+foo x  =  x - 1
+
+foo x  =  0 - x
+
+foo x  =  1 - x
+
+foo 1  =  0
+foo x  =  x
+
+foo 1  =  0
+foo x  =  1
+
+foo 1  =  1
+foo x  =  0
+
+foo 0  =  0
+foo x  =  x + 1
+
+foo 0  =  0
+foo x  =  x - 1
+
+foo 0  =  0
+foo x  =  1 - x
+
+foo 0  =  1
+foo x  =  x + x
+
+foo 0  =  1
+foo x  =  x - 1
+
+foo 0  =  1
+foo x  =  0 - x
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  1
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  x
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  0
+
+foo x  =  x + (x + x)
+
+foo x  =  x + (x + 1)
+
+foo x  =  x + (x - 1)
+
+foo x  =  1 + (x + x)
+
+foo x  =  1 + (x + 1)
+
+foo x  =  1 + (0 - x)
+
+foo x  =  1 + (1 - x)
+
+foo x  =  x - (x + x)
+
+foo x  =  x - (x + 1)
+
+foo x  =  0 - (x + x)
+
+foo x  =  0 - (x + 1)
+
+foo x  =  1 - (x + x)
+
+foo x  =  1 - (x + 1)
+
+foo 1  =  0
+foo x  =  x + x
+
+foo 1  =  0
+foo x  =  x + 1
+
+foo 1  =  0
+foo x  =  0 - x
+
+foo 1  =  1
+foo x  =  x + x
+
+foo 1  =  1
+foo x  =  x + 1
+
+foo 1  =  1
+foo x  =  x - 1
+
+foo 1  =  1
+foo x  =  0 - x
+
+foo 1  =  1
+foo x  =  1 - x
+
+foo 0  =  0
+foo x  =  x + (x + 1)
+
+foo 0  =  0
+foo x  =  x + (x - 1)
+
+foo 0  =  0
+foo x  =  1 + (x + x)
+
+foo 0  =  0
+foo x  =  1 + (x + 1)
+
+foo 0  =  0
+foo x  =  1 + (0 - x)
+
+foo 0  =  0
+foo x  =  1 + (1 - x)
+
+foo 0  =  0
+foo x  =  x - (x + 1)
+
+foo 0  =  0
+foo x  =  0 - (x + 1)
+
+foo 0  =  0
+foo x  =  1 - (x + x)
+
+foo 0  =  1
+foo x  =  x + (x + x)
+
+foo 0  =  1
+foo x  =  x + (x - 1)
+
+foo 0  =  1
+foo x  =  1 + (x + 1)
+
+foo 0  =  1
+foo x  =  1 + (1 - x)
+
+foo 0  =  1
+foo x  =  x - (x + x)
+
+foo 0  =  1
+foo x  =  x - (x + 1)
+
+foo 0  =  1
+foo x  =  0 - (x + x)
+
+foo 0  =  1
+foo x  =  0 - (x + 1)
+
+foo 0  =  1
+foo x  =  1 - (x + 1)
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  x + 1
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  x + 1
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  x - 1
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  1 - x
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  x + x
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  0 - x
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  x + x
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  x - 1
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  0 - x
+
+
+Candidates for: ? :: Int -> Int -> Int
+  pruning with 10/23 rules
+  [3,3,6,9,21,39,87,180,390] direct candidates, 0 duplicates
+  [3,8,22,50,116,302,765,1864,4439] pattern candidates, 0 duplicates
+
+rules:
+x * y == x + y
+x * y == y + x
+x + 0 == x
+0 + x == x
+dec (x + y) == x + dec y
+dec (x + y) == y + dec x
+dec (x + y) == dec x + y
+dec (x + y) == dec y + x
+(x + y) + z == x + (y + z)
+(x + y) + z == y + (x + z)
+equations:
+y + x == x + y
+y + dec x == x + dec y
+dec x + y == x + dec y
+dec y + x == dec x + y
+x + dec 0 == dec x
+dec 0 + x == dec x
+y + (x + z) == x + (y + z)
+z + (x + y) == x + (y + z)
+z + (y + x) == x + (y + z)
+y + dec (dec x) == x + dec (dec y)
+dec (dec x) + y == x + dec (dec y)
+x + dec (dec 0) == dec (dec x)
+dec (dec 0) + x == dec (dec x)
+
+direct candidates:
+
+x ? y  =  x
+
+x ? y  =  y
+
+x ? y  =  0
+
+x ? y  =  dec x
+
+x ? y  =  dec y
+
+x ? y  =  dec 0
+
+x ? y  =  x + x
+
+x ? y  =  x + y
+
+x ? y  =  y + y
+
+x ? y  =  dec (dec x)
+
+x ? y  =  dec (dec y)
+
+x ? y  =  dec (dec 0)
+
+x ? y  =  dec (dec (dec x))
+
+x ? y  =  dec (dec (dec y))
+
+x ? y  =  dec (dec (dec 0))
+
+x ? y  =  x + dec x
+
+x ? y  =  x + dec y
+
+x ? y  =  x + dec 0
+
+x ? y  =  y + dec x
+
+x ? y  =  y + dec y
+
+x ? y  =  y + dec 0
+
+x ? y  =  dec (dec (dec (dec x)))
+
+x ? y  =  dec (dec (dec (dec y)))
+
+x ? y  =  dec (dec (dec (dec 0)))
+
+x ? y  =  x + (x + x)
+
+x ? y  =  x + (x + y)
+
+x ? y  =  x + (y + y)
+
+x ? y  =  x + dec (dec x)
+
+x ? y  =  x + dec (dec y)
+
+x ? y  =  x + dec (dec 0)
+
+x ? y  =  y + (x + x)
+
+x ? y  =  y + (x + y)
+
+x ? y  =  y + (y + y)
+
+x ? y  =  y + dec (dec x)
+
+x ? y  =  y + dec (dec y)
+
+x ? y  =  y + dec (dec 0)
+
+x ? y  =  dec x + dec x
+
+x ? y  =  dec x + dec y
+
+x ? y  =  dec x + dec 0
+
+x ? y  =  dec y + dec y
+
+x ? y  =  dec y + dec 0
+
+x ? y  =  dec 0 + dec 0
+
+x ? y  =  dec (dec (dec (dec (dec x))))
+
+x ? y  =  dec (dec (dec (dec (dec y))))
+
+x ? y  =  dec (dec (dec (dec (dec 0))))
+
+x ? y  =  x + dec (dec (dec x))
+
+x ? y  =  x + dec (dec (dec y))
+
+x ? y  =  x + dec (dec (dec 0))
+
+x ? y  =  x + (x + dec x)
+
+x ? y  =  x + (x + dec y)
+
+x ? y  =  x + (x + dec 0)
+
+x ? y  =  x + (y + dec x)
+
+x ? y  =  x + (y + dec y)
+
+x ? y  =  x + (y + dec 0)
+
+x ? y  =  y + dec (dec (dec x))
+
+x ? y  =  y + dec (dec (dec y))
+
+x ? y  =  y + dec (dec (dec 0))
+
+x ? y  =  y + (x + dec x)
+
+x ? y  =  y + (x + dec y)
+
+x ? y  =  y + (x + dec 0)
+
+x ? y  =  y + (y + dec x)
+
+x ? y  =  y + (y + dec y)
+
+x ? y  =  y + (y + dec 0)
+
+x ? y  =  dec x + (x + x)
+
+x ? y  =  dec x + (x + y)
+
+x ? y  =  dec x + (y + y)
+
+x ? y  =  dec x + dec (dec x)
+
+x ? y  =  dec x + dec (dec y)
+
+x ? y  =  dec x + dec (dec 0)
+
+x ? y  =  dec y + (x + x)
+
+x ? y  =  dec y + (x + y)
+
+x ? y  =  dec y + (y + y)
+
+x ? y  =  dec y + dec (dec x)
+
+x ? y  =  dec y + dec (dec y)
+
+x ? y  =  dec y + dec (dec 0)
+
+x ? y  =  dec 0 + (x + x)
+
+x ? y  =  dec 0 + (x + y)
+
+x ? y  =  dec 0 + (y + y)
+
+x ? y  =  dec 0 + dec (dec x)
+
+x ? y  =  dec 0 + dec (dec y)
+
+x ? y  =  dec 0 + dec (dec 0)
+
+
+pattern candidates:
+
+x ? y  =  x
+
+x ? y  =  y
+
+x ? y  =  0
+
+x ? y  =  dec x
+
+x ? y  =  dec y
+
+x ? 0  =  x
+x ? y  =  y
+
+x ? 0  =  x
+x ? y  =  0
+
+x ? 0  =  0
+x ? y  =  x
+
+0 ? x  =  x
+x ? y  =  x
+
+0 ? x  =  x
+x ? y  =  0
+
+0 ? x  =  0
+x ? y  =  y
+
+x ? y  =  x + x
+
+x ? y  =  x + y
+
+x ? y  =  y + y
+
+x ? y  =  dec (dec x)
+
+x ? y  =  dec (dec y)
+
+x ? 0  =  x
+x ? y  =  dec x
+
+x ? 0  =  x
+x ? y  =  dec y
+
+x ? 0  =  0
+x ? y  =  dec x
+
+x ? 0  =  0
+x ? y  =  dec y
+
+x ? 0  =  dec x
+x ? y  =  x
+
+x ? 0  =  dec x
+x ? y  =  y
+
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  dec x
+
+0 ? x  =  x
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? y  =  dec x
+
+0 ? x  =  0
+x ? y  =  dec y
+
+0 ? x  =  dec x
+x ? y  =  x
+
+0 ? x  =  dec x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y
+
+x ? y  =  dec (dec (dec x))
+
+x ? y  =  dec (dec (dec y))
+
+x ? y  =  x + dec x
+
+x ? y  =  x + dec y
+
+x ? y  =  y + dec x
+
+x ? y  =  y + dec y
+
+x ? 0  =  x
+x ? y  =  x + x
+
+x ? 0  =  x
+x ? y  =  y + y
+
+x ? 0  =  x
+x ? y  =  dec (dec x)
+
+x ? 0  =  x
+x ? y  =  dec (dec y)
+
+x ? 0  =  0
+x ? y  =  x + x
+
+x ? 0  =  0
+x ? y  =  x + y
+
+x ? 0  =  0
+x ? y  =  dec (dec x)
+
+x ? 0  =  0
+x ? y  =  dec (dec y)
+
+x ? 0  =  dec x
+x ? y  =  dec y
+
+x ? 0  =  x + x
+x ? y  =  x
+
+x ? 0  =  x + x
+x ? y  =  y
+
+x ? 0  =  x + x
+x ? y  =  0
+
+x ? 0  =  dec (dec x)
+x ? y  =  x
+
+x ? 0  =  dec (dec x)
+x ? y  =  y
+
+x ? 0  =  dec (dec x)
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  x + x
+
+0 ? x  =  x
+x ? y  =  y + y
+
+0 ? x  =  x
+x ? y  =  dec (dec x)
+
+0 ? x  =  x
+x ? y  =  dec (dec y)
+
+0 ? x  =  0
+x ? y  =  x + y
+
+0 ? x  =  0
+x ? y  =  y + y
+
+0 ? x  =  0
+x ? y  =  dec (dec x)
+
+0 ? x  =  0
+x ? y  =  dec (dec y)
+
+0 ? x  =  dec x
+x ? y  =  dec x
+
+0 ? x  =  x + x
+x ? y  =  x
+
+0 ? x  =  x + x
+x ? y  =  y
+
+0 ? x  =  x + x
+x ? y  =  0
+
+0 ? x  =  dec (dec x)
+x ? y  =  x
+
+0 ? x  =  dec (dec x)
+x ? y  =  y
+
+0 ? x  =  dec (dec x)
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x
+
+x ? 0  =  x
+x ? y  =  x ? dec y
+
+x ? 0  =  x
+x ? y  =  y ? dec x
+
+x ? 0  =  x
+x ? y  =  y ? dec y
+
+x ? 0  =  x
+x ? y  =  0 ? dec y
+
+x ? 0  =  x
+x ? y  =  dec x ? x
+
+x ? 0  =  x
+x ? y  =  dec x ? y
+
+x ? 0  =  x
+x ? y  =  dec y ? x
+
+0 ? x  =  x
+x ? y  =  x ? dec y
+
+0 ? x  =  x
+x ? y  =  y ? dec x
+
+0 ? x  =  x
+x ? y  =  y ? dec y
+
+0 ? x  =  x
+x ? y  =  dec x ? x
+
+0 ? x  =  x
+x ? y  =  dec x ? y
+
+0 ? x  =  x
+x ? y  =  dec x ? 0
+
+0 ? x  =  x
+x ? y  =  dec y ? x
+
+x ? y  =  dec (dec (dec (dec x)))
+
+x ? y  =  dec (dec (dec (dec y)))
+
+x ? y  =  x + (x + x)
+
+x ? y  =  x + (x + y)
+
+x ? y  =  x + (y + y)
+
+x ? y  =  x + dec (dec x)
+
+x ? y  =  x + dec (dec y)
+
+x ? y  =  y + (x + x)
+
+x ? y  =  y + (x + y)
+
+x ? y  =  y + (y + y)
+
+x ? y  =  y + dec (dec x)
+
+x ? y  =  y + dec (dec y)
+
+x ? y  =  dec x + dec x
+
+x ? y  =  dec x + dec y
+
+x ? y  =  dec y + dec y
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec x))
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec y))
+
+x ? 0  =  x
+x ? y  =  x + dec x
+
+x ? 0  =  x
+x ? y  =  x + dec y
+
+x ? 0  =  x
+x ? y  =  y + dec x
+
+x ? 0  =  x
+x ? y  =  y + dec y
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec x))
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec y))
+
+x ? 0  =  0
+x ? y  =  x + dec x
+
+x ? 0  =  0
+x ? y  =  x + dec y
+
+x ? 0  =  0
+x ? y  =  y + dec x
+
+x ? 0  =  0
+x ? y  =  y + dec y
+
+x ? 0  =  dec x
+x ? y  =  x + x
+
+x ? 0  =  dec x
+x ? y  =  x + y
+
+x ? 0  =  dec x
+x ? y  =  y + y
+
+x ? 0  =  dec x
+x ? y  =  dec (dec x)
+
+x ? 0  =  dec x
+x ? y  =  dec (dec y)
+
+x ? 0  =  x + x
+x ? y  =  dec x
+
+x ? 0  =  x + x
+x ? y  =  dec y
+
+x ? 0  =  dec (dec x)
+x ? y  =  dec x
+
+x ? 0  =  dec (dec x)
+x ? y  =  dec y
+
+x ? 0  =  dec (dec (dec x))
+x ? y  =  x
+
+x ? 0  =  dec (dec (dec x))
+x ? y  =  y
+
+x ? 0  =  dec (dec (dec x))
+x ? y  =  0
+
+x ? 0  =  x + dec x
+x ? y  =  x
+
+x ? 0  =  x + dec x
+x ? y  =  y
+
+x ? 0  =  x + dec x
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  x
+x ? y  =  x + dec x
+
+0 ? x  =  x
+x ? y  =  x + dec y
+
+0 ? x  =  x
+x ? y  =  y + dec x
+
+0 ? x  =  x
+x ? y  =  y + dec y
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  0
+x ? y  =  x + dec x
+
+0 ? x  =  0
+x ? y  =  x + dec y
+
+0 ? x  =  0
+x ? y  =  y + dec x
+
+0 ? x  =  0
+x ? y  =  y + dec y
+
+0 ? x  =  dec x
+x ? y  =  x + x
+
+0 ? x  =  dec x
+x ? y  =  x + y
+
+0 ? x  =  dec x
+x ? y  =  y + y
+
+0 ? x  =  dec x
+x ? y  =  dec (dec x)
+
+0 ? x  =  dec x
+x ? y  =  dec (dec y)
+
+0 ? x  =  x + x
+x ? y  =  dec x
+
+0 ? x  =  x + x
+x ? y  =  dec y
+
+0 ? x  =  dec (dec x)
+x ? y  =  dec x
+
+0 ? x  =  dec (dec x)
+x ? y  =  dec y
+
+0 ? x  =  dec (dec (dec x))
+x ? y  =  x
+
+0 ? x  =  dec (dec (dec x))
+x ? y  =  y
+
+0 ? x  =  dec (dec (dec x))
+x ? y  =  0
+
+0 ? x  =  x + dec x
+x ? y  =  x
+
+0 ? x  =  x + dec x
+x ? y  =  y
+
+0 ? x  =  x + dec x
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec x)
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec y)
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec x)
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec y)
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  dec (dec x)
+x ? y  =  x
+
+0 ? x  =  x
+x ? 0  =  dec (dec x)
+x ? y  =  0
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec x)
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec y)
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec (dec x)
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec (dec y)
+
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? x  =  0
+x ? 0  =  dec (dec x)
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? x  =  dec (dec x)
+x ? 0  =  x
+x ? y  =  y
+
+0 ? x  =  dec (dec x)
+x ? 0  =  x
+x ? y  =  0
+
+0 ? x  =  dec (dec x)
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? y  =  dec x
+
+x ? 0  =  x
+x ? y  =  x ? dec (dec y)
+
+x ? 0  =  x
+x ? y  =  y ? dec (dec x)
+
+x ? 0  =  x
+x ? y  =  y ? dec (dec y)
+
+x ? 0  =  x
+x ? y  =  0 ? dec (dec y)
+
+x ? 0  =  x
+x ? y  =  dec x ? dec x
+
+x ? 0  =  x
+x ? y  =  dec x ? dec y
+
+x ? 0  =  x
+x ? y  =  dec y ? dec x
+
+x ? 0  =  x
+x ? y  =  dec y ? dec y
+
+x ? 0  =  x
+x ? y  =  dec (dec x) ? x
+
+x ? 0  =  x
+x ? y  =  dec (dec x) ? y
+
+x ? 0  =  x
+x ? y  =  dec (dec y) ? x
+
+0 ? x  =  x
+x ? y  =  x ? dec (dec y)
+
+0 ? x  =  x
+x ? y  =  y ? dec (dec x)
+
+0 ? x  =  x
+x ? y  =  y ? dec (dec y)
+
+0 ? x  =  x
+x ? y  =  dec x ? dec x
+
+0 ? x  =  x
+x ? y  =  dec x ? dec y
+
+0 ? x  =  x
+x ? y  =  dec y ? dec x
+
+0 ? x  =  x
+x ? y  =  dec y ? dec y
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? x
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? y
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? 0
+
+0 ? x  =  x
+x ? y  =  dec (dec y) ? x
+
+x ? 0  =  x
+x ? y  =  dec (x ? dec y)
+
+x ? 0  =  x
+x ? y  =  dec (y ? dec x)
+
+x ? 0  =  x
+x ? y  =  dec (y ? dec y)
+
+x ? 0  =  x
+x ? y  =  dec (0 ? dec y)
+
+x ? 0  =  x
+x ? y  =  dec (dec x ? x)
+
+x ? 0  =  x
+x ? y  =  dec (dec x ? y)
+
+x ? 0  =  x
+x ? y  =  dec (dec y ? x)
+
+x ? 0  =  0
+x ? y  =  dec (x ? dec y)
+
+x ? 0  =  0
+x ? y  =  dec (y ? dec x)
+
+x ? 0  =  0
+x ? y  =  dec (y ? dec y)
+
+x ? 0  =  0
+x ? y  =  dec (0 ? dec y)
+
+x ? 0  =  0
+x ? y  =  dec (dec x ? x)
+
+x ? 0  =  0
+x ? y  =  dec (dec x ? y)
+
+x ? 0  =  0
+x ? y  =  dec (dec y ? x)
+
+x ? 0  =  dec x
+x ? y  =  x ? dec y
+
+x ? 0  =  dec x
+x ? y  =  y ? dec x
+
+x ? 0  =  dec x
+x ? y  =  y ? dec y
+
+x ? 0  =  dec x
+x ? y  =  0 ? dec y
+
+x ? 0  =  dec x
+x ? y  =  dec x ? x
+
+x ? 0  =  dec x
+x ? y  =  dec x ? y
+
+x ? 0  =  dec x
+x ? y  =  dec y ? x
+
+0 ? x  =  x
+x ? y  =  dec (x ? dec y)
+
+0 ? x  =  x
+x ? y  =  dec (y ? dec x)
+
+0 ? x  =  x
+x ? y  =  dec (y ? dec y)
+
+0 ? x  =  x
+x ? y  =  dec (dec x ? x)
+
+0 ? x  =  x
+x ? y  =  dec (dec x ? y)
+
+0 ? x  =  x
+x ? y  =  dec (dec x ? 0)
+
+0 ? x  =  x
+x ? y  =  dec (dec y ? x)
+
+0 ? x  =  0
+x ? y  =  dec (x ? dec y)
+
+0 ? x  =  0
+x ? y  =  dec (y ? dec x)
+
+0 ? x  =  0
+x ? y  =  dec (y ? dec y)
+
+0 ? x  =  0
+x ? y  =  dec (dec x ? x)
+
+0 ? x  =  0
+x ? y  =  dec (dec x ? y)
+
+0 ? x  =  0
+x ? y  =  dec (dec x ? 0)
+
+0 ? x  =  0
+x ? y  =  dec (dec y ? x)
+
+0 ? x  =  dec x
+x ? y  =  x ? dec y
+
+0 ? x  =  dec x
+x ? y  =  y ? dec x
+
+0 ? x  =  dec x
+x ? y  =  y ? dec y
+
+0 ? x  =  dec x
+x ? y  =  dec x ? x
+
+0 ? x  =  dec x
+x ? y  =  dec x ? y
+
+0 ? x  =  dec x
+x ? y  =  dec x ? 0
+
+0 ? x  =  dec x
+x ? y  =  dec y ? x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x ? dec y
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y ? dec x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y ? dec y
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x ? x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x ? y
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y ? x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x ? dec y
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y ? dec x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y ? dec y
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x ? x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x ? y
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y ? x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x ? dec y
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y ? dec x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y ? dec y
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x ? x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x ? y
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y ? x
+
+x ? y  =  dec (dec (dec (dec (dec x))))
+
+x ? y  =  dec (dec (dec (dec (dec y))))
+
+x ? y  =  x + dec (dec (dec x))
+
+x ? y  =  x + dec (dec (dec y))
+
+x ? y  =  x + (x + dec x)
+
+x ? y  =  x + (x + dec y)
+
+x ? y  =  x + (y + dec x)
+
+x ? y  =  x + (y + dec y)
+
+x ? y  =  y + dec (dec (dec x))
+
+x ? y  =  y + dec (dec (dec y))
+
+x ? y  =  y + (x + dec x)
+
+x ? y  =  y + (x + dec y)
+
+x ? y  =  y + (y + dec x)
+
+x ? y  =  y + (y + dec y)
+
+x ? y  =  dec x + (x + x)
+
+x ? y  =  dec x + (x + y)
+
+x ? y  =  dec x + (y + y)
+
+x ? y  =  dec x + dec (dec x)
+
+x ? y  =  dec x + dec (dec y)
+
+x ? y  =  dec y + (x + x)
+
+x ? y  =  dec y + (x + y)
+
+x ? y  =  dec y + (y + y)
+
+x ? y  =  dec y + dec (dec x)
+
+x ? y  =  dec y + dec (dec y)
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec (dec x)))
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec (dec y)))
+
+x ? 0  =  x
+x ? y  =  x + (x + x)
+
+x ? 0  =  x
+x ? y  =  x + (x + y)
+
+x ? 0  =  x
+x ? y  =  x + dec (dec x)
+
+x ? 0  =  x
+x ? y  =  x + dec (dec y)
+
+x ? 0  =  x
+x ? y  =  y + (x + x)
+
+x ? 0  =  x
+x ? y  =  y + (y + y)
+
+x ? 0  =  x
+x ? y  =  y + dec (dec x)
+
+x ? 0  =  x
+x ? y  =  y + dec (dec y)
+
+x ? 0  =  x
+x ? y  =  dec x + dec x
+
+x ? 0  =  x
+x ? y  =  dec x + dec y
+
+x ? 0  =  x
+x ? y  =  dec y + dec y
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec (dec x)))
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec (dec y)))
+
+x ? 0  =  0
+x ? y  =  x + (x + x)
+
+x ? 0  =  0
+x ? y  =  x + (x + y)
+
+x ? 0  =  0
+x ? y  =  x + (y + y)
+
+x ? 0  =  0
+x ? y  =  x + dec (dec x)
+
+x ? 0  =  0
+x ? y  =  x + dec (dec y)
+
+x ? 0  =  0
+x ? y  =  y + (x + x)
+
+x ? 0  =  0
+x ? y  =  y + (x + y)
+
+x ? 0  =  0
+x ? y  =  y + dec (dec x)
+
+x ? 0  =  0
+x ? y  =  y + dec (dec y)
+
+x ? 0  =  0
+x ? y  =  dec x + dec x
+
+x ? 0  =  0
+x ? y  =  dec x + dec y
+
+x ? 0  =  0
+x ? y  =  dec y + dec y
+
+x ? 0  =  dec x
+x ? y  =  dec (dec (dec x))
+
+x ? 0  =  dec x
+x ? y  =  dec (dec (dec y))
+
+x ? 0  =  dec x
+x ? y  =  x + dec x
+
+x ? 0  =  dec x
+x ? y  =  x + dec y
+
+x ? 0  =  dec x
+x ? y  =  y + dec y
+
+x ? 0  =  x + x
+x ? y  =  x + y
+
+x ? 0  =  x + x
+x ? y  =  y + y
+
+x ? 0  =  x + x
+x ? y  =  dec (dec x)
+
+x ? 0  =  x + x
+x ? y  =  dec (dec y)
+
+x ? 0  =  dec (dec x)
+x ? y  =  x + x
+
+x ? 0  =  dec (dec x)
+x ? y  =  x + y
+
+x ? 0  =  dec (dec x)
+x ? y  =  y + y
+
+x ? 0  =  dec (dec x)
+x ? y  =  dec (dec y)
+
+x ? 0  =  dec (dec (dec x))
+x ? y  =  dec x
+
+x ? 0  =  dec (dec (dec x))
+x ? y  =  dec y
+
+x ? 0  =  x + dec x
+x ? y  =  dec x
+
+x ? 0  =  x + dec x
+x ? y  =  dec y
+
+x ? 0  =  dec (dec (dec (dec x)))
+x ? y  =  x
+
+x ? 0  =  dec (dec (dec (dec x)))
+x ? y  =  y
+
+x ? 0  =  dec (dec (dec (dec x)))
+x ? y  =  0
+
+x ? 0  =  x + (x + x)
+x ? y  =  x
+
+x ? 0  =  x + (x + x)
+x ? y  =  y
+
+x ? 0  =  x + (x + x)
+x ? y  =  0
+
+x ? 0  =  x + dec (dec x)
+x ? y  =  x
+
+x ? 0  =  x + dec (dec x)
+x ? y  =  y
+
+x ? 0  =  x + dec (dec x)
+x ? y  =  0
+
+x ? 0  =  dec x + dec x
+x ? y  =  x
+
+x ? 0  =  dec x + dec x
+x ? y  =  y
+
+x ? 0  =  dec x + dec x
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec (dec x)))
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec (dec y)))
+
+0 ? x  =  x
+x ? y  =  x + (x + x)
+
+0 ? x  =  x
+x ? y  =  x + (y + y)
+
+0 ? x  =  x
+x ? y  =  x + dec (dec x)
+
+0 ? x  =  x
+x ? y  =  x + dec (dec y)
+
+0 ? x  =  x
+x ? y  =  y + (x + y)
+
+0 ? x  =  x
+x ? y  =  y + (y + y)
+
+0 ? x  =  x
+x ? y  =  y + dec (dec x)
+
+0 ? x  =  x
+x ? y  =  y + dec (dec y)
+
+0 ? x  =  x
+x ? y  =  dec x + dec x
+
+0 ? x  =  x
+x ? y  =  dec x + dec y
+
+0 ? x  =  x
+x ? y  =  dec y + dec y
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec (dec x)))
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec (dec y)))
+
+0 ? x  =  0
+x ? y  =  x + (x + y)
+
+0 ? x  =  0
+x ? y  =  x + (y + y)
+
+0 ? x  =  0
+x ? y  =  x + dec (dec x)
+
+0 ? x  =  0
+x ? y  =  x + dec (dec y)
+
+0 ? x  =  0
+x ? y  =  y + (x + x)
+
+0 ? x  =  0
+x ? y  =  y + (x + y)
+
+0 ? x  =  0
+x ? y  =  y + (y + y)
+
+0 ? x  =  0
+x ? y  =  y + dec (dec x)
+
+0 ? x  =  0
+x ? y  =  y + dec (dec y)
+
+0 ? x  =  0
+x ? y  =  dec x + dec x
+
+0 ? x  =  0
+x ? y  =  dec x + dec y
+
+0 ? x  =  0
+x ? y  =  dec y + dec y
+
+0 ? x  =  dec x
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  dec x
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  dec x
+x ? y  =  x + dec x
+
+0 ? x  =  dec x
+x ? y  =  y + dec x
+
+0 ? x  =  dec x
+x ? y  =  y + dec y
+
+0 ? x  =  x + x
+x ? y  =  x + x
+
+0 ? x  =  x + x
+x ? y  =  x + y
+
+0 ? x  =  x + x
+x ? y  =  dec (dec x)
+
+0 ? x  =  x + x
+x ? y  =  dec (dec y)
+
+0 ? x  =  dec (dec x)
+x ? y  =  x + x
+
+0 ? x  =  dec (dec x)
+x ? y  =  x + y
+
+0 ? x  =  dec (dec x)
+x ? y  =  y + y
+
+0 ? x  =  dec (dec x)
+x ? y  =  dec (dec x)
+
+0 ? x  =  dec (dec (dec x))
+x ? y  =  dec x
+
+0 ? x  =  dec (dec (dec x))
+x ? y  =  dec y
+
+0 ? x  =  x + dec x
+x ? y  =  dec x
+
+0 ? x  =  x + dec x
+x ? y  =  dec y
+
+0 ? x  =  dec (dec (dec (dec x)))
+x ? y  =  x
+
+0 ? x  =  dec (dec (dec (dec x)))
+x ? y  =  y
+
+0 ? x  =  dec (dec (dec (dec x)))
+x ? y  =  0
+
+0 ? x  =  x + (x + x)
+x ? y  =  x
+
+0 ? x  =  x + (x + x)
+x ? y  =  y
+
+0 ? x  =  x + (x + x)
+x ? y  =  0
+
+0 ? x  =  x + dec (dec x)
+x ? y  =  x
+
+0 ? x  =  x + dec (dec x)
+x ? y  =  y
+
+0 ? x  =  x + dec (dec x)
+x ? y  =  0
+
+0 ? x  =  dec x + dec x
+x ? y  =  x
+
+0 ? x  =  dec x + dec x
+x ? y  =  y
+
+0 ? x  =  dec x + dec x
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + dec x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + dec y
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + dec x
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + dec y
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + dec x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + dec y
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + dec x
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + dec y
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  x + x
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  y + y
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec (dec x)
+
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec (dec y)
+
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  dec x
+
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  dec y
+
+0 ? x  =  x
+x ? 0  =  dec (dec x)
+x ? y  =  dec x
+
+0 ? x  =  x
+x ? 0  =  dec (dec x)
+x ? y  =  dec y
+
+0 ? x  =  x
+x ? 0  =  dec (dec (dec x))
+x ? y  =  x
+
+0 ? x  =  x
+x ? 0  =  dec (dec (dec x))
+x ? y  =  0
+
+0 ? x  =  x
+x ? 0  =  x + dec x
+x ? y  =  x
+
+0 ? x  =  x
+x ? 0  =  x + dec x
+x ? y  =  0
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + dec x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + dec y
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + dec x
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + dec y
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec (dec (dec x))
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec (dec (dec y))
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + dec x
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + dec y
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + dec x
+
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + dec y
+
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  x + y
+
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  y + y
+
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec (dec x)
+
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec (dec y)
+
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  dec x
+
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? 0  =  dec (dec x)
+x ? y  =  dec x
+
+0 ? x  =  0
+x ? 0  =  dec (dec x)
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? 0  =  dec (dec (dec x))
+x ? y  =  y
+
+0 ? x  =  0
+x ? 0  =  x + dec x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec (dec x)
+
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec (dec y)
+
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec (dec x)
+
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec (dec y)
+
+0 ? x  =  dec x
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? x  =  dec x
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? x  =  dec x
+x ? 0  =  dec (dec x)
+x ? y  =  x
+
+0 ? x  =  dec x
+x ? 0  =  dec (dec x)
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? 0  =  dec (dec x)
+x ? y  =  0
+
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? x  =  x + x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? x  =  x + x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? x  =  x + x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? x  =  dec (dec x)
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? x  =  dec (dec x)
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? x  =  dec (dec x)
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? x  =  dec (dec x)
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? x  =  dec (dec x)
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? x  =  dec (dec x)
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? x  =  dec (dec x)
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? x  =  dec (dec (dec x))
+x ? 0  =  x
+x ? y  =  y
+
+0 ? x  =  dec (dec (dec x))
+x ? 0  =  x
+x ? y  =  0
+
+0 ? x  =  dec (dec (dec x))
+x ? 0  =  0
+x ? y  =  x
+
+0 ? x  =  x + dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? x  =  x + dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? x  =  x + dec x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? y  =  dec (dec x)
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? y  =  dec (dec y)
+
+0 ? 0  =  0
+0 ? x  =  dec (dec x)
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec (dec x)
+x ? y  =  dec y
+
+
+Candidates for: goo :: [Int] -> [Int]
+  pruning with 4/4 rules
+  [2,0,1,0,1,0,1,0,1] direct candidates, 0 duplicates
+  [2,1,1,3,4,7,10,17,26] pattern candidates, 0 duplicates
+
+rules:
+xs ++ [] == xs
+[] ++ xs == xs
+(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
+(x:xs) ++ ys == x:(xs ++ ys)
+
+direct candidates:
+
+goo xs  =  xs
+
+goo xs  =  []
+
+goo xs  =  xs ++ xs
+
+goo xs  =  xs ++ (xs ++ xs)
+
+
+pattern candidates:
+
+goo xs  =  xs
+
+goo xs  =  []
+
+goo []  =  []
+goo (x:xs)  =  xs
+
+goo xs  =  xs ++ xs
+
+goo []  =  []
+goo (x:xs)  =  x:xs
+
+goo []  =  []
+goo (x:xs)  =  [x]
+
+goo []  =  []
+goo (x:xs)  =  xs ++ xs
+
+goo []  =  []
+goo (x:xs)  =  x:goo xs
+
+goo []  =  []
+goo (x:xs)  =  xs ++ goo xs
+
+goo []  =  []
+goo (x:xs)  =  goo xs ++ xs
+
+goo xs  =  xs ++ (xs ++ xs)
+
+goo []  =  []
+goo (x:xs)  =  goo xs ++ goo xs
+
+goo []  =  []
+goo (x:xs)  =  x:x:xs
+
+goo []  =  []
+goo (x:xs)  =  [x,x]
+
+goo []  =  []
+goo (x:xs)  =  x:(xs ++ xs)
+
+goo []  =  []
+goo (x:xs)  =  xs ++ (x:xs)
+
+goo []  =  []
+goo (x:xs)  =  xs ++ [x]
+
+goo []  =  []
+goo (x:xs)  =  xs ++ (xs ++ xs)
+
+
+Candidates for: ?? :: [Int] -> [Int] -> [Int]
+  pruning with 4/4 rules
+  [3,0,4,0,8,0,16,0,32] direct candidates, 0 duplicates
+  [3,8,15,45,127,268,845,1565,5692] pattern candidates, 0 duplicates
+
+rules:
+xs ++ [] == xs
+[] ++ xs == xs
+(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
+(x:xs) ++ ys == x:(xs ++ ys)
+
+direct candidates:
+
+xs ?? ys  =  xs
+
+xs ?? ys  =  ys
+
+xs ?? ys  =  []
+
+xs ?? ys  =  xs ++ xs
+
+xs ?? ys  =  xs ++ ys
+
+xs ?? ys  =  ys ++ xs
+
+xs ?? ys  =  ys ++ ys
+
+xs ?? ys  =  xs ++ (xs ++ xs)
+
+xs ?? ys  =  xs ++ (xs ++ ys)
+
+xs ?? ys  =  xs ++ (ys ++ xs)
+
+xs ?? ys  =  xs ++ (ys ++ ys)
+
+xs ?? ys  =  ys ++ (xs ++ xs)
+
+xs ?? ys  =  ys ++ (xs ++ ys)
+
+xs ?? ys  =  ys ++ (ys ++ xs)
+
+xs ?? ys  =  ys ++ (ys ++ ys)
+
+
+pattern candidates:
+
+xs ?? ys  =  xs
+
+xs ?? ys  =  ys
+
+xs ?? ys  =  []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys
+
+xs ?? ys  =  xs ++ xs
+
+xs ?? ys  =  xs ++ ys
+
+xs ?? ys  =  ys ++ xs
+
+xs ?? ys  =  ys ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [] ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [] ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [x]
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  [x]
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  xs
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  [x]
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  [x]
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  xs ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  xs ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  xs ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  ys ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  ys ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  [] ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  [] ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? ys  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? ys  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? ys  =  ys
+
+xs ?? ys  =  xs ++ (xs ++ xs)
+
+xs ?? ys  =  xs ++ (xs ++ ys)
+
+xs ?? ys  =  xs ++ (ys ++ xs)
+
+xs ?? ys  =  xs ++ (ys ++ ys)
+
+xs ?? ys  =  ys ++ (xs ++ xs)
+
+xs ?? ys  =  ys ++ (xs ++ ys)
+
+xs ?? ys  =  ys ++ (ys ++ xs)
+
+xs ?? ys  =  ys ++ (ys ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  []
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  x:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  x:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  [x]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  xs ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  xs ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  ys ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? ys  =  ys ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? ys  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? ys  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? ys  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? ys  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? ys  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? ys  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? ys  =  []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:xs) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:ys) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [x] ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (xs ++ xs) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (xs ++ ys) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (ys ++ xs) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (ys ++ ys) ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? (x:xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? (x:ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? [x]
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? (xs ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? (xs ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? (ys ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? (ys ++ ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:[] ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:[] ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ [] ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ [] ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ [] ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ [] ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ?? ys ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? xs ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? ys ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [] ?? xs ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [] ?? ys ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ?? ys ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? xs ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? ys ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [] ?? xs ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [] ?? ys ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:xs ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:[] ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:[] ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ xs ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ [] ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ [] ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ xs ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ [] ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ [] ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ?? ys ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? xs ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? ys ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  [] ?? xs ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  [] ?? ys ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ?? ys ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? xs ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? ys ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  [] ?? xs ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  [] ?? ys ++ ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  xs ?? ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys ?? xs
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys ?? ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  [] ?? xs
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  [] ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:xs ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:xs ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:xs ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:ys ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:ys ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ xs ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ xs ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ xs ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ ys ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ ys ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ xs ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ xs ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ xs ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ ys ?? xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ ys ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? xs ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? ys ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? [] ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? xs ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? [] ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? xs ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? ys ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ?? [] ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? xs ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? [] ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:xs ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:xs ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:xs ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:ys ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ xs ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ xs ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ xs ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ ys ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ xs ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ xs ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ xs ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ ys ?? xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ?? xs ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ?? ys ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ?? [] ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ?? xs ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ?? [] ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ?? xs ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ?? ys ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ?? [] ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ?? xs ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ?? [] ++ ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  xs ?? xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  xs ?? ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  xs ?? []
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  ys ?? xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  ys ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [] ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [] ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  [] ?? xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  [] ?? xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:x:xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:x:ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  [x,x]
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:(xs ++ xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:(xs ++ ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:(ys ++ xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:(ys ++ ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ (x:xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ (x:ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ [x]
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ (xs ++ xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ (xs ++ ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ (ys ++ xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ (ys ++ ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ (x:xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ (x:ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ [x]
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ (xs ++ xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ (xs ++ ys)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ (ys ++ xs)
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ (ys ++ ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:x:xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:x:ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  [x,x]
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:(xs ++ xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:(xs ++ ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:(ys ++ xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:(ys ++ ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ (x:xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ (x:ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ [x]
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ (xs ++ xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ (xs ++ ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ (ys ++ xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ (ys ++ ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ (x:xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ (x:ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ [x]
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ (xs ++ xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ (xs ++ ys)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ (ys ++ xs)
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ (ys ++ ys)
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  x:xs
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  x:ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  [x]
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  xs ++ ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys ++ xs
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys ++ ys
+
+xs ?? []  =  xs ++ (xs ++ xs)
+xs ?? (x:ys)  =  xs
+
+xs ?? []  =  xs ++ (xs ++ xs)
+xs ?? (x:ys)  =  ys
+
+xs ?? []  =  xs ++ (xs ++ xs)
+xs ?? (x:ys)  =  []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:x:xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:x:ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  [x,x]
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:(xs ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:(xs ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:(ys ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  x:(ys ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ (x:xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ (x:ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ [x]
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ (xs ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ (xs ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ (ys ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ (ys ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ (x:xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ (x:ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ [x]
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ (xs ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ (xs ++ ys)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ (ys ++ xs)
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ (ys ++ ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:x:xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:x:ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  [x,x]
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:(xs ++ xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:(xs ++ ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:(ys ++ xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:(ys ++ ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ (x:xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ (x:ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ [x]
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ (xs ++ xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ (xs ++ ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ (ys ++ xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ (ys ++ ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ (x:xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ (x:ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ [x]
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ (xs ++ xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ (xs ++ ys)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ (ys ++ xs)
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ (ys ++ ys)
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  x:xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  x:ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  [x]
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  xs ++ xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  xs ++ ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  ys ++ xs
+
+[] ?? xs  =  xs ++ (xs ++ xs)
+(x:xs) ?? ys  =  xs
+
+[] ?? xs  =  xs ++ (xs ++ xs)
+(x:xs) ?? ys  =  ys
+
+[] ?? xs  =  xs ++ (xs ++ xs)
+(x:xs) ?? ys  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+
+Candidates for: ton :: Bool -> Bool
+  pruning with 39/49 rules
+  [3,1,0,0,0,0,0,0,0] direct candidates, 0 duplicates
+  [3,3,0,0,0,0,0,0,0] pattern candidates, 0 duplicates
+
+rules:
+not False == True
+not True == False
+p && p == p
+p || p == p
+not (not p) == p
+p && False == False
+p && True == p
+False && p == False
+True && p == p
+p || False == p
+p || True == True
+False || p == p
+True || p == True
+not (p && q) == not p || not q
+not (p && q) == not q || not p
+not (p || q) == not p && not q
+not (p || q) == not q && not p
+p && not p == False
+not p && p == False
+p || not p == True
+not p || p == True
+(p && q) && r == p && (q && r)
+(p && q) && r == q && (p && r)
+(p || q) || r == p || (q || r)
+(p || q) || r == q || (p || r)
+p && (p && q) == p && q
+p && (q && p) == p && q
+p && (q && p) == q && p
+p || (p || q) == p || q
+p || (q || p) == p || q
+p || (q || p) == q || p
+p && (p || q) == p
+p && (q || p) == p
+(p || q) && p == p
+(p || q) && q == q
+p || p && q == p
+p || q && p == p
+p && q || p == p
+p && q || q == q
+equations:
+q && p == p && q
+q || p == p || q
+q && (p && r) == p && (q && r)
+r && (p && q) == p && (q && r)
+r && (q && p) == p && (q && r)
+q || (p || r) == p || (q || r)
+r || (p || q) == p || (q || r)
+r || (q || p) == p || (q || r)
+(r || q) && p == p && (q || r)
+r && q || p == p || q && r
+
+direct candidates:
+
+ton p  =  p
+
+ton p  =  False
+
+ton p  =  True
+
+ton p  =  not p
+
+
+pattern candidates:
+
+ton p  =  p
+
+ton p  =  False
+
+ton p  =  True
+
+ton p  =  not p
+
+ton False  =  False
+ton True  =  True
+
+ton False  =  True
+ton True  =  False
+
+
+Candidates for: &| :: Bool -> Bool -> Bool
+  pruning with 39/49 rules
+  [4,2,2,4,2,16,18,60,120] direct candidates, 0 duplicates
+  [4,14,26,10,2,16,18,60,120] pattern candidates, 0 duplicates
+
+rules:
+not False == True
+not True == False
+p && p == p
+p || p == p
+not (not p) == p
+p && False == False
+p && True == p
+False && p == False
+True && p == p
+p || False == p
+p || True == True
+False || p == p
+True || p == True
+not (p && q) == not p || not q
+not (p && q) == not q || not p
+not (p || q) == not p && not q
+not (p || q) == not q && not p
+p && not p == False
+not p && p == False
+p || not p == True
+not p || p == True
+(p && q) && r == p && (q && r)
+(p && q) && r == q && (p && r)
+(p || q) || r == p || (q || r)
+(p || q) || r == q || (p || r)
+p && (p && q) == p && q
+p && (q && p) == p && q
+p && (q && p) == q && p
+p || (p || q) == p || q
+p || (q || p) == p || q
+p || (q || p) == q || p
+p && (p || q) == p
+p && (q || p) == p
+(p || q) && p == p
+(p || q) && q == q
+p || p && q == p
+p || q && p == p
+p && q || p == p
+p && q || q == q
+equations:
+q && p == p && q
+q || p == p || q
+q && (p && r) == p && (q && r)
+r && (p && q) == p && (q && r)
+r && (q && p) == p && (q && r)
+q || (p || r) == p || (q || r)
+r || (p || q) == p || (q || r)
+r || (q || p) == p || (q || r)
+(r || q) && p == p && (q || r)
+r && q || p == p || q && r
+
+direct candidates:
+
+p &| q  =  p
+
+p &| q  =  q
+
+p &| q  =  False
+
+p &| q  =  True
+
+p &| q  =  not p
+
+p &| q  =  not q
+
+p &| q  =  p && q
+
+p &| q  =  p || q
+
+p &| q  =  p && not q
+
+p &| q  =  q && not p
+
+p &| q  =  p || not q
+
+p &| q  =  q || not p
+
+p &| q  =  not p && not q
+
+p &| q  =  not p || not q
+
+p &| q  =  p && (q && not p)
+
+p &| q  =  p && (q || not p)
+
+p &| q  =  q && (p && not q)
+
+p &| q  =  q && (p || not q)
+
+p &| q  =  p || q && not p
+
+p &| q  =  p || (q || not p)
+
+p &| q  =  q || p && not q
+
+p &| q  =  q || (p || not q)
+
+p &| q  =  not p && (p && q)
+
+p &| q  =  not p && (p || q)
+
+p &| q  =  not q && (p && q)
+
+p &| q  =  not q && (p || q)
+
+p &| q  =  not p || p && q
+
+p &| q  =  not p || (p || q)
+
+p &| q  =  not q || p && q
+
+p &| q  =  not q || (p || q)
+
+
+pattern candidates:
+
+p &| q  =  p
+
+p &| q  =  q
+
+p &| q  =  False
+
+p &| q  =  True
+
+p &| q  =  not p
+
+p &| q  =  not q
+
+p &| False  =  p
+p &| True  =  False
+
+p &| False  =  p
+p &| True  =  True
+
+p &| False  =  False
+p &| True  =  p
+
+p &| False  =  False
+p &| True  =  True
+
+p &| False  =  True
+p &| True  =  p
+
+p &| False  =  True
+p &| True  =  False
+
+False &| p  =  p
+True &| p  =  False
+
+False &| p  =  p
+True &| p  =  True
+
+False &| p  =  False
+True &| p  =  p
+
+False &| p  =  False
+True &| p  =  True
+
+False &| p  =  True
+True &| p  =  p
+
+False &| p  =  True
+True &| p  =  False
+
+p &| q  =  p && q
+
+p &| q  =  p || q
+
+p &| False  =  p
+p &| True  =  not p
+
+p &| False  =  False
+p &| True  =  not p
+
+p &| False  =  True
+p &| True  =  not p
+
+p &| False  =  not p
+p &| True  =  p
+
+p &| False  =  not p
+p &| True  =  False
+
+p &| False  =  not p
+p &| True  =  True
+
+False &| p  =  p
+True &| p  =  not p
+
+False &| p  =  False
+True &| p  =  not p
+
+False &| p  =  True
+True &| p  =  not p
+
+False &| p  =  not p
+True &| p  =  p
+
+False &| p  =  not p
+True &| p  =  False
+
+False &| p  =  not p
+True &| p  =  True
+
+False &| p  =  p
+True &| False  =  False
+True &| True  =  True
+
+False &| p  =  p
+True &| False  =  True
+True &| True  =  False
+
+False &| p  =  False
+True &| False  =  False
+True &| True  =  True
+
+False &| p  =  False
+True &| False  =  True
+True &| True  =  False
+
+False &| p  =  True
+True &| False  =  False
+True &| True  =  True
+
+False &| p  =  True
+True &| False  =  True
+True &| True  =  False
+
+False &| False  =  False
+False &| True  =  True
+True &| p  =  p
+
+False &| False  =  False
+False &| True  =  True
+True &| p  =  False
+
+False &| False  =  False
+False &| True  =  True
+True &| p  =  True
+
+False &| False  =  True
+False &| True  =  False
+True &| p  =  p
+
+False &| False  =  True
+False &| True  =  False
+True &| p  =  False
+
+False &| False  =  True
+False &| True  =  False
+True &| p  =  True
+
+p &| q  =  p && not q
+
+p &| q  =  q && not p
+
+p &| q  =  p || not q
+
+p &| q  =  q || not p
+
+False &| p  =  not p
+True &| False  =  False
+True &| True  =  True
+
+False &| p  =  not p
+True &| False  =  True
+True &| True  =  False
+
+False &| False  =  False
+False &| True  =  True
+True &| p  =  not p
+
+False &| False  =  True
+False &| True  =  False
+True &| p  =  not p
+
+False &| False  =  False
+False &| True  =  True
+True &| False  =  True
+True &| True  =  False
+
+False &| False  =  True
+False &| True  =  False
+True &| False  =  False
+True &| True  =  True
+
+p &| q  =  not p && not q
+
+p &| q  =  not p || not q
+
+p &| q  =  p && (q && not p)
+
+p &| q  =  p && (q || not p)
+
+p &| q  =  q && (p && not q)
+
+p &| q  =  q && (p || not q)
+
+p &| q  =  p || q && not p
+
+p &| q  =  p || (q || not p)
+
+p &| q  =  q || p && not q
+
+p &| q  =  q || (p || not q)
+
+p &| q  =  not p && (p && q)
+
+p &| q  =  not p && (p || q)
+
+p &| q  =  not q && (p && q)
+
+p &| q  =  not q && (p || q)
+
+p &| q  =  not p || p && q
+
+p &| q  =  not p || (p || q)
+
+p &| q  =  not q || p && q
+
+p &| q  =  not q || (p || q)
+
+
+Candidates for: gcd :: Int -> Int -> Int
+  pruning with 0/0 rules
+  [3,0,9,0,54,0,405,0,3402] direct candidates, 0 duplicates
+  [3,6,11,50,98,344,792,2956,6945] pattern candidates, 0 duplicates
+
+no rules.
+
+direct candidates:
+
+gcd x y  =  x
+
+gcd x y  =  y
+
+gcd x y  =  0
+
+gcd x y  =  x `mod` x
+
+gcd x y  =  x `mod` y
+
+gcd x y  =  x `mod` 0
+
+gcd x y  =  y `mod` x
+
+gcd x y  =  y `mod` y
+
+gcd x y  =  y `mod` 0
+
+gcd x y  =  0 `mod` x
+
+gcd x y  =  0 `mod` y
+
+gcd x y  =  0 `mod` 0
+
+gcd x y  =  (x `mod` x) `mod` x
+
+gcd x y  =  (x `mod` x) `mod` y
+
+gcd x y  =  (x `mod` x) `mod` 0
+
+gcd x y  =  (x `mod` y) `mod` x
+
+gcd x y  =  (x `mod` y) `mod` y
+
+gcd x y  =  (x `mod` y) `mod` 0
+
+gcd x y  =  (x `mod` 0) `mod` x
+
+gcd x y  =  (x `mod` 0) `mod` y
+
+gcd x y  =  (x `mod` 0) `mod` 0
+
+gcd x y  =  (y `mod` x) `mod` x
+
+gcd x y  =  (y `mod` x) `mod` y
+
+gcd x y  =  (y `mod` x) `mod` 0
+
+gcd x y  =  (y `mod` y) `mod` x
+
+gcd x y  =  (y `mod` y) `mod` y
+
+gcd x y  =  (y `mod` y) `mod` 0
+
+gcd x y  =  (y `mod` 0) `mod` x
+
+gcd x y  =  (y `mod` 0) `mod` y
+
+gcd x y  =  (y `mod` 0) `mod` 0
+
+gcd x y  =  (0 `mod` x) `mod` x
+
+gcd x y  =  (0 `mod` x) `mod` y
+
+gcd x y  =  (0 `mod` x) `mod` 0
+
+gcd x y  =  (0 `mod` y) `mod` x
+
+gcd x y  =  (0 `mod` y) `mod` y
+
+gcd x y  =  (0 `mod` y) `mod` 0
+
+gcd x y  =  (0 `mod` 0) `mod` x
+
+gcd x y  =  (0 `mod` 0) `mod` y
+
+gcd x y  =  (0 `mod` 0) `mod` 0
+
+gcd x y  =  x `mod` (x `mod` x)
+
+gcd x y  =  x `mod` (x `mod` y)
+
+gcd x y  =  x `mod` (x `mod` 0)
+
+gcd x y  =  x `mod` (y `mod` x)
+
+gcd x y  =  x `mod` (y `mod` y)
+
+gcd x y  =  x `mod` (y `mod` 0)
+
+gcd x y  =  x `mod` (0 `mod` x)
+
+gcd x y  =  x `mod` (0 `mod` y)
+
+gcd x y  =  x `mod` (0 `mod` 0)
+
+gcd x y  =  y `mod` (x `mod` x)
+
+gcd x y  =  y `mod` (x `mod` y)
+
+gcd x y  =  y `mod` (x `mod` 0)
+
+gcd x y  =  y `mod` (y `mod` x)
+
+gcd x y  =  y `mod` (y `mod` y)
+
+gcd x y  =  y `mod` (y `mod` 0)
+
+gcd x y  =  y `mod` (0 `mod` x)
+
+gcd x y  =  y `mod` (0 `mod` y)
+
+gcd x y  =  y `mod` (0 `mod` 0)
+
+gcd x y  =  0 `mod` (x `mod` x)
+
+gcd x y  =  0 `mod` (x `mod` y)
+
+gcd x y  =  0 `mod` (x `mod` 0)
+
+gcd x y  =  0 `mod` (y `mod` x)
+
+gcd x y  =  0 `mod` (y `mod` y)
+
+gcd x y  =  0 `mod` (y `mod` 0)
+
+gcd x y  =  0 `mod` (0 `mod` x)
+
+gcd x y  =  0 `mod` (0 `mod` y)
+
+gcd x y  =  0 `mod` (0 `mod` 0)
+
+
+pattern candidates:
+
+gcd x y  =  x
+
+gcd x y  =  y
+
+gcd x y  =  0
+
+gcd x 0  =  x
+gcd x y  =  y
+
+gcd x 0  =  x
+gcd x y  =  0
+
+gcd x 0  =  0
+gcd x y  =  x
+
+gcd 0 x  =  x
+gcd x y  =  x
+
+gcd 0 x  =  x
+gcd x y  =  0
+
+gcd 0 x  =  0
+gcd x y  =  y
+
+gcd x y  =  x `mod` x
+
+gcd x y  =  x `mod` y
+
+gcd x y  =  x `mod` 0
+
+gcd x y  =  y `mod` x
+
+gcd x y  =  y `mod` y
+
+gcd x y  =  y `mod` 0
+
+gcd x y  =  0 `mod` x
+
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  0
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  x
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  y
+
+gcd x 0  =  x
+gcd x y  =  x `mod` x
+
+gcd x 0  =  x
+gcd x y  =  x `mod` y
+
+gcd x 0  =  x
+gcd x y  =  x `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  y `mod` x
+
+gcd x 0  =  x
+gcd x y  =  y `mod` y
+
+gcd x 0  =  x
+gcd x y  =  y `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` x
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` y
+
+gcd x 0  =  0
+gcd x y  =  x `mod` x
+
+gcd x 0  =  0
+gcd x y  =  x `mod` y
+
+gcd x 0  =  0
+gcd x y  =  x `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  y `mod` x
+
+gcd x 0  =  0
+gcd x y  =  y `mod` y
+
+gcd x 0  =  0
+gcd x y  =  y `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` x
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` y
+
+gcd x 0  =  x `mod` x
+gcd x y  =  x
+
+gcd x 0  =  x `mod` x
+gcd x y  =  y
+
+gcd x 0  =  x `mod` x
+gcd x y  =  0
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  x
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  y
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  0
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  x
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  y
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  x
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  0
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  0
+
+gcd x y  =  (x `mod` x) `mod` x
+
+gcd x y  =  (x `mod` x) `mod` y
+
+gcd x y  =  (x `mod` x) `mod` 0
+
+gcd x y  =  (x `mod` y) `mod` x
+
+gcd x y  =  (x `mod` y) `mod` y
+
+gcd x y  =  (x `mod` y) `mod` 0
+
+gcd x y  =  (x `mod` 0) `mod` x
+
+gcd x y  =  (x `mod` 0) `mod` y
+
+gcd x y  =  (x `mod` 0) `mod` 0
+
+gcd x y  =  (y `mod` x) `mod` x
+
+gcd x y  =  (y `mod` x) `mod` y
+
+gcd x y  =  (y `mod` x) `mod` 0
+
+gcd x y  =  (y `mod` y) `mod` x
+
+gcd x y  =  (y `mod` y) `mod` y
+
+gcd x y  =  (y `mod` y) `mod` 0
+
+gcd x y  =  (y `mod` 0) `mod` x
+
+gcd x y  =  (y `mod` 0) `mod` y
+
+gcd x y  =  (y `mod` 0) `mod` 0
+
+gcd x y  =  (0 `mod` x) `mod` x
+
+gcd x y  =  (0 `mod` x) `mod` y
+
+gcd x y  =  (0 `mod` x) `mod` 0
+
+gcd x y  =  (0 `mod` y) `mod` x
+
+gcd x y  =  (0 `mod` y) `mod` y
+
+gcd x y  =  (0 `mod` y) `mod` 0
+
+gcd x y  =  x `mod` (x `mod` x)
+
+gcd x y  =  x `mod` (x `mod` y)
+
+gcd x y  =  x `mod` (x `mod` 0)
+
+gcd x y  =  x `mod` (y `mod` x)
+
+gcd x y  =  x `mod` (y `mod` y)
+
+gcd x y  =  x `mod` (y `mod` 0)
+
+gcd x y  =  x `mod` (0 `mod` x)
+
+gcd x y  =  x `mod` (0 `mod` y)
+
+gcd x y  =  y `mod` (x `mod` x)
+
+gcd x y  =  y `mod` (x `mod` y)
+
+gcd x y  =  y `mod` (x `mod` 0)
+
+gcd x y  =  y `mod` (y `mod` x)
+
+gcd x y  =  y `mod` (y `mod` y)
+
+gcd x y  =  y `mod` (y `mod` 0)
+
+gcd x y  =  y `mod` (0 `mod` x)
+
+gcd x y  =  y `mod` (0 `mod` y)
+
+gcd x y  =  0 `mod` (x `mod` x)
+
+gcd x y  =  0 `mod` (x `mod` y)
+
+gcd x y  =  0 `mod` (x `mod` 0)
+
+gcd x y  =  0 `mod` (y `mod` x)
+
+gcd x y  =  0 `mod` (y `mod` y)
+
+gcd x y  =  0 `mod` (y `mod` 0)
+
+gcd x y  =  0 `mod` (0 `mod` x)
+
+gcd x y  =  0 `mod` (0 `mod` y)
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  x
+gcd x 0  =  x
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  x
+gcd x 0  =  0
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  x
+gcd x 0  =  x `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  x
+gcd x 0  =  x `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  x
+gcd x 0  =  x `mod` 0
+gcd x y  =  x
+
+gcd 0 x  =  x
+gcd x 0  =  x `mod` 0
+gcd x y  =  0
+
+gcd 0 x  =  x
+gcd x 0  =  0 `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  x
+gcd x 0  =  0 `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  0
+gcd x 0  =  x
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  0
+gcd x 0  =  0
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  0
+gcd x 0  =  x `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  0
+gcd x 0  =  x `mod` 0
+gcd x y  =  y
+
+gcd 0 x  =  0
+gcd x 0  =  0 `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` x
+gcd x 0  =  x
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` x
+gcd x 0  =  x
+gcd x y  =  0
+
+gcd 0 x  =  x `mod` x
+gcd x 0  =  0
+gcd x y  =  x
+
+gcd 0 x  =  x `mod` 0
+gcd x 0  =  x
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` 0
+gcd x 0  =  x
+gcd x y  =  0
+
+gcd 0 x  =  x `mod` 0
+gcd x 0  =  0
+gcd x y  =  x
+
+gcd 0 x  =  0 `mod` x
+gcd x 0  =  x
+gcd x y  =  y
+
+gcd 0 x  =  0 `mod` x
+gcd x 0  =  x
+gcd x y  =  0
+
+gcd 0 x  =  0 `mod` x
+gcd x 0  =  0
+gcd x y  =  x
+
+gcd x 0  =  x
+gcd x y  =  gcd x (x `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd x (y `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd x (0 `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd y (x `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  gcd y (x `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd y (y `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  gcd y (y `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd y (0 `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  gcd y (0 `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd 0 (x `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd 0 (y `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd 0 (0 `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  gcd (x `mod` x) x
+
+gcd x 0  =  x
+gcd x y  =  gcd (x `mod` x) y
+
+gcd x 0  =  x
+gcd x y  =  gcd (x `mod` y) x
+
+gcd x 0  =  x
+gcd x y  =  gcd (y `mod` x) x
+
+gcd x 0  =  x
+gcd x y  =  gcd (y `mod` x) y
+
+gcd x 0  =  x
+gcd x y  =  gcd (y `mod` y) x
+
+gcd x 0  =  x
+gcd x y  =  gcd (0 `mod` x) x
+
+gcd x 0  =  x
+gcd x y  =  gcd (0 `mod` x) y
+
+gcd x 0  =  x
+gcd x y  =  gcd (0 `mod` y) x
+
+gcd 0 x  =  x
+gcd x y  =  gcd x (x `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  gcd x (y `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  gcd x (0 `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  gcd y (x `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  gcd y (x `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  gcd y (y `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  gcd y (y `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  gcd y (0 `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  gcd y (0 `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  gcd (x `mod` x) x
+
+gcd 0 x  =  x
+gcd x y  =  gcd (x `mod` x) y
+
+gcd 0 x  =  x
+gcd x y  =  gcd (x `mod` x) 0
+
+gcd 0 x  =  x
+gcd x y  =  gcd (x `mod` y) x
+
+gcd 0 x  =  x
+gcd x y  =  gcd (y `mod` x) x
+
+gcd 0 x  =  x
+gcd x y  =  gcd (y `mod` x) y
+
+gcd 0 x  =  x
+gcd x y  =  gcd (y `mod` x) 0
+
+gcd 0 x  =  x
+gcd x y  =  gcd (y `mod` y) x
+
+gcd 0 x  =  x
+gcd x y  =  gcd (0 `mod` x) x
+
+gcd 0 x  =  x
+gcd x y  =  gcd (0 `mod` x) y
+
+gcd 0 x  =  x
+gcd x y  =  gcd (0 `mod` x) 0
+
+gcd 0 x  =  x
+gcd x y  =  gcd (0 `mod` y) x
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` x) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` x) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` x) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` y) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` y) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` y) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` 0) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` 0) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (x `mod` 0) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` x) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` x) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` x) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` y) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` y) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` y) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` 0) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` 0) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (y `mod` 0) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (0 `mod` x) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (0 `mod` x) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (0 `mod` x) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  (0 `mod` y) `mod` x
+
+gcd x 0  =  x
+gcd x y  =  (0 `mod` y) `mod` y
+
+gcd x 0  =  x
+gcd x y  =  (0 `mod` y) `mod` 0
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (x `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (x `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (x `mod` 0)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (y `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (y `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (y `mod` 0)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (0 `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  x `mod` (0 `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (x `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (x `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (x `mod` 0)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (y `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (y `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (y `mod` 0)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (0 `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  y `mod` (0 `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (x `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (x `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (x `mod` 0)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (y `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (y `mod` y)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (y `mod` 0)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (0 `mod` x)
+
+gcd x 0  =  x
+gcd x y  =  0 `mod` (0 `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` x) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` x) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` x) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` y) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` y) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` y) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` 0) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` 0) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (x `mod` 0) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` x) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` x) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` x) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` y) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` y) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` y) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` 0) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` 0) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (y `mod` 0) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (0 `mod` x) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (0 `mod` x) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (0 `mod` x) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  (0 `mod` y) `mod` x
+
+gcd x 0  =  0
+gcd x y  =  (0 `mod` y) `mod` y
+
+gcd x 0  =  0
+gcd x y  =  (0 `mod` y) `mod` 0
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (x `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (x `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (x `mod` 0)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (y `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (y `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (y `mod` 0)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (0 `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  x `mod` (0 `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (x `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (x `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (x `mod` 0)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (y `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (y `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (y `mod` 0)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (0 `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  y `mod` (0 `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (x `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (x `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (x `mod` 0)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (y `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (y `mod` y)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (y `mod` 0)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (0 `mod` x)
+
+gcd x 0  =  0
+gcd x y  =  0 `mod` (0 `mod` y)
+
+gcd x 0  =  x `mod` x
+gcd x y  =  x `mod` y
+
+gcd x 0  =  x `mod` x
+gcd x y  =  x `mod` 0
+
+gcd x 0  =  x `mod` x
+gcd x y  =  y `mod` x
+
+gcd x 0  =  x `mod` x
+gcd x y  =  y `mod` y
+
+gcd x 0  =  x `mod` x
+gcd x y  =  y `mod` 0
+
+gcd x 0  =  x `mod` x
+gcd x y  =  0 `mod` x
+
+gcd x 0  =  x `mod` x
+gcd x y  =  0 `mod` y
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  x `mod` x
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  y `mod` x
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  y `mod` y
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  y `mod` 0
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  0 `mod` x
+
+gcd x 0  =  x `mod` 0
+gcd x y  =  0 `mod` y
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  x `mod` x
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  x `mod` y
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  x `mod` 0
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  y `mod` y
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  y `mod` 0
+
+gcd x 0  =  0 `mod` x
+gcd x y  =  0 `mod` y
+
+gcd x 0  =  (x `mod` x) `mod` x
+gcd x y  =  x
+
+gcd x 0  =  (x `mod` x) `mod` x
+gcd x y  =  y
+
+gcd x 0  =  (x `mod` x) `mod` x
+gcd x y  =  0
+
+gcd x 0  =  (x `mod` x) `mod` 0
+gcd x y  =  x
+
+gcd x 0  =  (x `mod` x) `mod` 0
+gcd x y  =  y
+
+gcd x 0  =  (x `mod` x) `mod` 0
+gcd x y  =  0
+
+gcd x 0  =  (x `mod` 0) `mod` x
+gcd x y  =  x
+
+gcd x 0  =  (x `mod` 0) `mod` x
+gcd x y  =  y
+
+gcd x 0  =  (x `mod` 0) `mod` x
+gcd x y  =  0
+
+gcd x 0  =  (x `mod` 0) `mod` 0
+gcd x y  =  x
+
+gcd x 0  =  (x `mod` 0) `mod` 0
+gcd x y  =  y
+
+gcd x 0  =  (x `mod` 0) `mod` 0
+gcd x y  =  0
+
+gcd x 0  =  (0 `mod` x) `mod` x
+gcd x y  =  x
+
+gcd x 0  =  (0 `mod` x) `mod` x
+gcd x y  =  y
+
+gcd x 0  =  (0 `mod` x) `mod` x
+gcd x y  =  0
+
+gcd x 0  =  (0 `mod` x) `mod` 0
+gcd x y  =  x
+
+gcd x 0  =  (0 `mod` x) `mod` 0
+gcd x y  =  y
+
+gcd x 0  =  (0 `mod` x) `mod` 0
+gcd x y  =  0
+
+gcd x 0  =  x `mod` (x `mod` x)
+gcd x y  =  x
+
+gcd x 0  =  x `mod` (x `mod` x)
+gcd x y  =  y
+
+gcd x 0  =  x `mod` (x `mod` x)
+gcd x y  =  0
+
+gcd x 0  =  x `mod` (x `mod` 0)
+gcd x y  =  x
+
+gcd x 0  =  x `mod` (x `mod` 0)
+gcd x y  =  y
+
+gcd x 0  =  x `mod` (x `mod` 0)
+gcd x y  =  0
+
+gcd x 0  =  x `mod` (0 `mod` x)
+gcd x y  =  x
+
+gcd x 0  =  x `mod` (0 `mod` x)
+gcd x y  =  y
+
+gcd x 0  =  x `mod` (0 `mod` x)
+gcd x y  =  0
+
+gcd x 0  =  0 `mod` (x `mod` x)
+gcd x y  =  x
+
+gcd x 0  =  0 `mod` (x `mod` x)
+gcd x y  =  y
+
+gcd x 0  =  0 `mod` (x `mod` x)
+gcd x y  =  0
+
+gcd x 0  =  0 `mod` (x `mod` 0)
+gcd x y  =  x
+
+gcd x 0  =  0 `mod` (x `mod` 0)
+gcd x y  =  y
+
+gcd x 0  =  0 `mod` (x `mod` 0)
+gcd x y  =  0
+
+gcd x 0  =  0 `mod` (0 `mod` x)
+gcd x y  =  x
+
+gcd x 0  =  0 `mod` (0 `mod` x)
+gcd x y  =  y
+
+gcd x 0  =  0 `mod` (0 `mod` x)
+gcd x y  =  0
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` x) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` x) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` x) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` y) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` y) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` y) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` 0) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` 0) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (x `mod` 0) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` x) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` x) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` x) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` y) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` y) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` y) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` 0) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` 0) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (y `mod` 0) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (0 `mod` x) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (0 `mod` x) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (0 `mod` x) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  (0 `mod` y) `mod` x
+
+gcd 0 x  =  x
+gcd x y  =  (0 `mod` y) `mod` y
+
+gcd 0 x  =  x
+gcd x y  =  (0 `mod` y) `mod` 0
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (x `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (x `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (x `mod` 0)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (y `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (y `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (y `mod` 0)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (0 `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  x `mod` (0 `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (x `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (x `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (x `mod` 0)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (y `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (y `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (y `mod` 0)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (0 `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  y `mod` (0 `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (x `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (x `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (x `mod` 0)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (y `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (y `mod` y)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (y `mod` 0)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (0 `mod` x)
+
+gcd 0 x  =  x
+gcd x y  =  0 `mod` (0 `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` x) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` x) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` x) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` y) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` y) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` y) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` 0) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` 0) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (x `mod` 0) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` x) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` x) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` x) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` y) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` y) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` y) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` 0) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` 0) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (y `mod` 0) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (0 `mod` x) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (0 `mod` x) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (0 `mod` x) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  (0 `mod` y) `mod` x
+
+gcd 0 x  =  0
+gcd x y  =  (0 `mod` y) `mod` y
+
+gcd 0 x  =  0
+gcd x y  =  (0 `mod` y) `mod` 0
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (x `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (x `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (x `mod` 0)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (y `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (y `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (y `mod` 0)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (0 `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  x `mod` (0 `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (x `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (x `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (x `mod` 0)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (y `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (y `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (y `mod` 0)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (0 `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  y `mod` (0 `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (x `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (x `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (x `mod` 0)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (y `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (y `mod` y)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (y `mod` 0)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (0 `mod` x)
+
+gcd 0 x  =  0
+gcd x y  =  0 `mod` (0 `mod` y)
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  x `mod` x
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  x `mod` y
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  x `mod` 0
+gcd x y  =  0 `mod` y
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  x `mod` x
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  x `mod` 0
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  y `mod` x
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  y `mod` y
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  y `mod` 0
+
+gcd 0 x  =  0 `mod` x
+gcd x y  =  0 `mod` x
+
+gcd 0 x  =  (x `mod` x) `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  (x `mod` x) `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  (x `mod` x) `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  (x `mod` x) `mod` 0
+gcd x y  =  x
+
+gcd 0 x  =  (x `mod` x) `mod` 0
+gcd x y  =  y
+
+gcd 0 x  =  (x `mod` x) `mod` 0
+gcd x y  =  0
+
+gcd 0 x  =  (x `mod` 0) `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  (x `mod` 0) `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  (x `mod` 0) `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  (x `mod` 0) `mod` 0
+gcd x y  =  x
+
+gcd 0 x  =  (x `mod` 0) `mod` 0
+gcd x y  =  y
+
+gcd 0 x  =  (x `mod` 0) `mod` 0
+gcd x y  =  0
+
+gcd 0 x  =  (0 `mod` x) `mod` x
+gcd x y  =  x
+
+gcd 0 x  =  (0 `mod` x) `mod` x
+gcd x y  =  y
+
+gcd 0 x  =  (0 `mod` x) `mod` x
+gcd x y  =  0
+
+gcd 0 x  =  (0 `mod` x) `mod` 0
+gcd x y  =  x
+
+gcd 0 x  =  (0 `mod` x) `mod` 0
+gcd x y  =  y
+
+gcd 0 x  =  (0 `mod` x) `mod` 0
+gcd x y  =  0
+
+gcd 0 x  =  x `mod` (x `mod` x)
+gcd x y  =  x
+
+gcd 0 x  =  x `mod` (x `mod` x)
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` (x `mod` x)
+gcd x y  =  0
+
+gcd 0 x  =  x `mod` (x `mod` 0)
+gcd x y  =  x
+
+gcd 0 x  =  x `mod` (x `mod` 0)
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` (x `mod` 0)
+gcd x y  =  0
+
+gcd 0 x  =  x `mod` (0 `mod` x)
+gcd x y  =  x
+
+gcd 0 x  =  x `mod` (0 `mod` x)
+gcd x y  =  y
+
+gcd 0 x  =  x `mod` (0 `mod` x)
+gcd x y  =  0
+
+gcd 0 x  =  0 `mod` (x `mod` x)
+gcd x y  =  x
+
+gcd 0 x  =  0 `mod` (x `mod` x)
+gcd x y  =  y
+
+gcd 0 x  =  0 `mod` (x `mod` x)
+gcd x y  =  0
+
+gcd 0 x  =  0 `mod` (x `mod` 0)
+gcd x y  =  x
+
+gcd 0 x  =  0 `mod` (x `mod` 0)
+gcd x y  =  y
+
+gcd 0 x  =  0 `mod` (x `mod` 0)
+gcd x y  =  0
+
+gcd 0 x  =  0 `mod` (0 `mod` x)
+gcd x y  =  x
+
+gcd 0 x  =  0 `mod` (0 `mod` x)
+gcd x y  =  y
+
+gcd 0 x  =  0 `mod` (0 `mod` x)
+gcd x y  =  0
+
+
diff --git a/bench/erroneous.hs b/bench/erroneous.hs
new file mode 100644
--- /dev/null
+++ b/bench/erroneous.hs
@@ -0,0 +1,101 @@
+-- Print erroneous candidates
+--
+-- Copyright (C) 2024 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+
+-- This script needs some internal utilities of Conjure:
+import Conjure.Engine
+import Conjure.Defn
+import Conjure.Defn.Redundancy
+import Conjure.Defn.Test
+import Conjure.Utils
+import Test.LeanCheck.Tiers (discardT)
+
+
+-- | This function prints erroneous candidates,
+--   i.e.: candidates that yield errors or loop indefinitely
+--         even if for just a single combination of argument values.
+--
+-- The arguments are, in their respective order:
+--
+-- * maximum candidate size (5 = few seconds, 7 = few minutes);
+-- * function name (for pretty-printing purposes);
+-- * proxy value to indicate the type of functions to generate;
+-- * list of primitives, in Conjure-compatible form.
+printErroneousCandidates :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()
+printErroneousCandidates n nm f ps  =  do
+  putStrLn $ "Erroneous candidates for: " ++ nm ++ " :: " ++ show (typeOf f)
+  putStrLn $ "  pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"
+  putStrLn $ "  " ++ show (map length css) ++ " candidates"
+  putStrLn $ "  " ++ show numErroneous ++ "/" ++ show numCandidates ++ " erroneous candidates"
+  putStrLn ""
+--printThy thy
+  putStrLn $ unlines . map showDefnWithError $ erroneous
+  where
+  numCandidates  =  length candidates
+  numErroneous   =  length erroneous
+  erroneous      =  [(c, e) | c <- candidates, Just e <- [findError c]]
+  candidates     =  concat css
+  css            =  take n
+                 .  discardT isRedundantByIntroduction -- additional pruning rule
+                 $  css'
+  (css', thy)    =  candidateDefnsC args nm f ps  -- Conjure uses this for listing candidates
+  nRules         =  length (rules thy)
+  nREs           =  length (equations thy) + nRules
+  maxTests       =  60 -- a hardcoded value probably will not hurt in this simple benchmark
+  maxEvalRecursions  =  60
+  findError      =  findDefnError maxTests maxEvalRecursions nm f
+  showDefnWithError (d,e)  =  showDefn d
+                           ++ "-- " ++ showExpr e ++ "  =  bottom\n"
+
+
+main :: IO ()
+main  =  do
+
+  -- This N value limits the maximum size of candidates,
+  -- increase it to print erroneous candidates of bigger size.
+  let n = 7
+
+  printErroneousCandidates n "foo" (undefined :: Int -> Int)
+    [ pr (0 :: Int)
+    , pr (1 :: Int)
+    , prim "+" ((+) :: Int -> Int -> Int)
+    , prim "*" ((+) :: Int -> Int -> Int)
+    , prim "-" ((-) :: Int -> Int -> Int)
+    ]
+
+  printErroneousCandidates n "?" (undefined :: Int -> Int -> Int)
+    [ pr (0 :: Int)
+    , prim "+" ((+) :: Int -> Int -> Int)
+    , prim "*" ((+) :: Int -> Int -> Int)
+    , prim "dec" (subtract 1 :: Int -> Int)
+    ]
+
+  printErroneousCandidates n "goo" (undefined :: [Int] -> [Int])
+    [ pr ([] :: [Int])
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "++" ((++) :: [Int] -> [Int] -> [Int])
+    ]
+
+  printErroneousCandidates n "??" (undefined :: [Int] -> [Int] -> [Int])
+    [ pr ([] :: [Int])
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "++" ((++) :: [Int] -> [Int] -> [Int])
+    ]
+
+  printErroneousCandidates n "ton" (undefined :: Bool -> Bool)
+    [ pr False
+    , pr True
+    , prim "&&" (&&)
+    , prim "||" (||)
+    , prim "not" not
+    ]
+
+  printErroneousCandidates n "&|" (undefined :: Bool -> Bool -> Bool)
+    [ pr False
+    , pr True
+    , prim "&&" (&&)
+    , prim "||" (||)
+    , prim "not" not
+    ]
diff --git a/bench/erroneous.txt b/bench/erroneous.txt
new file mode 100644
--- /dev/null
+++ b/bench/erroneous.txt
@@ -0,0 +1,643 @@
+Erroneous candidates for: foo :: Int -> Int
+  pruning with 15/35 rules
+  [3,3,8,9,21,27,98] candidates
+  0/169 erroneous candidates
+
+
+Erroneous candidates for: ? :: Int -> Int -> Int
+  pruning with 10/23 rules
+  [3,8,22,50,116,302,765] candidates
+  147/1266 erroneous candidates
+
+x ? 0  =  x
+x ? y  =  dec x ? y
+-- 0 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  x ? dec y
+-- 1 ? 0  =  bottom
+
+x ? 0  =  x
+x ? y  =  x ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  y ? dec (dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  y ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  0 ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec x ? dec x
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec y ? dec x
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec x) ? x
+-- 1 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec x) ? y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec y) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  x ? dec (dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  y ? dec (dec x)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  y ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec y ? dec x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec y ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? 0
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec y) ? x
+-- 1 ? 0  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec x ? y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec x ? y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec x ? y
+-- 0 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (x ? dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (x ? dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  x ? dec y
+-- 1 ? 0  =  bottom
+
+x ? 0  =  x
+x ? y  =  x ? dec (dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  y ? dec (dec (dec x))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  y ? dec (dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  0 ? dec (dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec x ? (x + y)
+-- 1 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec x ? (y + y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec x ? dec (dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec x ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec y ? dec (dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec y ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec x) ? dec x
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec y) ? dec x
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec x)) ? x
+-- 1 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec x)) ? y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec y)) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  x ? dec (dec (dec y))
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  y ? dec (dec (dec x))
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  y ? dec (dec (dec y))
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec y ? dec (dec x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec y ? dec (dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  (x + x) ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  (x + y) ? dec y
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? dec x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec x) ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec y) ? dec x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec y) ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x)) ? x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x)) ? y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x)) ? 0
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec y)) ? x
+-- 1 ? 0  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (x ? dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (y ? dec (dec x))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (y ? dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (0 ? dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec x ? dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec y ? dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec x) ? x)
+-- 1 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec x) ? y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec y) ? x)
+-- 1 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (x ? dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (y ? dec (dec x))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (y ? dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (0 ? dec (dec y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec x ? dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec y ? dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec x) ? x)
+-- 1 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec x) ? y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec y) ? x)
+-- 1 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  x ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  y ? dec (dec x)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  y ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  0 ? dec (dec y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec x ? dec x
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec y ? dec x
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec (dec x) ? x
+-- 1 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec (dec x) ? y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec (dec y) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (x ? dec (dec y))
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (y ? dec (dec x))
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (y ? dec (dec y))
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec y ? dec x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec y ? dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x) ? x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x) ? y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec x) ? 0)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (dec y) ? x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (x ? dec (dec y))
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (y ? dec (dec x))
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (y ? dec (dec y))
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec y ? dec x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec y ? dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec x) ? x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec x) ? y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec x) ? 0)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec (dec y) ? x)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  x ? dec (dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  y ? dec (dec x)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  y ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec y ? dec x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec y ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec (dec x) ? x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec (dec x) ? y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec (dec x) ? 0
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec (dec y) ? x
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y ? dec (dec x)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec x) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec x) ? y
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec (dec y) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y ? dec (dec x)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec x) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec x) ? y
+-- 1 ? 1  =  bottom
+
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec (dec y) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y ? dec (dec x)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y ? dec (dec y)
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec x) ? x
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec x) ? y
+-- 1 ? 1  =  bottom
+
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec (dec y) ? x
+-- 1 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  x + dec x ? y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec x ? y + y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x
+x ? y  =  dec (dec (dec x ? y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  x + dec x ? y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec x ? y + y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  0
+x ? y  =  dec (dec (dec x ? y))
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec x
+x ? y  =  dec (dec x ? y)
+-- 0 ? 1  =  bottom
+
+x ? 0  =  x + x
+x ? y  =  dec x ? y
+-- 0 ? 1  =  bottom
+
+x ? 0  =  dec (dec x)
+x ? y  =  dec x ? y
+-- 0 ? 1  =  bottom
+
+0 ? x  =  x
+x ? y  =  x + x ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  x ? dec y + y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x
+x ? y  =  dec (dec (x ? dec y))
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  x + x ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  x ? dec y + y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  0
+x ? y  =  dec (dec (x ? dec y))
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec x
+x ? y  =  dec (x ? dec y)
+-- 1 ? 0  =  bottom
+
+0 ? x  =  x + x
+x ? y  =  x ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? x  =  dec (dec x)
+x ? y  =  x ? dec y
+-- 1 ? 0  =  bottom
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? y  =  x ? dec y
+-- 1 ? 0  =  bottom
+
+
+Erroneous candidates for: goo :: [Int] -> [Int]
+  pruning with 4/4 rules
+  [2,1,1,2,4,7,10] candidates
+  0/27 erroneous candidates
+
+
+Erroneous candidates for: ?? :: [Int] -> [Int] -> [Int]
+  pruning with 4/4 rules
+  [3,8,15,43,122,264,830] candidates
+  0/1285 erroneous candidates
+
+
+Erroneous candidates for: ton :: Bool -> Bool
+  pruning with 39/49 rules
+  [3,2,0,0,0,0,0] candidates
+  0/5 erroneous candidates
+
+
+Erroneous candidates for: &| :: Bool -> Bool -> Bool
+  pruning with 39/49 rules
+  [4,12,20,6,2,16,18] candidates
+  0/78 erroneous candidates
+
+
diff --git a/bench/gps.hs b/bench/gps.hs
--- a/bench/gps.hs
+++ b/bench/gps.hs
@@ -1,6 +1,6 @@
 -- gps.hs: General Program Synthesis Benchmark Suite
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE CPP #-}
 import Conjure
diff --git a/bench/gps.out b/bench/gps.out
deleted file mode 100644
--- a/bench/gps.out
+++ /dev/null
@@ -1,539 +0,0 @@
-gps1 :: Int -> Float -> Float
--- testing 4 combinations of argument values
--- pruning with 0/5 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 1 candidates of size 4
--- tested 4 candidates
-gps1 x y  =  y + fromIntegral x
-
-gps2 :: Int -> Maybe [Char]
--- testing 6 combinations of argument values
--- pruning with 9/17 rules
--- looking through 1 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 32 candidates of size 7
--- looking through 48 candidates of size 8
--- looking through 48 candidates of size 9
--- looking through 48 candidates of size 10
--- looking through 16 candidates of size 11
--- looking through 512 candidates of size 12
--- looking through 1792 candidates of size 13
--- tested 1203 candidates
-gps2 x  =  if 2000 <= x
-           then Just "large"
-           else if x < 1000 then Just "small" else Nothing
-
-gps3 :: Int -> Int -> Int -> [Int]
--- testing 2 combinations of argument values
--- pruning with 11/33 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 64 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 1248 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 18627 candidates of size 8
--- tested 12358 candidates
-gps3 x y z  =  enumFromThenTo x (x + z) (y - 1)
-
-gps3 :: Int -> Int -> Int -> [Int]
--- testing 2 combinations of argument values
--- pruning with 6/18 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 15 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 81 candidates of size 7
--- looking through 36 candidates of size 8
--- tested 136 candidates
-cannot conjure
-
-gps4 :: [Char] -> [Char] -> [Char] -> Bool
--- testing 9 combinations of argument values
--- pruning with 11/15 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 6 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 0 candidates of size 8
--- looking through 162 candidates of size 9
--- looking through 26 candidates of size 10
--- looking through 15 candidates of size 11
--- tested 197 candidates
-gps4 cs ds es  =  length cs < length ds && length ds < length es
-
-gps5 :: [Char] -> [Char]
--- testing 5 combinations of argument values
--- pruning with 2/3 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 13 candidates of size 6
--- tested 30 candidates
-cannot conjure
-
-gps6 :: Int -> Int
--- testing 9 combinations of argument values
--- pruning with 16/18 rules
--- looking through 4 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 14 candidates of size 3
--- looking through 17 candidates of size 4
--- looking through 188 candidates of size 5
--- looking through 200 candidates of size 6
--- tested 425 candidates
-cannot conjure
-
-gps7 :: [Char] -> ([Char],Int)
--- testing 4 combinations of argument values
--- pruning with 5/10 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 7 candidates of size 6
--- looking through 16 candidates of size 7
--- looking through 39 candidates of size 8
--- looking through 88 candidates of size 9
--- looking through 201 candidates of size 10
--- looking through 442 candidates of size 11
--- tested 546 candidates
-gps7 cs  =  (init (unlines (words cs)),length (filter (not . isSpace) cs))
-
-gps8 :: [Char] -> [Char] -> [(Int,Char,Char)]
--- testing 3 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- tested 0 candidates
-cannot conjure
-
-gps9 :: Int -> [Int]
--- testing 3 combinations of argument values
--- pruning with 13/14 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 21 candidates of size 6
--- looking through 34 candidates of size 7
--- looking through 83 candidates of size 8
--- looking through 143 candidates of size 9
--- looking through 256 candidates of size 10
--- tested 325 candidates
-gps9 x  =  filter even (filter (x >) (map sq [1..x]))
-
-wallisNext :: Ratio Integer -> Ratio Integer
--- testing 6 combinations of argument values
--- pruning with 37/64 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 15 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 86 candidates of size 6
--- looking through 5 candidates of size 7
--- looking through 537 candidates of size 8
--- tested 588 candidates
-wallisNext (x % y)  =  (y + 1) % (x + 1)
-
-wallisNext :: Ratio Integer -> Ratio Integer
--- testing 6 combinations of argument values
--- pruning with 15/26 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 16 candidates of size 4
--- looking through 3 candidates of size 5
--- looking through 71 candidates of size 6
--- looking through 5 candidates of size 7
--- looking through 393 candidates of size 8
--- tested 451 candidates
-wallisNext (x % y)  =  (y + 1) % (x + 1)
-
-gps10 :: Int -> Ratio Integer
--- testing 6 combinations of argument values
--- pruning with 3/4 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 8 candidates of size 7
--- looking through 13 candidates of size 8
--- tested 33 candidates
-gps10 x  =  product (take x (iterate wallisNext (2 % 3)))
-
-gps11 :: [[Char]] -> [Int]
--- testing 4 combinations of argument values
--- pruning with 1/1 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 1 candidates of size 4
--- tested 2 candidates
-gps11 css  =  reverse (map length css)
-
-gps11 :: [[Char]] -> [Int]
--- testing 4 combinations of argument values
--- pruning with 4/4 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 1 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 2 candidates of size 8
--- tested 6 candidates
-gps11 []  =  []
-gps11 (cs:css)  =  gps11 css ++ [length cs]
-
-gps12 :: [Int] -> Int
--- testing 6 combinations of argument values
--- pruning with 13/27 rules
--- looking through 2 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 11 candidates of size 4
--- looking through 22 candidates of size 5
--- looking through 51 candidates of size 6
--- looking through 133 candidates of size 7
--- looking through 318 candidates of size 8
--- looking through 938 candidates of size 9
--- looking through 2418 candidates of size 10
--- looking through 7229 candidates of size 11
--- tested 8246 candidates
-gps12 xs  =  (length xs - fromJust (findIndex (0 ==) (reverse xs))) - 1
-
-gps13 :: [Ratio Integer] -> Ratio Integer
--- testing 3 combinations of argument values
--- pruning with 4/8 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 10 candidates of size 4
--- looking through 14 candidates of size 5
--- looking through 51 candidates of size 6
--- looking through 105 candidates of size 7
--- looking through 365 candidates of size 8
--- tested 271 candidates
-gps13 qs  =  foldr (+) 0 qs / fromIntegral (length qs)
-
-odd :: Int -> Bool
--- testing 6 combinations of argument values
--- pruning with 12/13 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 44 candidates of size 5
--- tested 25 candidates
-odd x  =  0 /= x `mod` 2
-
-gps14 :: [Int] -> Int
--- testing 3 combinations of argument values
--- pruning with 1/1 rules
--- looking through 0 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- tested 2 candidates
-gps14 xs  =  length (filter odd xs)
-
-gps14 :: [Int] -> Int
--- testing 3 combinations of argument values
--- pruning with 39/58 rules
--- looking through 3 candidates of size 1
--- looking through 9 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 27 candidates of size 4
--- looking through 30 candidates of size 5
--- looking through 258 candidates of size 6
--- looking through 474 candidates of size 7
--- tested 381 candidates
-gps14 []  =  0
-gps14 (x:xs)  =  x + gps14 xs `mod` 2
-
-gps15 :: [Int] -> [Int] -> Bool
--- testing 5 combinations of argument values
--- pruning with 3/7 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 4 candidates of size 4
--- tested 3 candidates
-gps15 xs ys  =  xs == reverse ys
-
-gps16 :: [Char] -> [Char] -> Bool
--- testing 6 combinations of argument values
--- pruning with 3/3 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 2 candidates of size 5
--- tested 9 candidates
-gps16 cs ds  =  sort cs `isSubsequenceOf` sort ds
-
-gps17 :: Int -> Int
--- testing 4 combinations of argument values
--- pruning with 27/65 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 7 candidates of size 3
--- looking through 13 candidates of size 4
--- looking through 35 candidates of size 5
--- looking through 61 candidates of size 6
--- looking through 219 candidates of size 7
--- looking through 354 candidates of size 8
--- looking through 1431 candidates of size 9
--- tested 729 candidates
-gps17 0  =  0
-gps17 x  =  gps17 (x - 1) + x * x
-
-gps18 :: [Int] -> [Int] -> [Int]
--- testing 3 combinations of argument values
--- pruning with 2/6 rules
--- looking through 3 candidates of size 1
--- looking through 7 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 37 candidates of size 4
--- looking through 98 candidates of size 5
--- looking through 106 candidates of size 6
--- looking through 440 candidates of size 7
--- looking through 428 candidates of size 8
--- looking through 1950 candidates of size 9
--- tested 2031 candidates
-gps18 [] xs  =  xs
-gps18 (x:xs) []  =  xs
-gps18 (x:xs) (y:ys)  =  x + y:gps18 xs ys
-
-gps18 :: [Int] -> [Int] -> [Int]
--- testing 3 combinations of argument values
--- pruning with 2/7 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 11 candidates of size 4
--- tested 14 candidates
-gps18 xs ys  =  zipWith (+) xs ys
-
-gps19 :: Int -> [Char] -> [Char]
--- testing 2 combinations of argument values
--- pruning with 0/0 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 1 candidates
-cannot conjure
-
-isVowel :: Char -> Bool
--- testing 12 combinations of argument values
--- pruning with 0/0 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 3 candidates of size 6
--- looking through 4 candidates of size 7
--- looking through 4 candidates of size 8
--- looking through 4 candidates of size 9
--- looking through 5 candidates of size 10
--- looking through 5 candidates of size 11
--- looking through 5 candidates of size 12
--- looking through 5 candidates of size 13
--- looking through 4 candidates of size 14
--- looking through 4 candidates of size 15
--- looking through 4 candidates of size 16
--- looking through 3 candidates of size 17
--- looking through 2 candidates of size 18
--- looking through 2 candidates of size 19
--- looking through 1 candidates of size 20
--- looking through 1 candidates of size 21
--- looking through 1 candidates of size 22
--- tested 65 candidates
-isVowel 'a'  =  True
-isVowel 'e'  =  True
-isVowel 'i'  =  True
-isVowel 'o'  =  True
-isVowel 'u'  =  True
-isVowel 'y'  =  True
-isVowel c  =  False
-
-pig1 :: [Char] -> [Char]
--- pruning with 5/5 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 14 candidates of size 5
--- looking through 28 candidates of size 6
--- looking through 47 candidates of size 7
--- looking through 126 candidates of size 8
--- looking through 201 candidates of size 9
--- looking through 631 candidates of size 10
--- looking through 1069 candidates of size 11
--- looking through 3495 candidates of size 12
--- looking through 6382 candidates of size 13
--- looking through 20409 candidates of size 14
--- tested 27901 candidates
-pig1 ""  =  "ay"
-pig1 (c:cs)  =  if isVowel c
-                then (c:cs) ++ "ay"
-                else cs ++ (c:"ay")
-
-gps20c :: [Char] -> [Char]
--- pruning with 1/1 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 5 candidates of size 5
--- tested 12 candidates
-gps20c cs  =  unwords (map pig1 (words cs))
-
-gps21 :: [Int] -> [Int]
--- testing 4 combinations of argument values
--- pruning with 4/4 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 13 candidates of size 6
--- looking through 9 candidates of size 7
--- looking through 30 candidates of size 8
--- looking through 25 candidates of size 9
--- looking through 65 candidates of size 10
--- tested 96 candidates
-gps21 []  =  []
-gps21 (x:xs)  =  (if x < 0 then 0 else x):gps21 xs
-
-gps22 :: [Char] -> Int
--- pruning with 5/9 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 3 candidates of size 6
--- tested 5 candidates
-gps22 ""  =  0
-gps22 (c:cs)  =  gps22 cs + scrabble1 c
-
-gps23 :: [Char] -> ([(Int,Int)],Int,Double)
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 0 candidates
-cannot conjure
-
-gps24 :: [Char] -> Char
--- testing 4 combinations of argument values
--- pruning with 15/19 rules
--- looking through 1 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 8 candidates of size 5
--- looking through 15 candidates of size 6
--- looking through 31 candidates of size 7
--- looking through 77 candidates of size 8
--- looking through 203 candidates of size 9
--- looking through 487 candidates of size 10
--- tested 485 candidates
-gps24 cs  =  chr (ord ' ' + sum (map ord cs) `mod` 64)
-
-gps25 :: Int -> [Int]
--- testing 4 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- tested 0 candidates
-cannot conjure
-
-gps26 :: Int -> Int -> Int -> Int -> Int -> Char
--- testing 5 combinations of argument values
--- pruning with 4/4 rules
--- looking through 5 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 5 candidates
-cannot conjure
-
-gps27 :: Int -> Int -> Int -> Int
--- testing 3 combinations of argument values
--- pruning with 14/18 rules
--- looking through 3 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 36 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 0 candidates of size 8
--- looking through 0 candidates of size 9
--- looking through 90 candidates of size 10
--- looking through 2592 candidates of size 11
--- tested 1489 candidates
-gps27 x y z  =  if x < y
-                then if y < z then y else z
-                else x
-
-gps27b :: Int -> Int -> Int -> Int
--- testing 3 combinations of argument values
--- pruning with 20/30 rules
--- looking through 3 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 12 candidates of size 5
--- tested 15 candidates
-gps27b x y z  =  min z (max x y)
-
-gps28 :: Int -> Int -> Int -> Int -> Int
--- testing 5 combinations of argument values
--- pruning with 6/10 rules
--- looking through 4 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 12 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 36 candidates of size 7
--- tested 25 candidates
-gps28 x y z x'  =  x `min` (y `min` (z `min` x'))
-
-gps29 :: [Char] -> Int
--- pruning with 7/11 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 6 candidates of size 6
--- looking through 10 candidates of size 7
--- looking through 10 candidates of size 8
--- looking through 24 candidates of size 9
--- tested 40 candidates
-gps29 ""  =  0
-gps29 (c:cs)  =  gps29 cs + (if isVowel c then 1 else 0)
-
diff --git a/bench/gps.txt b/bench/gps.txt
new file mode 100644
--- /dev/null
+++ b/bench/gps.txt
@@ -0,0 +1,539 @@
+gps1 :: Int -> Float -> Float
+-- testing 4 combinations of argument values
+-- pruning with 0/5 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- tested 4 candidates
+gps1 x y  =  y + fromIntegral x
+
+gps2 :: Int -> Maybe [Char]
+-- testing 6 combinations of argument values
+-- pruning with 9/17 rules
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 32 candidates of size 7
+-- looking through 32 candidates of size 8
+-- looking through 48 candidates of size 9
+-- looking through 32 candidates of size 10
+-- looking through 16 candidates of size 11
+-- looking through 512 candidates of size 12
+-- looking through 1408 candidates of size 13
+-- tested 1171 candidates
+gps2 x  =  if 2000 <= x
+           then Just "large"
+           else if x < 1000 then Just "small" else Nothing
+
+gps3 :: Int -> Int -> Int -> [Int]
+-- testing 2 combinations of argument values
+-- pruning with 11/33 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 64 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 1248 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 18672 candidates of size 8
+-- tested 12358 candidates
+gps3 x y z  =  enumFromThenTo x (x + z) (y - 1)
+
+gps3 :: Int -> Int -> Int -> [Int]
+-- testing 2 combinations of argument values
+-- pruning with 6/18 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 15 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 81 candidates of size 7
+-- looking through 36 candidates of size 8
+-- tested 136 candidates
+cannot conjure
+
+gps4 :: [Char] -> [Char] -> [Char] -> Bool
+-- testing 9 combinations of argument values
+-- pruning with 11/15 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 6 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 0 candidates of size 8
+-- looking through 102 candidates of size 9
+-- looking through 30 candidates of size 10
+-- looking through 15 candidates of size 11
+-- tested 141 candidates
+gps4 cs ds es  =  length cs < length ds && length ds < length es
+
+gps5 :: [Char] -> [Char]
+-- testing 5 combinations of argument values
+-- pruning with 2/3 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 13 candidates of size 6
+-- tested 28 candidates
+cannot conjure
+
+gps6 :: Int -> Int
+-- testing 9 combinations of argument values
+-- pruning with 16/18 rules
+-- looking through 4 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 14 candidates of size 3
+-- looking through 14 candidates of size 4
+-- looking through 186 candidates of size 5
+-- looking through 165 candidates of size 6
+-- tested 385 candidates
+cannot conjure
+
+gps7 :: [Char] -> ([Char],Int)
+-- testing 4 combinations of argument values
+-- pruning with 5/10 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 7 candidates of size 6
+-- looking through 16 candidates of size 7
+-- looking through 39 candidates of size 8
+-- looking through 88 candidates of size 9
+-- looking through 201 candidates of size 10
+-- looking through 442 candidates of size 11
+-- tested 546 candidates
+gps7 cs  =  (init (unlines (words cs)),length (filter (not . isSpace) cs))
+
+gps8 :: [Char] -> [Char] -> [(Int,Char,Char)]
+-- testing 3 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- tested 0 candidates
+cannot conjure
+
+gps9 :: Int -> [Int]
+-- testing 3 combinations of argument values
+-- pruning with 13/14 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 10 candidates of size 5
+-- looking through 21 candidates of size 6
+-- looking through 30 candidates of size 7
+-- looking through 77 candidates of size 8
+-- looking through 134 candidates of size 9
+-- looking through 245 candidates of size 10
+-- tested 306 candidates
+gps9 x  =  filter even (filter (x >) (map sq [1..x]))
+
+wallisNext :: Ratio Integer -> Ratio Integer
+-- testing 6 combinations of argument values
+-- pruning with 37/64 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 15 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 86 candidates of size 6
+-- looking through 5 candidates of size 7
+-- looking through 537 candidates of size 8
+-- tested 588 candidates
+wallisNext (x % y)  =  (y + 1) % (x + 1)
+
+wallisNext :: Ratio Integer -> Ratio Integer
+-- testing 6 combinations of argument values
+-- pruning with 15/26 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 16 candidates of size 4
+-- looking through 3 candidates of size 5
+-- looking through 71 candidates of size 6
+-- looking through 5 candidates of size 7
+-- looking through 393 candidates of size 8
+-- tested 451 candidates
+wallisNext (x % y)  =  (y + 1) % (x + 1)
+
+gps10 :: Int -> Ratio Integer
+-- testing 6 combinations of argument values
+-- pruning with 3/4 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 8 candidates of size 7
+-- looking through 13 candidates of size 8
+-- tested 33 candidates
+gps10 x  =  product (take x (iterate wallisNext (2 % 3)))
+
+gps11 :: [[Char]] -> [Int]
+-- testing 4 combinations of argument values
+-- pruning with 1/1 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- tested 2 candidates
+gps11 css  =  reverse (map length css)
+
+gps11 :: [[Char]] -> [Int]
+-- testing 4 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 2 candidates of size 8
+-- tested 5 candidates
+gps11 []  =  []
+gps11 (cs:css)  =  gps11 css ++ [length cs]
+
+gps12 :: [Int] -> Int
+-- testing 6 combinations of argument values
+-- pruning with 13/27 rules
+-- looking through 2 candidates of size 1
+-- looking through 5 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 9 candidates of size 4
+-- looking through 22 candidates of size 5
+-- looking through 41 candidates of size 6
+-- looking through 125 candidates of size 7
+-- looking through 262 candidates of size 8
+-- looking through 816 candidates of size 9
+-- looking through 1996 candidates of size 10
+-- looking through 5925 candidates of size 11
+-- tested 6320 candidates
+gps12 xs  =  (length xs - fromJust (findIndex (0 ==) (reverse xs))) - 1
+
+gps13 :: [Ratio Integer] -> Ratio Integer
+-- testing 3 combinations of argument values
+-- pruning with 4/8 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 13 candidates of size 5
+-- looking through 51 candidates of size 6
+-- looking through 103 candidates of size 7
+-- looking through 365 candidates of size 8
+-- tested 267 candidates
+gps13 qs  =  foldr (+) 0 qs / fromIntegral (length qs)
+
+odd :: Int -> Bool
+-- testing 6 combinations of argument values
+-- pruning with 12/13 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 39 candidates of size 5
+-- tested 20 candidates
+odd x  =  0 /= x `mod` 2
+
+gps14 :: [Int] -> Int
+-- testing 3 combinations of argument values
+-- pruning with 1/1 rules
+-- looking through 0 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- tested 2 candidates
+gps14 xs  =  length (filter odd xs)
+
+gps14 :: [Int] -> Int
+-- testing 3 combinations of argument values
+-- pruning with 39/58 rules
+-- looking through 3 candidates of size 1
+-- looking through 9 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 27 candidates of size 4
+-- looking through 30 candidates of size 5
+-- looking through 258 candidates of size 6
+-- looking through 474 candidates of size 7
+-- tested 378 candidates
+gps14 []  =  0
+gps14 (x:xs)  =  x + gps14 xs `mod` 2
+
+gps15 :: [Int] -> [Int] -> Bool
+-- testing 5 combinations of argument values
+-- pruning with 3/7 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 4 candidates of size 4
+-- tested 3 candidates
+gps15 xs ys  =  xs == reverse ys
+
+gps16 :: [Char] -> [Char] -> Bool
+-- testing 6 combinations of argument values
+-- pruning with 3/3 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 2 candidates of size 5
+-- tested 9 candidates
+gps16 cs ds  =  sort cs `isSubsequenceOf` sort ds
+
+gps17 :: Int -> Int
+-- testing 4 combinations of argument values
+-- pruning with 27/65 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 7 candidates of size 3
+-- looking through 8 candidates of size 4
+-- looking through 28 candidates of size 5
+-- looking through 35 candidates of size 6
+-- looking through 179 candidates of size 7
+-- looking through 217 candidates of size 8
+-- looking through 1196 candidates of size 9
+-- tested 492 candidates
+gps17 0  =  0
+gps17 x  =  gps17 (x - 1) + x * x
+
+gps18 :: [Int] -> [Int] -> [Int]
+-- testing 3 combinations of argument values
+-- pruning with 2/6 rules
+-- looking through 3 candidates of size 1
+-- looking through 8 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 23 candidates of size 4
+-- looking through 86 candidates of size 5
+-- looking through 84 candidates of size 6
+-- looking through 354 candidates of size 7
+-- looking through 353 candidates of size 8
+-- looking through 1528 candidates of size 9
+-- tested 1409 candidates
+gps18 [] xs  =  xs
+gps18 (x:xs) []  =  xs
+gps18 (x:xs) (y:ys)  =  x + y:gps18 xs ys
+
+gps18 :: [Int] -> [Int] -> [Int]
+-- testing 3 combinations of argument values
+-- pruning with 2/7 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 9 candidates of size 4
+-- tested 13 candidates
+gps18 xs ys  =  zipWith (+) xs ys
+
+gps19 :: Int -> [Char] -> [Char]
+-- testing 2 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 1 candidates
+cannot conjure
+
+isVowel :: Char -> Bool
+-- testing 12 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 3 candidates of size 6
+-- looking through 4 candidates of size 7
+-- looking through 4 candidates of size 8
+-- looking through 4 candidates of size 9
+-- looking through 5 candidates of size 10
+-- looking through 5 candidates of size 11
+-- looking through 5 candidates of size 12
+-- looking through 5 candidates of size 13
+-- looking through 4 candidates of size 14
+-- looking through 4 candidates of size 15
+-- looking through 4 candidates of size 16
+-- looking through 3 candidates of size 17
+-- looking through 2 candidates of size 18
+-- looking through 2 candidates of size 19
+-- looking through 1 candidates of size 20
+-- looking through 1 candidates of size 21
+-- looking through 1 candidates of size 22
+-- tested 65 candidates
+isVowel 'a'  =  True
+isVowel 'e'  =  True
+isVowel 'i'  =  True
+isVowel 'o'  =  True
+isVowel 'u'  =  True
+isVowel 'y'  =  True
+isVowel c  =  False
+
+pig1 :: [Char] -> [Char]
+-- pruning with 5/5 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 8 candidates of size 4
+-- looking through 13 candidates of size 5
+-- looking through 28 candidates of size 6
+-- looking through 46 candidates of size 7
+-- looking through 126 candidates of size 8
+-- looking through 200 candidates of size 9
+-- looking through 631 candidates of size 10
+-- looking through 1068 candidates of size 11
+-- looking through 3495 candidates of size 12
+-- looking through 6381 candidates of size 13
+-- looking through 20409 candidates of size 14
+-- tested 27895 candidates
+pig1 ""  =  "ay"
+pig1 (c:cs)  =  if isVowel c
+                then (c:cs) ++ "ay"
+                else cs ++ (c:"ay")
+
+gps20c :: [Char] -> [Char]
+-- pruning with 1/1 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 5 candidates of size 5
+-- tested 12 candidates
+gps20c cs  =  unwords (map pig1 (words cs))
+
+gps21 :: [Int] -> [Int]
+-- testing 4 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 13 candidates of size 6
+-- looking through 8 candidates of size 7
+-- looking through 30 candidates of size 8
+-- looking through 24 candidates of size 9
+-- looking through 65 candidates of size 10
+-- tested 92 candidates
+gps21 []  =  []
+gps21 (x:xs)  =  (if x < 0 then 0 else x):gps21 xs
+
+gps22 :: [Char] -> Int
+-- pruning with 5/9 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 3 candidates of size 6
+-- tested 4 candidates
+gps22 ""  =  0
+gps22 (c:cs)  =  gps22 cs + scrabble1 c
+
+gps23 :: [Char] -> ([(Int,Int)],Int,Double)
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 0 candidates
+cannot conjure
+
+gps24 :: [Char] -> Char
+-- testing 4 combinations of argument values
+-- pruning with 15/19 rules
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 8 candidates of size 5
+-- looking through 13 candidates of size 6
+-- looking through 30 candidates of size 7
+-- looking through 75 candidates of size 8
+-- looking through 195 candidates of size 9
+-- looking through 474 candidates of size 10
+-- tested 457 candidates
+gps24 cs  =  chr (ord ' ' + sum (map ord cs) `mod` 64)
+
+gps25 :: Int -> [Int]
+-- testing 4 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- tested 0 candidates
+cannot conjure
+
+gps26 :: Int -> Int -> Int -> Int -> Int -> Char
+-- testing 5 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 5 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 5 candidates
+cannot conjure
+
+gps27 :: Int -> Int -> Int -> Int
+-- testing 3 combinations of argument values
+-- pruning with 14/18 rules
+-- looking through 3 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 36 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 0 candidates of size 8
+-- looking through 0 candidates of size 9
+-- looking through 90 candidates of size 10
+-- looking through 2592 candidates of size 11
+-- tested 1489 candidates
+gps27 x y z  =  if x < y
+                then if y < z then y else z
+                else x
+
+gps27b :: Int -> Int -> Int -> Int
+-- testing 3 combinations of argument values
+-- pruning with 20/30 rules
+-- looking through 3 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 12 candidates of size 5
+-- tested 15 candidates
+gps27b x y z  =  min z (max x y)
+
+gps28 :: Int -> Int -> Int -> Int -> Int
+-- testing 5 combinations of argument values
+-- pruning with 6/10 rules
+-- looking through 4 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 12 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 36 candidates of size 7
+-- tested 25 candidates
+gps28 x y z x'  =  x `min` (y `min` (z `min` x'))
+
+gps29 :: [Char] -> Int
+-- pruning with 7/11 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 6 candidates of size 6
+-- looking through 10 candidates of size 7
+-- looking through 10 candidates of size 8
+-- looking through 24 candidates of size 9
+-- tested 38 candidates
+gps29 ""  =  0
+gps29 (c:cs)  =  gps29 cs + (if isVowel c then 1 else 0)
+
diff --git a/bench/gps2.hs b/bench/gps2.hs
--- a/bench/gps2.hs
+++ b/bench/gps2.hs
@@ -1,6 +1,6 @@
 -- gps2.hs: General Program Synthesis Benchmark Suite II
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE CPP, TemplateHaskell #-}
 #if __GLASGOW_HASKELL__ <= 710
diff --git a/bench/gps2.out b/bench/gps2.out
deleted file mode 100644
--- a/bench/gps2.out
+++ /dev/null
@@ -1,388 +0,0 @@
-gps1 :: [Int] -> Maybe Int
--- testing 4 combinations of argument values
--- pruning with 11/21 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 1 candidates of size 7
--- looking through 0 candidates of size 8
--- looking through 1 candidates of size 9
--- looking through 2 candidates of size 10
--- tested 5 candidates
-gps1 xs  =  findIndex (0 >) (map (foldr (+) 0) (tail (inits xs)))
-
-gps1 :: [Int] -> Maybe Int
--- testing 4 combinations of argument values
--- pruning with 11/21 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 1 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 1 candidates of size 7
--- looking through 4 candidates of size 8
--- tested 6 candidates
-gps1 xs  =  findIndex (0 >) (map sum (tail (inits xs)))
-
-gps1 :: Int -> [Int] -> Int
--- testing 6 combinations of argument values
--- pruning with 8/9 rules
--- looking through 4 candidates of size 1
--- looking through 24 candidates of size 2
--- looking through 75 candidates of size 3
--- looking through 234 candidates of size 4
--- tested 337 candidates
-cannot conjure
-
-gps2 :: Double -> Double -> Int -> Double
--- testing 5 combinations of argument values
--- pruning with 2/6 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 17 candidates of size 3
--- looking through 62 candidates of size 4
--- looking through 266 candidates of size 5
--- looking through 1154 candidates of size 6
--- tested 1503 candidates
-cannot conjure
-
-gps3 :: [Char] -> Int
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 0 candidates
-cannot conjure
-
-gps4 :: [Char] -> [Char]
--- pruning with 13/20 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 9 candidates of size 3
--- looking through 22 candidates of size 4
--- looking through 54 candidates of size 5
--- looking through 124 candidates of size 6
--- tested 214 candidates
-cannot conjure
-
-gps5 :: Int -> [Int]
--- testing 6 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- tested 0 candidates
-cannot conjure
-
-tell :: [Int] -> Int -> [Int]
--- pruning with 0/0 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 6 candidates of size 5
--- looking through 46 candidates of size 6
--- looking through 26 candidates of size 7
--- looking through 400 candidates of size 8
--- looking through 134 candidates of size 9
--- looking through 3914 candidates of size 10
--- tested 1552 candidates
-tell [] x  =  []
-tell (x:xs) y  =  y `div` x:tell xs (y `mod` x)
-
-gps5 :: Int -> [Int]
--- testing 6 combinations of argument values
--- pruning with 0/0 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 1 candidates of size 3
--- tested 2 candidates
-gps5 x  =  tell [25,10,5,1] x
-
-gps5 :: Int -> [Int]
--- testing 6 combinations of argument values
--- pruning with 12/12 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 9 candidates of size 4
--- looking through 45 candidates of size 5
--- looking through 82 candidates of size 6
--- looking through 428 candidates of size 7
--- looking through 887 candidates of size 8
--- looking through 4354 candidates of size 9
--- looking through 9260 candidates of size 10
--- looking through 43875 candidates of size 11
--- tested 32327 candidates
-gps5 x  =  tell [25,10,5,1] x
-
-gps6 :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- tested 2 candidates
-cannot conjure
-
-gps7 :: Integer -> Integer -> Ratio Integer
--- testing 6 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- tested 0 candidates
-cannot conjure
-
-gps8 :: Int -> [Int] -> (Int,Int)
--- testing 3 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 0 candidates
-cannot conjure
-
-gps9 :: Int -> [Char]
--- testing 7 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- tested 0 candidates
-cannot conjure
-
-gps10 :: [Int] -> Int
--- testing 7 combinations of argument values
--- pruning with 67/100 rules
--- looking through 4 candidates of size 1
--- looking through 16 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 68 candidates of size 4
--- looking through 80 candidates of size 5
--- looking through 1084 candidates of size 6
--- looking through 1556 candidates of size 7
--- looking through 20600 candidates of size 8
--- looking through 35632 candidates of size 9
--- tested 29542 candidates
-gps10 []  =  0
-gps10 (x:xs)  =  gps10 xs + (x `div` 3 - 2)
-
-gcd :: Int -> Int -> Int
--- testing 11 combinations of argument values
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 50 candidates of size 4
--- looking through 98 candidates of size 5
--- looking through 359 candidates of size 6
--- tested 171 candidates
-gcd x 0  =  x
-gcd x y  =  gcd y (x `mod` y)
-
-gps12 :: [Char] -> [Char] -> [Int]
--- testing 5 combinations of argument values
--- pruning with 1/2 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 4 candidates of size 5
--- tested 3 candidates
-gps12 cs ds  =  findIndices (ds `isPrefixOf`) (tails cs)
-
-gps13_leaders :: [Int] -> [Int]
--- testing 4 combinations of argument values
--- pruning with 5/5 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 1 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 1 candidates of size 7
--- looking through 4 candidates of size 8
--- looking through 7 candidates of size 9
--- looking through 21 candidates of size 10
--- looking through 34 candidates of size 11
--- looking through 67 candidates of size 12
--- tested 83 candidates
-gps13_leaders []  =  []
-gps13_leaders (x:xs)  =  if all (x >) xs
-                         then x:gps13_leaders xs
-                         else gps13_leaders xs
-
-gps14_luhn :: [Int] -> Int
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 0 candidates
-cannot conjure
-
-gps15_mastermind :: () -> ()
--- pruning with 0/1 rules
--- looking through 1 candidates of size 1
--- tested 1 candidates
-gps15_mastermind u  =  u
-
-gps16_middle :: [Char] -> [Char]
--- testing 7 combinations of argument values
--- pruning with 10/11 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 7 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 34 candidates of size 6
--- looking through 61 candidates of size 7
--- looking through 126 candidates of size 8
--- looking through 307 candidates of size 9
--- looking through 824 candidates of size 10
--- looking through 2282 candidates of size 11
--- looking through 6293 candidates of size 12
--- tested 3977 candidates
-gps16_middle ""  =  ""
-gps16_middle (c:cs)  =  if length cs <= 1
-                        then c:cs
-                        else gps16_middle (init cs)
-
-gps17_pds :: [Int] -> Int
--- testing 5 combinations of argument values
--- pruning with 29/40 rules
--- looking through 1 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 3 candidates of size 5
--- tested 9 candidates
-cannot conjure
-
-gps18_price :: [Double] -> [Double] -> Double
--- testing 4 combinations of argument values
--- pruning with 26/35 rules
--- looking through 2 candidates of size 1
--- looking through 8 candidates of size 2
--- looking through 32 candidates of size 3
--- looking through 86 candidates of size 4
--- looking through 412 candidates of size 5
--- looking through 1072 candidates of size 6
--- tested 1612 candidates
-cannot conjure
-
-gps19_snowday :: Int -> Double -> Double -> Double -> Double
--- testing 7 combinations of argument values
--- pruning with 6/19 rules
--- looking through 3 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 22 candidates of size 3
--- looking through 118 candidates of size 4
--- looking through 318 candidates of size 5
--- looking through 1936 candidates of size 6
--- tested 2401 candidates
-cannot conjure
-
-gps20 :: [Char] -> Bool
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- tested 0 candidates
-cannot conjure
-
-spin :: [Char] -> [Char]
--- pruning with 6/6 rules
--- reasoning produced 1 incorrect properties, please re-run with more tests for faster results
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 4 candidates of size 8
--- tested 3 candidates
-spin cs  =  if length cs >= 5
-            then reverse cs
-            else cs
-
-gps21_spinwords :: [Char] -> [Char]
--- pruning with 16/16 rules
--- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
--- looking through 1 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 5 candidates of size 5
--- tested 12 candidates
-gps21_spinwords cs  =  unwords (map spin (words cs))
-
-digits :: Int -> [Int]
--- testing 5 combinations of argument values
--- pruning with 7/7 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 14 candidates of size 5
--- looking through 13 candidates of size 6
--- looking through 94 candidates of size 7
--- looking through 104 candidates of size 8
--- looking through 856 candidates of size 9
--- looking through 929 candidates of size 10
--- looking through 8914 candidates of size 11
--- looking through 9686 candidates of size 12
--- tested 20616 candidates
-cannot conjure
-
-gps22 :: Int -> [Char]
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- tested 0 candidates
-cannot conjure
-
-gps23 :: [Char] -> [Char] -> [Char] -> [Char]
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 9 candidates of size 2
--- looking through 31 candidates of size 3
--- looking through 36 candidates of size 4
--- looking through 187 candidates of size 5
--- looking through 627 candidates of size 6
--- looking through 944 candidates of size 7
--- looking through 863 candidates of size 8
--- looking through 951 candidates of size 9
--- looking through 3902 candidates of size 10
--- looking through 6758 candidates of size 11
--- looking through 3276 candidates of size 12
--- tested 17587 candidates
-cannot conjure
-
-gps24 :: [Char] -> Twitter
--- pruning with 4/8 rules
--- reasoning produced 4 incorrect properties, please re-run with more tests for faster results
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 8 candidates of size 3
--- looking through 7 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 10 candidates of size 7
--- looking through 48 candidates of size 8
--- looking through 138 candidates of size 9
--- looking through 232 candidates of size 10
--- looking through 322 candidates of size 11
--- looking through 483 candidates of size 12
--- tested 936 candidates
-gps24 ""  =  Empty
-gps24 (c:cs)  =  if 140 > length cs
-                 then Tweet (length (c:cs))
-                 else TooMany
-
-gps25 :: [Double] -> [Double] -> Double
--- testing 6 combinations of argument values
--- pruning with 31/59 rules
--- looking through 2 candidates of size 1
--- looking through 9 candidates of size 2
--- looking through 49 candidates of size 3
--- looking through 211 candidates of size 4
--- looking through 1063 candidates of size 5
--- looking through 4717 candidates of size 6
--- tested 6051 candidates
-cannot conjure
-
diff --git a/bench/gps2.txt b/bench/gps2.txt
new file mode 100644
--- /dev/null
+++ b/bench/gps2.txt
@@ -0,0 +1,387 @@
+gps1 :: [Int] -> Maybe Int
+-- testing 4 combinations of argument values
+-- pruning with 11/21 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 1 candidates of size 7
+-- looking through 0 candidates of size 8
+-- looking through 1 candidates of size 9
+-- looking through 2 candidates of size 10
+-- tested 5 candidates
+gps1 xs  =  findIndex (0 >) (map (foldr (+) 0) (tail (inits xs)))
+
+gps1 :: [Int] -> Maybe Int
+-- testing 4 combinations of argument values
+-- pruning with 11/21 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 1 candidates of size 7
+-- looking through 4 candidates of size 8
+-- tested 6 candidates
+gps1 xs  =  findIndex (0 >) (map sum (tail (inits xs)))
+
+gps1 :: Int -> [Int] -> Int
+-- testing 6 combinations of argument values
+-- pruning with 8/9 rules
+-- looking through 4 candidates of size 1
+-- looking through 24 candidates of size 2
+-- looking through 75 candidates of size 3
+-- looking through 216 candidates of size 4
+-- tested 319 candidates
+cannot conjure
+
+gps2 :: Double -> Double -> Int -> Double
+-- testing 5 combinations of argument values
+-- pruning with 2/6 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 17 candidates of size 3
+-- looking through 62 candidates of size 4
+-- looking through 266 candidates of size 5
+-- looking through 1154 candidates of size 6
+-- tested 1503 candidates
+cannot conjure
+
+gps3 :: [Char] -> Int
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 0 candidates
+cannot conjure
+
+gps4 :: [Char] -> [Char]
+-- pruning with 13/20 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 8 candidates of size 3
+-- looking through 20 candidates of size 4
+-- looking through 51 candidates of size 5
+-- looking through 119 candidates of size 6
+-- tested 203 candidates
+cannot conjure
+
+gps5 :: Int -> [Int]
+-- testing 6 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- tested 0 candidates
+cannot conjure
+
+tell :: [Int] -> Int -> [Int]
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 6 candidates of size 5
+-- looking through 39 candidates of size 6
+-- looking through 26 candidates of size 7
+-- looking through 328 candidates of size 8
+-- looking through 134 candidates of size 9
+-- looking through 3229 candidates of size 10
+-- tested 783 candidates
+tell [] x  =  []
+tell (x:xs) y  =  y `div` x:tell xs (y `mod` x)
+
+gps5 :: Int -> [Int]
+-- testing 6 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- tested 2 candidates
+gps5 x  =  tell [25,10,5,1] x
+
+gps5 :: Int -> [Int]
+-- testing 6 combinations of argument values
+-- pruning with 12/12 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 5 candidates of size 3
+-- looking through 9 candidates of size 4
+-- looking through 45 candidates of size 5
+-- looking through 82 candidates of size 6
+-- looking through 428 candidates of size 7
+-- looking through 882 candidates of size 8
+-- looking through 4350 candidates of size 9
+-- looking through 9232 candidates of size 10
+-- looking through 43847 candidates of size 11
+-- tested 32290 candidates
+gps5 x  =  tell [25,10,5,1] x
+
+gps6 :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 1 candidates of size 2
+-- tested 1 candidates
+cannot conjure
+
+gps7 :: Integer -> Integer -> Ratio Integer
+-- testing 6 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- tested 0 candidates
+cannot conjure
+
+gps8 :: Int -> [Int] -> (Int,Int)
+-- testing 3 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 0 candidates
+cannot conjure
+
+gps9 :: Int -> [Char]
+-- testing 7 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- tested 0 candidates
+cannot conjure
+
+gps10 :: [Int] -> Int
+-- testing 7 combinations of argument values
+-- pruning with 67/100 rules
+-- looking through 4 candidates of size 1
+-- looking through 16 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 68 candidates of size 4
+-- looking through 80 candidates of size 5
+-- looking through 1084 candidates of size 6
+-- looking through 1556 candidates of size 7
+-- looking through 20600 candidates of size 8
+-- looking through 35632 candidates of size 9
+-- tested 29538 candidates
+gps10 []  =  0
+gps10 (x:xs)  =  gps10 xs + (x `div` 3 - 2)
+
+gcd :: Int -> Int -> Int
+-- testing 11 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 50 candidates of size 4
+-- looking through 98 candidates of size 5
+-- looking through 344 candidates of size 6
+-- tested 173 candidates
+gcd x 0  =  x
+gcd x y  =  gcd y (x `mod` y)
+
+gps12 :: [Char] -> [Char] -> [Int]
+-- testing 5 combinations of argument values
+-- pruning with 1/2 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 4 candidates of size 5
+-- tested 3 candidates
+gps12 cs ds  =  findIndices (ds `isPrefixOf`) (tails cs)
+
+gps13_leaders :: [Int] -> [Int]
+-- testing 4 combinations of argument values
+-- pruning with 5/5 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 1 candidates of size 7
+-- looking through 4 candidates of size 8
+-- looking through 7 candidates of size 9
+-- looking through 21 candidates of size 10
+-- looking through 34 candidates of size 11
+-- looking through 67 candidates of size 12
+-- tested 82 candidates
+gps13_leaders []  =  []
+gps13_leaders (x:xs)  =  if all (x >) xs
+                         then x:gps13_leaders xs
+                         else gps13_leaders xs
+
+gps14_luhn :: [Int] -> Int
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 0 candidates
+cannot conjure
+
+gps15_mastermind :: () -> ()
+-- pruning with 0/1 rules
+-- looking through 1 candidates of size 1
+-- tested 1 candidates
+gps15_mastermind u  =  u
+
+gps16_middle :: [Char] -> [Char]
+-- testing 7 combinations of argument values
+-- pruning with 10/11 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 19 candidates of size 5
+-- looking through 32 candidates of size 6
+-- looking through 59 candidates of size 7
+-- looking through 124 candidates of size 8
+-- looking through 305 candidates of size 9
+-- looking through 822 candidates of size 10
+-- looking through 2276 candidates of size 11
+-- looking through 6273 candidates of size 12
+-- tested 3956 candidates
+gps16_middle ""  =  ""
+gps16_middle (c:cs)  =  if length cs <= 1
+                        then c:cs
+                        else gps16_middle (init cs)
+
+gps17_pds :: [Int] -> Int
+-- testing 5 combinations of argument values
+-- pruning with 29/40 rules
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 3 candidates of size 5
+-- tested 8 candidates
+cannot conjure
+
+gps18_price :: [Double] -> [Double] -> Double
+-- testing 4 combinations of argument values
+-- pruning with 26/35 rules
+-- looking through 2 candidates of size 1
+-- looking through 8 candidates of size 2
+-- looking through 32 candidates of size 3
+-- looking through 70 candidates of size 4
+-- looking through 396 candidates of size 5
+-- looking through 1016 candidates of size 6
+-- tested 1524 candidates
+cannot conjure
+
+gps19_snowday :: Int -> Double -> Double -> Double -> Double
+-- testing 7 combinations of argument values
+-- pruning with 6/19 rules
+-- looking through 3 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 24 candidates of size 3
+-- looking through 120 candidates of size 4
+-- looking through 318 candidates of size 5
+-- looking through 1944 candidates of size 6
+-- tested 2415 candidates
+cannot conjure
+
+gps20 :: [Char] -> Bool
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 0 candidates
+cannot conjure
+
+spin :: [Char] -> [Char]
+-- pruning with 6/6 rules
+-- reasoning produced 1 incorrect properties, please re-run with more tests for faster results
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 4 candidates of size 8
+-- tested 3 candidates
+spin cs  =  if length cs >= 5
+            then reverse cs
+            else cs
+
+gps21_spinwords :: [Char] -> [Char]
+-- pruning with 16/16 rules
+-- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 5 candidates of size 5
+-- tested 12 candidates
+gps21_spinwords cs  =  unwords (map spin (words cs))
+
+digits :: Int -> [Int]
+-- testing 5 combinations of argument values
+-- pruning with 7/7 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 11 candidates of size 5
+-- looking through 13 candidates of size 6
+-- looking through 91 candidates of size 7
+-- looking through 104 candidates of size 8
+-- looking through 850 candidates of size 9
+-- looking through 923 candidates of size 10
+-- looking through 8902 candidates of size 11
+-- looking through 9662 candidates of size 12
+-- tested 20562 candidates
+cannot conjure
+
+gps22 :: Int -> [Char]
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- tested 0 candidates
+cannot conjure
+
+gps23 :: [Char] -> [Char] -> [Char] -> [Char]
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 12 candidates of size 2
+-- looking through 33 candidates of size 3
+-- looking through 36 candidates of size 4
+-- looking through 127 candidates of size 5
+-- looking through 507 candidates of size 6
+-- looking through 839 candidates of size 7
+-- looking through 784 candidates of size 8
+-- looking through 600 candidates of size 9
+-- looking through 2722 candidates of size 10
+-- looking through 5292 candidates of size 11
+-- looking through 2832 candidates of size 12
+-- tested 13787 candidates
+cannot conjure
+
+gps24 :: [Char] -> Twitter
+-- pruning with 4/8 rules
+-- reasoning produced 4 incorrect properties, please re-run with more tests for faster results
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 3 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 10 candidates of size 7
+-- looking through 48 candidates of size 8
+-- looking through 134 candidates of size 9
+-- looking through 224 candidates of size 10
+-- looking through 314 candidates of size 11
+-- looking through 479 candidates of size 12
+-- tested 908 candidates
+gps24 ""  =  Empty
+gps24 (c:cs)  =  if 140 > length cs
+                 then Tweet (length (c:cs))
+                 else TooMany
+
+gps25 :: [Double] -> [Double] -> Double
+-- testing 6 combinations of argument values
+-- pruning with 31/59 rules
+-- looking through 2 candidates of size 1
+-- looking through 9 candidates of size 2
+-- looking through 49 candidates of size 3
+-- looking through 195 candidates of size 4
+-- looking through 1035 candidates of size 5
+-- looking through 4596 candidates of size 6
+-- tested 5886 candidates
+cannot conjure
+
diff --git a/bench/ill-hit.out b/bench/ill-hit.out
deleted file mode 100644
--- a/bench/ill-hit.out
+++ /dev/null
@@ -1,23 +0,0 @@
-sum :: [Int] -> Int
--- testing 4 combinations of argument values
--- pruning with 14/25 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 7 candidates of size 4
--- looking through 11 candidates of size 5
--- tested 16 candidates
-sum []  =  0
-sum (x:xs)  =  x + sum xs
-
-sum :: [Int] -> Int
--- pruning with 14/25 rules
--- looking through 2 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 18 candidates of size 5
--- tested 25 candidates
-sum []  =  0
-sum (x:xs)  =  x + sum xs
-
diff --git a/bench/ill-hit.txt b/bench/ill-hit.txt
new file mode 100644
--- /dev/null
+++ b/bench/ill-hit.txt
@@ -0,0 +1,23 @@
+sum :: [Int] -> Int
+-- testing 4 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 11 candidates of size 5
+-- tested 14 candidates
+sum []  =  0
+sum (x:xs)  =  x + sum xs
+
+sum :: [Int] -> Int
+-- pruning with 14/25 rules
+-- looking through 2 candidates of size 1
+-- looking through 5 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 18 candidates of size 5
+-- tested 21 candidates
+sum []  =  0
+sum (x:xs)  =  x + sum xs
+
diff --git a/bench/longshot.hs b/bench/longshot.hs
--- a/bench/longshot.hs
+++ b/bench/longshot.hs
@@ -1,6 +1,6 @@
 -- longshot.hs: miscellaneous longshots
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/bench/longshot.out b/bench/longshot.out
deleted file mode 100644
--- a/bench/longshot.out
+++ /dev/null
diff --git a/bench/longshot.txt b/bench/longshot.txt
new file mode 100644
--- /dev/null
+++ b/bench/longshot.txt
diff --git a/bench/lowtests.hs b/bench/lowtests.hs
--- a/bench/lowtests.hs
+++ b/bench/lowtests.hs
@@ -1,6 +1,6 @@
 -- lowtests.hs: conjuring with a low number of tests
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 --
 -- With a low number of tests Conjure may not be able to find the actual
diff --git a/bench/lowtests.out b/bench/lowtests.out
deleted file mode 100644
--- a/bench/lowtests.out
+++ /dev/null
@@ -1,89 +0,0 @@
-subset :: [Int] -> [Int] -> Bool
--- testing 44 combinations of argument values
--- pruning with 3/3 rules
-{-
-rules:
-xs `isSubsequenceOf` xs == True
-sort (sort xs) == sort xs
-sort xs `isSubsequenceOf` ys == xs `isSubsequenceOf` sort ys
-
--}
--- reasoning produced 1 incorrect properties, please re-run with more tests for faster results
-{-
-invalid:
-xs `isSubsequenceOf` sort xs == True
--}
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 12 candidates of size 7
--- looking through 21 candidates of size 8
--- looking through 8 candidates of size 9
--- looking through 6 candidates of size 10
--- looking through 30 candidates of size 11
--- looking through 45 candidates of size 12
--- tested 128 candidates
-cannot conjure
-
-subset :: [Int] -> [Int] -> Bool
--- testing 44 combinations of argument values
--- pruning with 3/3 rules
-{-
-rules:
-xs `isSubsequenceOf` xs == True
-sort (sort xs) == sort xs
-sort xs `isSubsequenceOf` xs == xs `isSubsequenceOf` sort xs
-
--}
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 2 candidates of size 5
--- tested 9 candidates
-subset xs ys  =  sort xs `isSubsequenceOf` sort ys
-
-replicates :: [Char] -> Int -> [Char]
--- testing 60 combinations of argument values
--- pruning with 2/2 rules
-{-
-rules:
-concat (transpose xss) == concat xss
-transpose (transpose (transpose xss)) == transpose xss
-
--}
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 1 candidates of size 7
--- looking through 0 candidates of size 8
--- looking through 0 candidates of size 9
--- looking through 1 candidates of size 10
--- looking through 0 candidates of size 11
--- looking through 0 candidates of size 12
--- tested 4 candidates
-cannot conjure
-
-replicates :: [Char] -> Int -> [Char]
--- testing 360 combinations of argument values
--- pruning with 2/2 rules
-{-
-rules:
-transpose (transpose (transpose xss)) == transpose xss
-replicate x (concat (transpose xss)) == replicate x (concat xss)
-
--}
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 1 candidates of size 5
--- tested 3 candidates
-replicates cs x  =  concat (transpose (replicate x cs))
-
diff --git a/bench/lowtests.txt b/bench/lowtests.txt
new file mode 100644
--- /dev/null
+++ b/bench/lowtests.txt
@@ -0,0 +1,89 @@
+subset :: [Int] -> [Int] -> Bool
+-- testing 44 combinations of argument values
+-- pruning with 3/3 rules
+{-
+rules:
+xs `isSubsequenceOf` xs == True
+sort (sort xs) == sort xs
+sort xs `isSubsequenceOf` ys == xs `isSubsequenceOf` sort ys
+
+-}
+-- reasoning produced 1 incorrect properties, please re-run with more tests for faster results
+{-
+invalid:
+xs `isSubsequenceOf` sort xs == True
+-}
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 10 candidates of size 7
+-- looking through 10 candidates of size 8
+-- looking through 0 candidates of size 9
+-- looking through 6 candidates of size 10
+-- looking through 20 candidates of size 11
+-- looking through 15 candidates of size 12
+-- tested 67 candidates
+cannot conjure
+
+subset :: [Int] -> [Int] -> Bool
+-- testing 44 combinations of argument values
+-- pruning with 3/3 rules
+{-
+rules:
+xs `isSubsequenceOf` xs == True
+sort (sort xs) == sort xs
+sort xs `isSubsequenceOf` xs == xs `isSubsequenceOf` sort xs
+
+-}
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 2 candidates of size 5
+-- tested 9 candidates
+subset xs ys  =  sort xs `isSubsequenceOf` sort ys
+
+replicates :: [Char] -> Int -> [Char]
+-- testing 60 combinations of argument values
+-- pruning with 2/2 rules
+{-
+rules:
+concat (transpose xss) == concat xss
+transpose (transpose (transpose xss)) == transpose xss
+
+-}
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 1 candidates of size 7
+-- looking through 0 candidates of size 8
+-- looking through 0 candidates of size 9
+-- looking through 1 candidates of size 10
+-- looking through 0 candidates of size 11
+-- looking through 0 candidates of size 12
+-- tested 4 candidates
+cannot conjure
+
+replicates :: [Char] -> Int -> [Char]
+-- testing 360 combinations of argument values
+-- pruning with 2/2 rules
+{-
+rules:
+transpose (transpose (transpose xss)) == transpose xss
+replicate x (concat (transpose xss)) == replicate x (concat xss)
+
+-}
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 1 candidates of size 5
+-- tested 3 candidates
+replicates cs x  =  concat (transpose (replicate x cs))
+
diff --git a/bench/p12.hs b/bench/p12.hs
--- a/bench/p12.hs
+++ b/bench/p12.hs
@@ -1,6 +1,6 @@
 -- 12 background primitives
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 import System.Environment
diff --git a/bench/p12.out b/bench/p12.out
deleted file mode 100644
--- a/bench/p12.out
+++ /dev/null
@@ -1,14 +0,0 @@
-running with 13 primitives
-factorial :: Int -> Int
--- testing 6 combinations of argument values
--- pruning with 67/100 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 15 candidates of size 4
--- looking through 43 candidates of size 5
--- looking through 152 candidates of size 6
--- tested 77 candidates
-factorial 0  =  1
-factorial x  =  x * factorial (dec x)
-
diff --git a/bench/p12.txt b/bench/p12.txt
new file mode 100644
--- /dev/null
+++ b/bench/p12.txt
@@ -0,0 +1,14 @@
+running with 13 primitives
+factorial :: Int -> Int
+-- testing 6 combinations of argument values
+-- pruning with 67/100 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 13 candidates of size 4
+-- looking through 40 candidates of size 5
+-- looking through 138 candidates of size 6
+-- tested 69 candidates
+factorial 0  =  1
+factorial x  =  x * factorial (dec x)
+
diff --git a/bench/p30.hs b/bench/p30.hs
--- a/bench/p30.hs
+++ b/bench/p30.hs
@@ -1,6 +1,6 @@
 -- 30 background primitives, does Conjure scale?
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 import System.Environment
diff --git a/bench/p30.out b/bench/p30.out
deleted file mode 100644
--- a/bench/p30.out
+++ /dev/null
@@ -1,2 +0,0 @@
-running with 26 primitives
-usage: p30 <factorial|sum|product|length|count> [t]
diff --git a/bench/p30.txt b/bench/p30.txt
new file mode 100644
--- /dev/null
+++ b/bench/p30.txt
@@ -0,0 +1,2 @@
+running with 26 primitives
+usage: p30 <factorial|sum|product|length|count> [t]
diff --git a/bench/redundants.hs b/bench/redundants.hs
--- a/bench/redundants.hs
+++ b/bench/redundants.hs
@@ -1,12 +1,14 @@
 -- Print redundant candidates
 --
--- Copyright (C) 2023 Rudy Matela
+-- Copyright (C) 2023-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
 -- This script needs some internal utilities of Conjure:
 import Conjure.Engine
 import Conjure.Defn
+import Conjure.Defn.Redundancy
+import Conjure.Defn.Test
 import Conjure.Utils
 import Test.LeanCheck.Tiers (discardT)
 
@@ -41,8 +43,8 @@
   (css', thy)    =  candidateDefnsC args nm f ps  -- Conjure uses this for listing candidates
   nRules         =  length (rules thy)
   nREs           =  length (equations thy) + nRules
-  maxTests       =  360 -- a hardcoded value probably will not hurt in this simple benchmark
-  maxEvalRecursions  =  60
+  maxTests       =  60 -- a hardcoded value probably will not hurt in this simple benchmark
+  maxEvalRecursions  =  30
 
   -- shows a class of candidates
   showClass :: [Defn] -> String
@@ -56,8 +58,8 @@
 
   -- This N value limits the maximum size of candidates,
   -- increase it to print redundant candidates of bigger size.
-  let n = 5
-  -- With n = 5, this should run in a few seconds.
+  let n = 6
+  -- With n = 6, this should run in a few seconds.
   -- With n = 7 and -O2 optimization,
   -- this should take a few minutes to run and generate a ~300K text file.
   -- We can also customize the n per-function below:
diff --git a/bench/redundants.out b/bench/redundants.out
deleted file mode 100644
--- a/bench/redundants.out
+++ /dev/null
@@ -1,953 +0,0 @@
-Redundant candidates for: foo :: Int -> Int
-  pruning with 15/35 rules
-  [3,3,8,13,29] candidates
-  46/56 unique candidates
-  10/56 redundant candidates
-
-rules:
-x * y == x + y
-x * y == y + x
-x - x == 0
-x + 0 == x
-0 + x == x
-x - 0 == x
-(x + y) + z == x + (y + z)
-(x + y) + z == y + (x + z)
-x - (y - z) == z + (x - y)
-(x - y) - z == x - (y + z)
-(x - y) - z == x - (z + y)
-(x + y) - z == x + (y - z)
-(x + y) - z == y + (x - z)
-x + (y - x) == y
-(x - y) + y == x
-equations:
-y + x == x + y
-y + (x + z) == x + (y + z)
-z + (x + y) == x + (y + z)
-z + (y + x) == x + (y + z)
-y + (x - z) == x + (y - z)
-(x - z) + y == x + (y - z)
-(z - y) + x == (x - y) + z
-y - (x + y) == 0 - x
-y - (y + x) == 0 - x
-z - (y + z) == x - (x + y)
-z - (y + z) == x - (y + x)
-z - (z + y) == x - (x + y)
-z - (z + y) == x - (y + x)
-x + (0 - y) == x - y
-(0 - y) + x == x - y
-x - (x + 1) == 0 - 1
-x - (1 + x) == 0 - 1
-y - (y + 1) == x - (x + 1)
-y - (y + 1) == x - (1 + x)
-y - (1 + y) == x - (1 + x)
-
-class of 2 equivalent candidates:
-
-    foo x  =  x + x
-
-    foo 0  =  0
-    foo x  =  x + x
-
-
-class of 2 equivalent candidates:
-
-    foo x  =  x + 1
-
-    foo 0  =  1
-    foo x  =  x + 1
-
-
-class of 2 equivalent candidates:
-
-    foo x  =  x - 1
-
-    foo 1  =  0
-    foo x  =  x - 1
-
-
-class of 4 equivalent candidates:
-
-    foo x  =  0 - x
-
-    foo 0  =  0
-    foo x  =  0 - x
-
-    foo x  =  x - (x + x)
-
-    foo x  =  1 - (x + 1)
-
-
-class of 4 equivalent candidates:
-
-    foo x  =  1 - x
-
-    foo 0  =  1
-    foo x  =  1 - x
-
-    foo x  =  1 + (0 - x)
-
-    foo 1  =  0
-    foo x  =  1 - x
-
-
-class of 2 equivalent candidates:
-
-    foo x  =  x + (x + 1)
-
-    foo x  =  1 + (x + x)
-
-
-
-Redundant candidates for: ? :: Int -> Int -> Int
-  pruning with 10/23 rules
-  [3,7,22,53,129] candidates
-  192/214 unique candidates
-  22/214 redundant candidates
-
-rules:
-x * y == x + y
-x * y == y + x
-x + 0 == x
-0 + x == x
-dec (x + y) == x + dec y
-dec (x + y) == y + dec x
-dec (x + y) == dec x + y
-dec (x + y) == dec y + x
-(x + y) + z == x + (y + z)
-(x + y) + z == y + (x + z)
-equations:
-y + x == x + y
-y + dec x == x + dec y
-dec x + y == x + dec y
-dec y + x == dec x + y
-x + dec 0 == dec x
-dec 0 + x == dec x
-y + (x + z) == x + (y + z)
-z + (x + y) == x + (y + z)
-z + (y + x) == x + (y + z)
-y + dec (dec x) == x + dec (dec y)
-dec (dec x) + y == x + dec (dec y)
-x + dec (dec 0) == dec (dec x)
-dec (dec 0) + x == dec (dec x)
-
-class of 2 equivalent candidates:
-
-    x ? y  =  x + x
-
-    0 ? x  =  0
-    x ? y  =  x + x
-
-
-class of 4 equivalent candidates:
-
-    x ? y  =  x + y
-
-    x ? 0  =  x
-    x ? y  =  x + y
-
-    0 ? x  =  x
-    x ? y  =  x + y
-
-    0 ? x  =  x
-    x ? 0  =  x
-    x ? y  =  x + y
-
-
-class of 2 equivalent candidates:
-
-    x ? y  =  y + y
-
-    x ? 0  =  0
-    x ? y  =  y + y
-
-
-class of 2 equivalent candidates:
-
-    x ? y  =  x + dec y
-
-    x ? y  =  y + dec x
-
-
-class of 2 equivalent candidates:
-
-    x ? 0  =  x
-    x ? y  =  x + x
-
-    0 ? x  =  0
-    x ? 0  =  x
-    x ? y  =  x + x
-
-
-class of 2 equivalent candidates:
-
-    x ? 0  =  0
-    x ? y  =  x + x
-
-    0 ? x  =  0
-    x ? 0  =  0
-    x ? y  =  x + x
-
-
-class of 2 equivalent candidates:
-
-    x ? 0  =  0
-    x ? y  =  x + y
-
-    0 ? x  =  x
-    x ? 0  =  0
-    x ? y  =  x + y
-
-
-class of 2 equivalent candidates:
-
-    0 ? x  =  x
-    x ? y  =  y + y
-
-    0 ? x  =  x
-    x ? 0  =  0
-    x ? y  =  y + y
-
-
-class of 2 equivalent candidates:
-
-    0 ? x  =  0
-    x ? y  =  x + y
-
-    0 ? x  =  0
-    x ? 0  =  x
-    x ? y  =  x + y
-
-
-class of 2 equivalent candidates:
-
-    0 ? x  =  0
-    x ? y  =  y + y
-
-    0 ? x  =  0
-    x ? 0  =  0
-    x ? y  =  y + y
-
-
-class of 2 equivalent candidates:
-
-    x ? y  =  x + (x + y)
-
-    x ? y  =  y + (x + x)
-
-
-class of 2 equivalent candidates:
-
-    x ? y  =  x + (y + y)
-
-    x ? y  =  y + (x + y)
-
-
-class of 2 equivalent candidates:
-
-    x ? y  =  x + dec (dec x)
-
-    x ? y  =  dec x + dec x
-
-
-class of 3 equivalent candidates:
-
-    x ? y  =  x + dec (dec y)
-
-    x ? y  =  y + dec (dec x)
-
-    x ? y  =  dec x + dec y
-
-
-class of 2 equivalent candidates:
-
-    x ? y  =  y + dec (dec y)
-
-    x ? y  =  dec y + dec y
-
-
-class of 2 equivalent candidates:
-
-    x ? 0  =  x
-    x ? y  =  x + dec y
-
-    x ? 0  =  x
-    x ? y  =  y + dec x
-
-
-class of 2 equivalent candidates:
-
-    x ? 0  =  0
-    x ? y  =  x + dec y
-
-    x ? 0  =  0
-    x ? y  =  y + dec x
-
-
-class of 2 equivalent candidates:
-
-    0 ? x  =  x
-    x ? y  =  x + dec y
-
-    0 ? x  =  x
-    x ? y  =  y + dec x
-
-
-class of 2 equivalent candidates:
-
-    0 ? x  =  0
-    x ? y  =  x + dec y
-
-    0 ? x  =  0
-    x ? y  =  y + dec x
-
-
-
-Redundant candidates for: goo :: [Int] -> [Int]
-  pruning with 4/4 rules
-  [2,1,2,2,4] candidates
-  9/11 unique candidates
-  2/11 redundant candidates
-
-rules:
-xs ++ [] == xs
-[] ++ xs == xs
-(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
-(x:xs) ++ ys == x:(xs ++ ys)
-
-class of 2 equivalent candidates:
-
-    goo xs  =  xs
-
-    goo []  =  []
-    goo (x:xs)  =  x:goo xs
-
-
-class of 2 equivalent candidates:
-
-    goo xs  =  []
-
-    goo []  =  []
-    goo (x:xs)  =  goo xs
-
-
-
-Redundant candidates for: ?? :: [Int] -> [Int] -> [Int]
-  pruning with 4/4 rules
-  [3,7,15,57,134] candidates
-  160/216 unique candidates
-  56/216 redundant candidates
-
-rules:
-xs ++ [] == xs
-[] ++ xs == xs
-(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
-(x:xs) ++ ys == x:(xs ++ ys)
-
-class of 2 equivalent candidates:
-
-    xs ?? ys  =  xs
-
-    xs ?? []  =  xs
-    xs ?? (x:ys)  =  xs ?? ys
-
-
-class of 2 equivalent candidates:
-
-    xs ?? ys  =  ys
-
-    [] ?? xs  =  xs
-    (x:xs) ?? ys  =  xs ?? ys
-
-
-class of 22 equivalent candidates:
-
-    xs ?? ys  =  []
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  xs ?? ys
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  ys ?? xs
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  ys ?? ys
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  [] ?? xs
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  [] ?? ys
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  xs ?? xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  xs ?? ys
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  xs ?? []
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  ys ?? xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  ys ?? []
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs ?? xs
-    (x:xs) ?? (y:ys)  =  []
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs ?? []
-    (x:xs) ?? (y:ys)  =  []
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs ?? xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs ?? ys
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs ?? []
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys ?? xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys ?? ys
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys ?? []
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs ?? xs
-    (x:xs) ?? ys  =  []
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs ?? []
-    (x:xs) ?? ys  =  []
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  [] ?? xs
-    (x:xs) ?? ys  =  []
-
-
-class of 5 equivalent candidates:
-
-    xs ?? []  =  xs
-    xs ?? (x:ys)  =  []
-
-    xs ?? []  =  xs
-    xs ?? (x:ys)  =  ys ?? ys
-
-    xs ?? []  =  xs
-    xs ?? (x:ys)  =  [] ?? xs
-
-    xs ?? []  =  xs
-    xs ?? (x:ys)  =  [] ?? ys
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  x:xs
-    (x:xs) ?? (y:ys)  =  []
-
-
-class of 2 equivalent candidates:
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  x:xs
-
-
-class of 3 equivalent candidates:
-
-    xs ?? []  =  []
-    xs ?? (x:ys)  =  ys
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  xs ?? ys
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  [] ?? ys
-
-
-class of 10 equivalent candidates:
-
-    [] ?? xs  =  xs
-    (x:xs) ?? ys  =  []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? ys  =  xs ?? xs
-
-    [] ?? xs  =  xs
-    (x:xs) ?? ys  =  xs ?? []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? ys  =  ys ?? []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs ?? xs
-    (x:xs) ?? (y:ys)  =  []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs ?? []
-    (x:xs) ?? (y:ys)  =  []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs ?? xs
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs ?? []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys ?? ys
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys ?? []
-
-
-class of 2 equivalent candidates:
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  xs
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  [] ?? xs
-    (x:xs) ?? ys  =  xs
-
-
-class of 3 equivalent candidates:
-
-    [] ?? xs  =  []
-    (x:xs) ?? ys  =  ys
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs ?? []
-    (x:xs) ?? ys  =  ys
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  [] ?? xs
-    (x:xs) ?? ys  =  ys
-
-
-class of 3 equivalent candidates:
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  []
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  xs ?? xs
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  ys ?? ys
-
-
-class of 2 equivalent candidates:
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs ?? []
-    (x:xs) ?? (y:ys)  =  xs
-
-
-class of 2 equivalent candidates:
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs ?? []
-    (x:xs) ?? (y:ys)  =  ys
-
-
-class of 3 equivalent candidates:
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  []
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  xs ?? xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  ys ?? ys
-
-
-class of 2 equivalent candidates:
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  xs
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs ?? []
-    (x:xs) ?? (y:ys)  =  xs
-
-
-class of 2 equivalent candidates:
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  []
-    (x:xs) ?? (y:ys)  =  ys
-
-    [] ?? xs  =  []
-    (x:xs) ?? []  =  xs ?? []
-    (x:xs) ?? (y:ys)  =  ys
-
-
-class of 2 equivalent candidates:
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  ys
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs ?? xs
-    (x:xs) ?? ys  =  ys
-
-
-class of 4 equivalent candidates:
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  []
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  xs ?? xs
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  xs ?? []
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs
-    (x:xs) ?? ys  =  ys ?? []
-
-
-class of 2 equivalent candidates:
-
-    [] ?? xs  =  xs
-    (x:xs) ?? ys  =  ys ?? xs
-
-    [] ?? xs  =  xs
-    (x:xs) ?? []  =  xs
-    (x:xs) ?? (y:ys)  =  xs ?? ys
-
-
-class of 2 equivalent candidates:
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs ?? xs
-    (x:xs) ?? ys  =  xs
-
-    [] ?? []  =  []
-    [] ?? (x:xs)  =  xs ?? []
-    (x:xs) ?? ys  =  xs
-
-
-
-Redundant candidates for: ton :: Bool -> Bool
-  pruning with 39/49 rules
-  [3,2,0,0,0] candidates
-  4/5 unique candidates
-  1/5 redundant candidates
-
-rules:
-not False == True
-not True == False
-p && p == p
-p || p == p
-not (not p) == p
-p && False == False
-p && True == p
-False && p == False
-True && p == p
-p || False == p
-p || True == True
-False || p == p
-True || p == True
-not (p && q) == not p || not q
-not (p && q) == not q || not p
-not (p || q) == not p && not q
-not (p || q) == not q && not p
-p && not p == False
-not p && p == False
-p || not p == True
-not p || p == True
-(p && q) && r == p && (q && r)
-(p && q) && r == q && (p && r)
-(p || q) || r == p || (q || r)
-(p || q) || r == q || (p || r)
-p && (p && q) == p && q
-p && (q && p) == p && q
-p && (q && p) == q && p
-p || (p || q) == p || q
-p || (q || p) == p || q
-p || (q || p) == q || p
-p && (p || q) == p
-p && (q || p) == p
-(p || q) && p == p
-(p || q) && q == q
-p || p && q == p
-p || q && p == p
-p && q || p == p
-p && q || q == q
-equations:
-q && p == p && q
-q || p == p || q
-q && (p && r) == p && (q && r)
-r && (p && q) == p && (q && r)
-r && (q && p) == p && (q && r)
-q || (p || r) == p || (q || r)
-r || (p || q) == p || (q || r)
-r || (q || p) == p || (q || r)
-(r || q) && p == p && (q || r)
-r && q || p == p || q && r
-
-class of 2 equivalent candidates:
-
-    ton p  =  not p
-
-    ton False  =  True
-    ton True  =  False
-
-
-
-Redundant candidates for: &| :: Bool -> Bool -> Bool
-  pruning with 39/49 rules
-  [4,12,20,6,2] candidates
-  16/44 unique candidates
-  28/44 redundant candidates
-
-rules:
-not False == True
-not True == False
-p && p == p
-p || p == p
-not (not p) == p
-p && False == False
-p && True == p
-False && p == False
-True && p == p
-p || False == p
-p || True == True
-False || p == p
-True || p == True
-not (p && q) == not p || not q
-not (p && q) == not q || not p
-not (p || q) == not p && not q
-not (p || q) == not q && not p
-p && not p == False
-not p && p == False
-p || not p == True
-not p || p == True
-(p && q) && r == p && (q && r)
-(p && q) && r == q && (p && r)
-(p || q) || r == p || (q || r)
-(p || q) || r == q || (p || r)
-p && (p && q) == p && q
-p && (q && p) == p && q
-p && (q && p) == q && p
-p || (p || q) == p || q
-p || (q || p) == p || q
-p || (q || p) == q || p
-p && (p || q) == p
-p && (q || p) == p
-(p || q) && p == p
-(p || q) && q == q
-p || p && q == p
-p || q && p == p
-p && q || p == p
-p && q || q == q
-equations:
-q && p == p && q
-q || p == p || q
-q && (p && r) == p && (q && r)
-r && (p && q) == p && (q && r)
-r && (q && p) == p && (q && r)
-q || (p || r) == p || (q || r)
-r || (p || q) == p || (q || r)
-r || (q || p) == p || (q || r)
-(r || q) && p == p && (q || r)
-r && q || p == p || q && r
-
-class of 2 equivalent candidates:
-
-    p &| q  =  not p
-
-    False &| p  =  True
-    True &| p  =  False
-
-
-class of 4 equivalent candidates:
-
-    p &| q  =  not q
-
-    p &| False  =  True
-    p &| True  =  False
-
-    False &| p  =  not p
-    True &| False  =  True
-    True &| True  =  False
-
-    False &| False  =  True
-    False &| True  =  False
-    True &| p  =  not p
-
-
-class of 4 equivalent candidates:
-
-    p &| False  =  p
-    p &| True  =  False
-
-    False &| p  =  False
-    True &| p  =  not p
-
-    False &| p  =  False
-    True &| False  =  True
-    True &| True  =  False
-
-    p &| q  =  p && not q
-
-
-class of 3 equivalent candidates:
-
-    p &| False  =  p
-    p &| True  =  True
-
-    False &| p  =  p
-    True &| p  =  True
-
-    p &| q  =  p || q
-
-
-class of 3 equivalent candidates:
-
-    p &| False  =  False
-    p &| True  =  p
-
-    False &| p  =  False
-    True &| p  =  p
-
-    p &| q  =  p && q
-
-
-class of 4 equivalent candidates:
-
-    p &| False  =  True
-    p &| True  =  p
-
-    False &| p  =  not p
-    True &| p  =  True
-
-    False &| False  =  True
-    False &| True  =  False
-    True &| p  =  True
-
-    p &| q  =  p || not q
-
-
-class of 3 equivalent candidates:
-
-    False &| p  =  p
-    True &| p  =  False
-
-    p &| False  =  False
-    p &| True  =  not p
-
-    p &| q  =  q && not p
-
-
-class of 3 equivalent candidates:
-
-    False &| p  =  True
-    True &| p  =  p
-
-    p &| False  =  not p
-    p &| True  =  True
-
-    p &| q  =  q || not p
-
-
-class of 3 equivalent candidates:
-
-    p &| False  =  p
-    p &| True  =  not p
-
-    False &| p  =  p
-    True &| p  =  not p
-
-    False &| p  =  p
-    True &| False  =  True
-    True &| True  =  False
-
-
-class of 4 equivalent candidates:
-
-    p &| False  =  True
-    p &| True  =  not p
-
-    False &| p  =  True
-    True &| p  =  not p
-
-    False &| p  =  True
-    True &| False  =  True
-    True &| True  =  False
-
-    p &| q  =  not p || not q
-
-
-class of 3 equivalent candidates:
-
-    p &| False  =  not p
-    p &| True  =  p
-
-    False &| p  =  not p
-    True &| p  =  p
-
-    False &| False  =  True
-    False &| True  =  False
-    True &| p  =  p
-
-
-class of 4 equivalent candidates:
-
-    p &| False  =  not p
-    p &| True  =  False
-
-    False &| p  =  not p
-    True &| p  =  False
-
-    False &| False  =  True
-    False &| True  =  False
-    True &| p  =  False
-
-    p &| q  =  not p && not q
-
-
-
diff --git a/bench/redundants.txt b/bench/redundants.txt
new file mode 100644
--- /dev/null
+++ b/bench/redundants.txt
@@ -0,0 +1,1990 @@
+Redundant candidates for: foo :: Int -> Int
+  pruning with 15/35 rules
+  [3,3,8,9,21,27] candidates
+  63/71 unique candidates
+  8/71 redundant candidates
+
+rules:
+x * y == x + y
+x * y == y + x
+x - x == 0
+x + 0 == x
+0 + x == x
+x - 0 == x
+(x + y) + z == x + (y + z)
+(x + y) + z == y + (x + z)
+x - (y - z) == z + (x - y)
+(x - y) - z == x - (y + z)
+(x - y) - z == x - (z + y)
+(x + y) - z == x + (y - z)
+(x + y) - z == y + (x - z)
+x + (y - x) == y
+(x - y) + y == x
+equations:
+y + x == x + y
+y + (x + z) == x + (y + z)
+z + (x + y) == x + (y + z)
+z + (y + x) == x + (y + z)
+y + (x - z) == x + (y - z)
+(x - z) + y == x + (y - z)
+(z - y) + x == (x - y) + z
+y - (x + y) == 0 - x
+y - (y + x) == 0 - x
+z - (y + z) == x - (x + y)
+z - (y + z) == x - (y + x)
+z - (z + y) == x - (x + y)
+z - (z + y) == x - (y + x)
+x + (0 - y) == x - y
+(0 - y) + x == x - y
+x - (x + 1) == 0 - 1
+x - (1 + x) == 0 - 1
+y - (y + 1) == x - (x + 1)
+y - (y + 1) == x - (1 + x)
+y - (1 + y) == x - (1 + x)
+
+class of 3 equivalent candidates:
+
+    foo x  =  0 - x
+
+    foo x  =  x - (x + x)
+
+    foo x  =  1 - (x + 1)
+
+
+class of 2 equivalent candidates:
+
+    foo x  =  1 - x
+
+    foo x  =  1 + (0 - x)
+
+
+class of 2 equivalent candidates:
+
+    foo 0  =  0
+    foo x  =  1 - x
+
+    foo 0  =  0
+    foo x  =  1 + (0 - x)
+
+
+class of 3 equivalent candidates:
+
+    foo 0  =  1
+    foo x  =  0 - x
+
+    foo 0  =  1
+    foo x  =  x - (x + x)
+
+    foo 0  =  1
+    foo x  =  1 - (x + 1)
+
+
+class of 2 equivalent candidates:
+
+    foo x  =  x + (x + 1)
+
+    foo x  =  1 + (x + x)
+
+
+class of 2 equivalent candidates:
+
+    foo 0  =  0
+    foo x  =  x + (x + 1)
+
+    foo 0  =  0
+    foo x  =  1 + (x + x)
+
+
+
+Redundant candidates for: ? :: Int -> Int -> Int
+  pruning with 10/23 rules
+  [3,8,22,50,116,302] candidates
+  410/501 unique candidates
+  91/501 redundant candidates
+
+rules:
+x * y == x + y
+x * y == y + x
+x + 0 == x
+0 + x == x
+dec (x + y) == x + dec y
+dec (x + y) == y + dec x
+dec (x + y) == dec x + y
+dec (x + y) == dec y + x
+(x + y) + z == x + (y + z)
+(x + y) + z == y + (x + z)
+equations:
+y + x == x + y
+y + dec x == x + dec y
+dec x + y == x + dec y
+dec y + x == dec x + y
+x + dec 0 == dec x
+dec 0 + x == dec x
+y + (x + z) == x + (y + z)
+z + (x + y) == x + (y + z)
+z + (y + x) == x + (y + z)
+y + dec (dec x) == x + dec (dec y)
+dec (dec x) + y == x + dec (dec y)
+x + dec (dec 0) == dec (dec x)
+dec (dec 0) + x == dec (dec x)
+
+class of 3 equivalent candidates:
+
+    x ? y  =  x
+
+    x ? 0  =  x
+    x ? y  =  x ? dec y
+
+    0 ? x  =  0
+    x ? 0  =  x
+    x ? y  =  x ? dec y
+
+
+class of 3 equivalent candidates:
+
+    x ? y  =  y
+
+    0 ? x  =  x
+    x ? y  =  dec x ? y
+
+    0 ? x  =  x
+    x ? 0  =  0
+    x ? y  =  dec x ? y
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  dec x
+
+    x ? 0  =  dec x
+    x ? y  =  x ? dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  dec y
+
+    0 ? x  =  dec x
+    x ? y  =  dec x ? y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  y
+
+    0 ? x  =  x
+    x ? 0  =  x
+    x ? y  =  dec x ? y
+
+
+class of 6 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  0
+
+    x ? 0  =  x
+    x ? y  =  0 ? dec y
+
+    x ? 0  =  x
+    x ? y  =  dec y ? dec y
+
+    0 ? x  =  0
+    x ? 0  =  x
+    x ? y  =  dec x ? x
+
+    0 ? x  =  0
+    x ? 0  =  x
+    x ? y  =  dec x ? y
+
+    0 ? x  =  0
+    x ? 0  =  x
+    x ? y  =  dec y ? x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  x
+
+    0 ? x  =  x
+    x ? 0  =  x
+    x ? y  =  x ? dec y
+
+
+class of 6 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  0
+
+    0 ? x  =  x
+    x ? y  =  dec x ? 0
+
+    0 ? x  =  x
+    x ? y  =  dec x ? dec x
+
+    0 ? x  =  x
+    x ? 0  =  0
+    x ? y  =  x ? dec y
+
+    0 ? x  =  x
+    x ? 0  =  0
+    x ? y  =  y ? dec x
+
+    0 ? x  =  x
+    x ? 0  =  0
+    x ? y  =  y ? dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  dec x
+    x ? y  =  0
+
+    x ? 0  =  dec x
+    x ? y  =  y ? dec y
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  dec x
+    x ? y  =  0
+
+    0 ? x  =  dec x
+    x ? y  =  dec x ? x
+
+
+class of 4 equivalent candidates:
+
+    x ? y  =  x + dec y
+
+    x ? y  =  y + dec x
+
+    x ? 0  =  dec x
+    x ? y  =  x + dec y
+
+    0 ? x  =  dec x
+    x ? y  =  y + dec x
+
+
+class of 3 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  dec x ? y
+
+    x ? 0  =  x
+    x ? y  =  dec (dec x) ? y
+
+    x ? 0  =  x
+    x ? y  =  dec (dec x ? y)
+
+
+class of 3 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  x ? dec y
+
+    0 ? x  =  x
+    x ? y  =  x ? dec (dec y)
+
+    0 ? x  =  x
+    x ? y  =  dec (x ? dec y)
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  x + (x + y)
+
+    x ? y  =  y + (x + x)
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  x + (y + y)
+
+    x ? y  =  y + (x + y)
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  x + dec (dec x)
+
+    x ? y  =  dec x + dec x
+
+
+class of 3 equivalent candidates:
+
+    x ? y  =  x + dec (dec y)
+
+    x ? y  =  y + dec (dec x)
+
+    x ? y  =  dec x + dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  y + dec (dec y)
+
+    x ? y  =  dec y + dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  x + dec y
+
+    x ? 0  =  x
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  x + dec y
+
+    x ? 0  =  0
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  x + dec y
+
+    0 ? x  =  x
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  x + dec y
+
+    0 ? x  =  0
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  dec x ? dec y
+
+    x ? 0  =  x
+    x ? y  =  dec (x ? dec y)
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  dec x ? dec y
+
+    0 ? x  =  x
+    x ? y  =  dec (dec x ? y)
+
+
+class of 3 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  dec (x ? dec y)
+
+    x ? 0  =  0
+    x ? y  =  dec (y ? dec y)
+
+    x ? 0  =  0
+    x ? y  =  dec (0 ? dec y)
+
+
+class of 3 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  dec (dec x ? x)
+
+    0 ? x  =  0
+    x ? y  =  dec (dec x ? y)
+
+    0 ? x  =  0
+    x ? y  =  dec (dec x ? 0)
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? 0  =  x
+    x ? y  =  y ? dec y
+
+    0 ? x  =  x
+    x ? 0  =  x
+    x ? y  =  dec x ? x
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  x + dec (dec (dec x))
+
+    x ? y  =  dec x + dec (dec x)
+
+
+class of 4 equivalent candidates:
+
+    x ? y  =  x + dec (dec (dec y))
+
+    x ? y  =  y + dec (dec (dec x))
+
+    x ? y  =  dec x + dec (dec y)
+
+    x ? y  =  dec y + dec (dec x)
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  x + (x + dec x)
+
+    x ? y  =  dec x + (x + x)
+
+
+class of 5 equivalent candidates:
+
+    x ? y  =  x + (x + dec y)
+
+    x ? y  =  x + (y + dec x)
+
+    x ? y  =  y + (x + dec x)
+
+    x ? y  =  dec x + (x + y)
+
+    x ? y  =  dec y + (x + x)
+
+
+class of 5 equivalent candidates:
+
+    x ? y  =  x + (y + dec y)
+
+    x ? y  =  y + (x + dec y)
+
+    x ? y  =  y + (y + dec x)
+
+    x ? y  =  dec x + (y + y)
+
+    x ? y  =  dec y + (x + y)
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  y + dec (dec (dec y))
+
+    x ? y  =  dec y + dec (dec y)
+
+
+class of 2 equivalent candidates:
+
+    x ? y  =  y + (y + dec y)
+
+    x ? y  =  dec y + (y + y)
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  x + (x + y)
+
+    x ? 0  =  x
+    x ? y  =  y + (x + x)
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  x + dec (dec x)
+
+    x ? 0  =  x
+    x ? y  =  dec x + dec x
+
+
+class of 3 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  x + dec (dec y)
+
+    x ? 0  =  x
+    x ? y  =  y + dec (dec x)
+
+    x ? 0  =  x
+    x ? y  =  dec x + dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x
+    x ? y  =  y + dec (dec y)
+
+    x ? 0  =  x
+    x ? y  =  dec y + dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  x + (x + y)
+
+    x ? 0  =  0
+    x ? y  =  y + (x + x)
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  x + (y + y)
+
+    x ? 0  =  0
+    x ? y  =  y + (x + y)
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  x + dec (dec x)
+
+    x ? 0  =  0
+    x ? y  =  dec x + dec x
+
+
+class of 3 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  x + dec (dec y)
+
+    x ? 0  =  0
+    x ? y  =  y + dec (dec x)
+
+    x ? 0  =  0
+    x ? y  =  dec x + dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  0
+    x ? y  =  y + dec (dec y)
+
+    x ? 0  =  0
+    x ? y  =  dec y + dec y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x + dec (dec x)
+    x ? y  =  x
+
+    x ? 0  =  dec x + dec x
+    x ? y  =  x
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x + dec (dec x)
+    x ? y  =  y
+
+    x ? 0  =  dec x + dec x
+    x ? y  =  y
+
+
+class of 2 equivalent candidates:
+
+    x ? 0  =  x + dec (dec x)
+    x ? y  =  0
+
+    x ? 0  =  dec x + dec x
+    x ? y  =  0
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  x + (y + y)
+
+    0 ? x  =  x
+    x ? y  =  y + (x + y)
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  x + dec (dec x)
+
+    0 ? x  =  x
+    x ? y  =  dec x + dec x
+
+
+class of 3 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  x + dec (dec y)
+
+    0 ? x  =  x
+    x ? y  =  y + dec (dec x)
+
+    0 ? x  =  x
+    x ? y  =  dec x + dec y
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? y  =  y + dec (dec y)
+
+    0 ? x  =  x
+    x ? y  =  dec y + dec y
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  x + (x + y)
+
+    0 ? x  =  0
+    x ? y  =  y + (x + x)
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  x + (y + y)
+
+    0 ? x  =  0
+    x ? y  =  y + (x + y)
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  x + dec (dec x)
+
+    0 ? x  =  0
+    x ? y  =  dec x + dec x
+
+
+class of 3 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  x + dec (dec y)
+
+    0 ? x  =  0
+    x ? y  =  y + dec (dec x)
+
+    0 ? x  =  0
+    x ? y  =  dec x + dec y
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? y  =  y + dec (dec y)
+
+    0 ? x  =  0
+    x ? y  =  dec y + dec y
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x + dec (dec x)
+    x ? y  =  x
+
+    0 ? x  =  dec x + dec x
+    x ? y  =  x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x + dec (dec x)
+    x ? y  =  y
+
+    0 ? x  =  dec x + dec x
+    x ? y  =  y
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x + dec (dec x)
+    x ? y  =  0
+
+    0 ? x  =  dec x + dec x
+    x ? y  =  0
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? 0  =  x
+    x ? y  =  x + dec y
+
+    0 ? x  =  x
+    x ? 0  =  x
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  x
+    x ? 0  =  0
+    x ? y  =  x + dec y
+
+    0 ? x  =  x
+    x ? 0  =  0
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? 0  =  x
+    x ? y  =  x + dec y
+
+    0 ? x  =  0
+    x ? 0  =  x
+    x ? y  =  y + dec x
+
+
+class of 2 equivalent candidates:
+
+    0 ? x  =  0
+    x ? 0  =  0
+    x ? y  =  x + dec y
+
+    0 ? x  =  0
+    x ? 0  =  0
+    x ? y  =  y + dec x
+
+
+
+Redundant candidates for: goo :: [Int] -> [Int]
+  pruning with 4/4 rules
+  [2,1,1,2,4,7] candidates
+  15/17 unique candidates
+  2/17 redundant candidates
+
+rules:
+xs ++ [] == xs
+[] ++ xs == xs
+(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
+(x:xs) ++ ys == x:(xs ++ ys)
+
+class of 2 equivalent candidates:
+
+    goo xs  =  xs
+
+    goo []  =  []
+    goo (x:xs)  =  x:goo xs
+
+
+class of 2 equivalent candidates:
+
+    goo xs  =  []
+
+    goo []  =  []
+    goo (x:xs)  =  goo xs ++ goo xs
+
+
+
+Redundant candidates for: ?? :: [Int] -> [Int] -> [Int]
+  pruning with 4/4 rules
+  [3,8,15,43,122,264] candidates
+  325/455 unique candidates
+  130/455 redundant candidates
+
+rules:
+xs ++ [] == xs
+[] ++ xs == xs
+(xs ++ ys) ++ zs == xs ++ (ys ++ zs)
+(x:xs) ++ ys == x:(xs ++ ys)
+
+class of 9 equivalent candidates:
+
+    xs ?? ys  =  xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ++ [] ?? xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ++ [] ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [] ?? xs ++ xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [] ?? ys ++ xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  x:xs ?? xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  x:xs ?? ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  x:xs ?? []
+
+
+class of 9 equivalent candidates:
+
+    xs ?? ys  =  ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  x:xs ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  x:ys ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  x:[] ?? ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ++ xs ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ++ ys ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? [] ++ ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ?? [] ++ ys
+
+
+class of 6 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  []
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [] ?? xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [] ?? ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  x:xs
+    (x:xs) ?? (y:ys)  =  []
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  (ys ++ ys) ?? ys
+
+
+class of 6 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  x:xs
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  xs ++ [] ?? xs
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  xs ++ [] ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  [] ?? xs ++ xs
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  [] ?? ys ++ xs
+
+
+class of 3 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  xs ?? ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  [] ?? ys
+
+
+class of 11 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs ?? xs
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs ?? []
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  xs ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  xs ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  ys ?? ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  ys ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? (xs ++ xs)
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  [] ?? xs
+    (x:xs) ?? ys  =  xs
+
+
+class of 7 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? []
+    (x:xs) ?? ys  =  ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  [] ?? xs
+    (x:xs) ?? ys  =  ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys ++ xs ?? []
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys ++ ys ?? []
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ?? [] ++ ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys ?? [] ++ ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? ys  =  xs ++ xs
+
+    xs ?? []  =  xs ++ xs
+    xs ?? (x:ys)  =  xs ?? ys
+
+
+class of 4 equivalent candidates:
+
+    xs ?? ys  =  xs ++ ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:xs ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ++ (x:ys)
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:(xs ++ ys)
+
+
+class of 4 equivalent candidates:
+
+    xs ?? ys  =  ys ++ xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:xs ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:(ys ++ xs)
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ++ (x:xs)
+
+
+class of 2 equivalent candidates:
+
+    xs ?? ys  =  ys ++ ys
+
+    [] ?? xs  =  xs ++ xs
+    (x:xs) ?? ys  =  xs ?? ys
+
+
+class of 3 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs ?? []
+    (x:xs) ?? (y:ys)  =  xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs ?? []
+    (x:xs) ?? (y:ys)  =  ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  [] ?? xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys
+
+
+class of 5 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  [] ?? xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  []
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs ?? []
+    (x:xs) ?? (y:ys)  =  xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs ?? []
+    (x:xs) ?? (y:ys)  =  ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? xs
+    (x:xs) ?? ys  =  ys
+
+
+class of 6 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  xs ?? xs
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  xs ?? []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? ys  =  ys ?? []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs ?? xs
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs ?? []
+    (x:xs) ?? (y:ys)  =  []
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? ys
+
+
+class of 3 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:ys ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:[] ?? ys
+
+
+class of 4 equivalent candidates:
+
+    xs ?? []  =  xs ++ xs
+    xs ?? (x:ys)  =  []
+
+    xs ?? []  =  xs ++ xs
+    xs ?? (x:ys)  =  ys ?? ys
+
+    xs ?? []  =  xs ++ xs
+    xs ?? (x:ys)  =  [] ?? xs
+
+    xs ?? []  =  xs ++ xs
+    xs ?? (x:ys)  =  [] ?? ys
+
+
+class of 3 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:xs ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:xs ?? []
+
+
+class of 4 equivalent candidates:
+
+    [] ?? xs  =  xs ++ xs
+    (x:xs) ?? ys  =  []
+
+    [] ?? xs  =  xs ++ xs
+    (x:xs) ?? ys  =  xs ?? xs
+
+    [] ?? xs  =  xs ++ xs
+    (x:xs) ?? ys  =  xs ?? []
+
+    [] ?? xs  =  xs ++ xs
+    (x:xs) ?? ys  =  ys ?? []
+
+
+class of 3 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? xs
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? []
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? []
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? xs
+    (x:xs) ?? ys  =  xs
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? []
+    (x:xs) ?? ys  =  xs
+
+
+class of 4 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ++ ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ++ xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ++ ys ?? []
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ?? [] ++ xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  xs ++ ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  ys ++ xs
+
+
+class of 4 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ++ ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ++ xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ++ ys ?? []
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys ?? [] ++ xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  xs ++ ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? []  =  []
+    (x:xs) ?? (y:ys)  =  ys ++ xs
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  (x:ys) ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [x] ?? ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  (xs ++ ys) ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ++ ys ?? ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  (ys ++ xs) ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ?? ys ++ xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? (x:xs)
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? [x]
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? (xs ++ ys)
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? xs ++ ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? (ys ++ xs)
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ++ xs ?? xs
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:ys ?? xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  x:(xs ++ ys)
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ++ xs ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  xs ?? ys ++ xs
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ++ ys ?? xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ?? xs ++ ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ++ ys ?? ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ++ [] ?? ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ++ [] ?? xs
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [] ?? xs ++ ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  ys ?? ys ++ ys
+
+    xs ?? []  =  xs
+    xs ?? (x:ys)  =  [] ?? ys ++ ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  xs ++ xs ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  xs ?? ys ++ xs
+
+
+class of 3 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ++ xs ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ++ ys ?? ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ++ [] ?? ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ++ ys ?? xs
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ?? xs ++ ys
+
+
+class of 2 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ++ [] ?? xs
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  [] ?? xs ++ ys
+
+
+class of 3 equivalent candidates:
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  xs ?? ys ++ ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  ys ?? ys ++ ys
+
+    xs ?? []  =  []
+    xs ?? (x:ys)  =  [] ?? ys ++ ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:ys ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  x:(ys ++ xs)
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ++ xs ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ++ xs ?? []
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ++ ys ?? xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ?? xs ++ xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  ys ++ xs ?? ys
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? ys ++ ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? xs ++ xs
+
+    [] ?? xs  =  xs
+    (x:xs) ?? ys  =  xs ?? [] ++ xs
+
+
+class of 3 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ++ xs ?? xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ++ xs ?? ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ++ xs ?? []
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ++ ys ?? xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys ?? xs ++ xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  ys ++ xs ?? ys
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ?? ys ++ ys
+
+
+class of 3 equivalent candidates:
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ?? xs ++ xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ?? ys ++ xs
+
+    [] ?? xs  =  []
+    (x:xs) ?? ys  =  xs ?? [] ++ xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ?? []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  [] ?? xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ?? []
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  [] ?? ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs ?? xs
+    (x:xs) ?? (y:ys)  =  xs
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  [] ?? xs
+    (x:xs) ?? (y:ys)  =  xs
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs ?? []
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys
+
+
+class of 2 equivalent candidates:
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  xs ++ ys
+
+    [] ?? []  =  []
+    [] ?? (x:xs)  =  xs
+    (x:xs) ?? []  =  xs
+    (x:xs) ?? (y:ys)  =  ys ++ xs
+
+
+
+Redundant candidates for: ton :: Bool -> Bool
+  pruning with 39/49 rules
+  [3,2,0,0,0,0] candidates
+  4/5 unique candidates
+  1/5 redundant candidates
+
+rules:
+not False == True
+not True == False
+p && p == p
+p || p == p
+not (not p) == p
+p && False == False
+p && True == p
+False && p == False
+True && p == p
+p || False == p
+p || True == True
+False || p == p
+True || p == True
+not (p && q) == not p || not q
+not (p && q) == not q || not p
+not (p || q) == not p && not q
+not (p || q) == not q && not p
+p && not p == False
+not p && p == False
+p || not p == True
+not p || p == True
+(p && q) && r == p && (q && r)
+(p && q) && r == q && (p && r)
+(p || q) || r == p || (q || r)
+(p || q) || r == q || (p || r)
+p && (p && q) == p && q
+p && (q && p) == p && q
+p && (q && p) == q && p
+p || (p || q) == p || q
+p || (q || p) == p || q
+p || (q || p) == q || p
+p && (p || q) == p
+p && (q || p) == p
+(p || q) && p == p
+(p || q) && q == q
+p || p && q == p
+p || q && p == p
+p && q || p == p
+p && q || q == q
+equations:
+q && p == p && q
+q || p == p || q
+q && (p && r) == p && (q && r)
+r && (p && q) == p && (q && r)
+r && (q && p) == p && (q && r)
+q || (p || r) == p || (q || r)
+r || (p || q) == p || (q || r)
+r || (q || p) == p || (q || r)
+(r || q) && p == p && (q || r)
+r && q || p == p || q && r
+
+class of 2 equivalent candidates:
+
+    ton p  =  not p
+
+    ton False  =  True
+    ton True  =  False
+
+
+
+Redundant candidates for: &| :: Bool -> Bool -> Bool
+  pruning with 39/49 rules
+  [4,12,20,6,2,16] candidates
+  16/60 unique candidates
+  44/60 redundant candidates
+
+rules:
+not False == True
+not True == False
+p && p == p
+p || p == p
+not (not p) == p
+p && False == False
+p && True == p
+False && p == False
+True && p == p
+p || False == p
+p || True == True
+False || p == p
+True || p == True
+not (p && q) == not p || not q
+not (p && q) == not q || not p
+not (p || q) == not p && not q
+not (p || q) == not q && not p
+p && not p == False
+not p && p == False
+p || not p == True
+not p || p == True
+(p && q) && r == p && (q && r)
+(p && q) && r == q && (p && r)
+(p || q) || r == p || (q || r)
+(p || q) || r == q || (p || r)
+p && (p && q) == p && q
+p && (q && p) == p && q
+p && (q && p) == q && p
+p || (p || q) == p || q
+p || (q || p) == p || q
+p || (q || p) == q || p
+p && (p || q) == p
+p && (q || p) == p
+(p || q) && p == p
+(p || q) && q == q
+p || p && q == p
+p || q && p == p
+p && q || p == p
+p && q || q == q
+equations:
+q && p == p && q
+q || p == p || q
+q && (p && r) == p && (q && r)
+r && (p && q) == p && (q && r)
+r && (q && p) == p && (q && r)
+q || (p || r) == p || (q || r)
+r || (p || q) == p || (q || r)
+r || (q || p) == p || (q || r)
+(r || q) && p == p && (q || r)
+r && q || p == p || q && r
+
+class of 5 equivalent candidates:
+
+    p &| q  =  False
+
+    p &| q  =  p && (q && not p)
+
+    p &| q  =  q && (p && not q)
+
+    p &| q  =  not p && (p && q)
+
+    p &| q  =  not q && (p && q)
+
+
+class of 5 equivalent candidates:
+
+    p &| q  =  True
+
+    p &| q  =  p || (q || not p)
+
+    p &| q  =  q || (p || not q)
+
+    p &| q  =  not p || (p || q)
+
+    p &| q  =  not q || (p || q)
+
+
+class of 2 equivalent candidates:
+
+    p &| q  =  not p
+
+    False &| p  =  True
+    True &| p  =  False
+
+
+class of 4 equivalent candidates:
+
+    p &| q  =  not q
+
+    p &| False  =  True
+    p &| True  =  False
+
+    False &| p  =  not p
+    True &| False  =  True
+    True &| True  =  False
+
+    False &| False  =  True
+    False &| True  =  False
+    True &| p  =  not p
+
+
+class of 5 equivalent candidates:
+
+    p &| False  =  p
+    p &| True  =  False
+
+    False &| p  =  False
+    True &| p  =  not p
+
+    False &| p  =  False
+    True &| False  =  True
+    True &| True  =  False
+
+    p &| q  =  p && not q
+
+    p &| q  =  not q && (p || q)
+
+
+class of 5 equivalent candidates:
+
+    p &| False  =  p
+    p &| True  =  True
+
+    False &| p  =  p
+    True &| p  =  True
+
+    p &| q  =  p || q
+
+    p &| q  =  p || q && not p
+
+    p &| q  =  q || p && not q
+
+
+class of 5 equivalent candidates:
+
+    p &| False  =  False
+    p &| True  =  p
+
+    False &| p  =  False
+    True &| p  =  p
+
+    p &| q  =  p && q
+
+    p &| q  =  p && (q || not p)
+
+    p &| q  =  q && (p || not q)
+
+
+class of 5 equivalent candidates:
+
+    p &| False  =  True
+    p &| True  =  p
+
+    False &| p  =  not p
+    True &| p  =  True
+
+    False &| False  =  True
+    False &| True  =  False
+    True &| p  =  True
+
+    p &| q  =  p || not q
+
+    p &| q  =  not q || p && q
+
+
+class of 4 equivalent candidates:
+
+    False &| p  =  p
+    True &| p  =  False
+
+    p &| False  =  False
+    p &| True  =  not p
+
+    p &| q  =  q && not p
+
+    p &| q  =  not p && (p || q)
+
+
+class of 4 equivalent candidates:
+
+    False &| p  =  True
+    True &| p  =  p
+
+    p &| False  =  not p
+    p &| True  =  True
+
+    p &| q  =  q || not p
+
+    p &| q  =  not p || p && q
+
+
+class of 3 equivalent candidates:
+
+    p &| False  =  p
+    p &| True  =  not p
+
+    False &| p  =  p
+    True &| p  =  not p
+
+    False &| p  =  p
+    True &| False  =  True
+    True &| True  =  False
+
+
+class of 4 equivalent candidates:
+
+    p &| False  =  True
+    p &| True  =  not p
+
+    False &| p  =  True
+    True &| p  =  not p
+
+    False &| p  =  True
+    True &| False  =  True
+    True &| True  =  False
+
+    p &| q  =  not p || not q
+
+
+class of 3 equivalent candidates:
+
+    p &| False  =  not p
+    p &| True  =  p
+
+    False &| p  =  not p
+    True &| p  =  p
+
+    False &| False  =  True
+    False &| True  =  False
+    True &| p  =  p
+
+
+class of 4 equivalent candidates:
+
+    p &| False  =  not p
+    p &| True  =  False
+
+    False &| p  =  not p
+    True &| p  =  False
+
+    False &| False  =  True
+    False &| True  =  False
+    True &| p  =  False
+
+    p &| q  =  not p && not q
+
+
+
diff --git a/bench/runtime/lapmatrud/bench/candidates.runtime b/bench/runtime/lapmatrud/bench/candidates.runtime
--- a/bench/runtime/lapmatrud/bench/candidates.runtime
+++ b/bench/runtime/lapmatrud/bench/candidates.runtime
@@ -1,1 +1,1 @@
-8.0
+5.5
diff --git a/bench/runtime/lapmatrud/bench/gps.runtime b/bench/runtime/lapmatrud/bench/gps.runtime
--- a/bench/runtime/lapmatrud/bench/gps.runtime
+++ b/bench/runtime/lapmatrud/bench/gps.runtime
@@ -1,1 +1,1 @@
-15.1
+15.8
diff --git a/bench/runtime/lapmatrud/bench/gps2.runtime b/bench/runtime/lapmatrud/bench/gps2.runtime
--- a/bench/runtime/lapmatrud/bench/gps2.runtime
+++ b/bench/runtime/lapmatrud/bench/gps2.runtime
@@ -1,1 +1,1 @@
-12.3
+13.1
diff --git a/bench/runtime/lapmatrud/bench/ill-hit.runtime b/bench/runtime/lapmatrud/bench/ill-hit.runtime
--- a/bench/runtime/lapmatrud/bench/ill-hit.runtime
+++ b/bench/runtime/lapmatrud/bench/ill-hit.runtime
@@ -1,1 +1,1 @@
-0.5
+0.4
diff --git a/bench/runtime/lapmatrud/bench/redundants.runtime b/bench/runtime/lapmatrud/bench/redundants.runtime
--- a/bench/runtime/lapmatrud/bench/redundants.runtime
+++ b/bench/runtime/lapmatrud/bench/redundants.runtime
@@ -1,1 +1,1 @@
-1.9
+3.9
diff --git a/bench/runtime/lapmatrud/bench/terpret.runtime b/bench/runtime/lapmatrud/bench/terpret.runtime
--- a/bench/runtime/lapmatrud/bench/terpret.runtime
+++ b/bench/runtime/lapmatrud/bench/terpret.runtime
@@ -1,1 +1,1 @@
-7.2
+8.3
diff --git a/bench/runtime/lapmatrud/bench/weird.runtime b/bench/runtime/lapmatrud/bench/weird.runtime
--- a/bench/runtime/lapmatrud/bench/weird.runtime
+++ b/bench/runtime/lapmatrud/bench/weird.runtime
@@ -1,1 +1,1 @@
-2.8
+3.1
diff --git a/bench/runtime/lapmatrud/eg/bools.runtime b/bench/runtime/lapmatrud/eg/bools.runtime
--- a/bench/runtime/lapmatrud/eg/bools.runtime
+++ b/bench/runtime/lapmatrud/eg/bools.runtime
@@ -1,1 +1,1 @@
-1.8
+1.6
diff --git a/bench/runtime/lapmatrud/eg/count.runtime b/bench/runtime/lapmatrud/eg/count.runtime
--- a/bench/runtime/lapmatrud/eg/count.runtime
+++ b/bench/runtime/lapmatrud/eg/count.runtime
@@ -1,1 +1,1 @@
-0.5
+0.3
diff --git a/bench/runtime/lapmatrud/eg/dupos.runtime b/bench/runtime/lapmatrud/eg/dupos.runtime
--- a/bench/runtime/lapmatrud/eg/dupos.runtime
+++ b/bench/runtime/lapmatrud/eg/dupos.runtime
@@ -1,1 +1,1 @@
-3.6
+3.3
diff --git a/bench/runtime/lapmatrud/eg/factorial.runtime b/bench/runtime/lapmatrud/eg/factorial.runtime
--- a/bench/runtime/lapmatrud/eg/factorial.runtime
+++ b/bench/runtime/lapmatrud/eg/factorial.runtime
@@ -1,1 +1,1 @@
-1.3
+1.2
diff --git a/bench/runtime/lapmatrud/eg/fib01.runtime b/bench/runtime/lapmatrud/eg/fib01.runtime
--- a/bench/runtime/lapmatrud/eg/fib01.runtime
+++ b/bench/runtime/lapmatrud/eg/fib01.runtime
@@ -1,1 +1,1 @@
-2.4
+1.2
diff --git a/bench/runtime/lapmatrud/eg/fibonacci.runtime b/bench/runtime/lapmatrud/eg/fibonacci.runtime
--- a/bench/runtime/lapmatrud/eg/fibonacci.runtime
+++ b/bench/runtime/lapmatrud/eg/fibonacci.runtime
@@ -1,1 +1,1 @@
-3.7
+4.2
diff --git a/bench/runtime/lapmatrud/eg/pow.runtime b/bench/runtime/lapmatrud/eg/pow.runtime
--- a/bench/runtime/lapmatrud/eg/pow.runtime
+++ b/bench/runtime/lapmatrud/eg/pow.runtime
@@ -1,1 +1,1 @@
-4.7
+3.8
diff --git a/bench/runtime/lapmatrud/eg/sort.runtime b/bench/runtime/lapmatrud/eg/sort.runtime
--- a/bench/runtime/lapmatrud/eg/sort.runtime
+++ b/bench/runtime/lapmatrud/eg/sort.runtime
@@ -1,1 +1,1 @@
-1.1
+1.2
diff --git a/bench/runtime/lapmatrud/eg/spec.runtime b/bench/runtime/lapmatrud/eg/spec.runtime
--- a/bench/runtime/lapmatrud/eg/spec.runtime
+++ b/bench/runtime/lapmatrud/eg/spec.runtime
@@ -1,1 +1,1 @@
-0.6
+0.5
diff --git a/bench/runtime/lapmatrud/eg/subset.runtime b/bench/runtime/lapmatrud/eg/subset.runtime
--- a/bench/runtime/lapmatrud/eg/subset.runtime
+++ b/bench/runtime/lapmatrud/eg/subset.runtime
@@ -1,1 +1,1 @@
-0.5
+0.4
diff --git a/bench/runtime/lapmatrud/eg/tree.runtime b/bench/runtime/lapmatrud/eg/tree.runtime
--- a/bench/runtime/lapmatrud/eg/tree.runtime
+++ b/bench/runtime/lapmatrud/eg/tree.runtime
@@ -1,1 +1,1 @@
-1.2
+1.5
diff --git a/bench/runtime/lapmatrud/versions b/bench/runtime/lapmatrud/versions
--- a/bench/runtime/lapmatrud/versions
+++ b/bench/runtime/lapmatrud/versions
@@ -1,4 +1,4 @@
 GHC 9.0.2
-leancheck-1.0.0
-express-1.0.12
+leancheck-1.0.2
+express-1.0.14
 speculate-0.4.14
diff --git a/bench/runtime/zero/bench/candidates.runtime b/bench/runtime/zero/bench/candidates.runtime
--- a/bench/runtime/zero/bench/candidates.runtime
+++ b/bench/runtime/zero/bench/candidates.runtime
@@ -1,1 +1,1 @@
-10.0
+9.7
diff --git a/bench/runtime/zero/bench/erroneous.runtime b/bench/runtime/zero/bench/erroneous.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/bench/erroneous.runtime
@@ -0,0 +1,1 @@
+3.7
diff --git a/bench/runtime/zero/bench/gps.runtime b/bench/runtime/zero/bench/gps.runtime
--- a/bench/runtime/zero/bench/gps.runtime
+++ b/bench/runtime/zero/bench/gps.runtime
@@ -1,1 +1,1 @@
-28.4
+28.5
diff --git a/bench/runtime/zero/bench/gps2.runtime b/bench/runtime/zero/bench/gps2.runtime
--- a/bench/runtime/zero/bench/gps2.runtime
+++ b/bench/runtime/zero/bench/gps2.runtime
@@ -1,1 +1,1 @@
-22.6
+26.1
diff --git a/bench/runtime/zero/bench/p12.runtime b/bench/runtime/zero/bench/p12.runtime
--- a/bench/runtime/zero/bench/p12.runtime
+++ b/bench/runtime/zero/bench/p12.runtime
@@ -1,1 +1,1 @@
-3.1
+3.8
diff --git a/bench/runtime/zero/bench/redundants.runtime b/bench/runtime/zero/bench/redundants.runtime
--- a/bench/runtime/zero/bench/redundants.runtime
+++ b/bench/runtime/zero/bench/redundants.runtime
@@ -1,1 +1,1 @@
-2.7
+14.9
diff --git a/bench/runtime/zero/bench/terpret.runtime b/bench/runtime/zero/bench/terpret.runtime
--- a/bench/runtime/zero/bench/terpret.runtime
+++ b/bench/runtime/zero/bench/terpret.runtime
@@ -1,1 +1,1 @@
-15.1
+14.8
diff --git a/bench/runtime/zero/bench/weird.runtime b/bench/runtime/zero/bench/weird.runtime
--- a/bench/runtime/zero/bench/weird.runtime
+++ b/bench/runtime/zero/bench/weird.runtime
@@ -1,1 +1,1 @@
-5.1
+5.4
diff --git a/bench/runtime/zero/eg/bools.runtime b/bench/runtime/zero/eg/bools.runtime
--- a/bench/runtime/zero/eg/bools.runtime
+++ b/bench/runtime/zero/eg/bools.runtime
@@ -1,1 +1,1 @@
-3.1
+3.2
diff --git a/bench/runtime/zero/eg/bst.runtime b/bench/runtime/zero/eg/bst.runtime
--- a/bench/runtime/zero/eg/bst.runtime
+++ b/bench/runtime/zero/eg/bst.runtime
@@ -1,1 +1,1 @@
-13.9
+13.8
diff --git a/bench/runtime/zero/eg/count.runtime b/bench/runtime/zero/eg/count.runtime
--- a/bench/runtime/zero/eg/count.runtime
+++ b/bench/runtime/zero/eg/count.runtime
@@ -1,1 +1,1 @@
-0.7
+0.6
diff --git a/bench/runtime/zero/eg/dupos.runtime b/bench/runtime/zero/eg/dupos.runtime
--- a/bench/runtime/zero/eg/dupos.runtime
+++ b/bench/runtime/zero/eg/dupos.runtime
@@ -1,1 +1,1 @@
-7.4
+6.5
diff --git a/bench/runtime/zero/eg/either.runtime b/bench/runtime/zero/eg/either.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/either.runtime
@@ -0,0 +1,1 @@
+0.2
diff --git a/bench/runtime/zero/eg/fib01.runtime b/bench/runtime/zero/eg/fib01.runtime
--- a/bench/runtime/zero/eg/fib01.runtime
+++ b/bench/runtime/zero/eg/fib01.runtime
@@ -1,1 +1,1 @@
-2.3
+2.6
diff --git a/bench/runtime/zero/eg/fibonacci.runtime b/bench/runtime/zero/eg/fibonacci.runtime
--- a/bench/runtime/zero/eg/fibonacci.runtime
+++ b/bench/runtime/zero/eg/fibonacci.runtime
@@ -1,1 +1,1 @@
-8.2
+9.1
diff --git a/bench/runtime/zero/eg/higher.runtime b/bench/runtime/zero/eg/higher.runtime
--- a/bench/runtime/zero/eg/higher.runtime
+++ b/bench/runtime/zero/eg/higher.runtime
@@ -1,1 +1,1 @@
-1.2
+1.1
diff --git a/bench/runtime/zero/eg/maybe.runtime b/bench/runtime/zero/eg/maybe.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/maybe.runtime
@@ -0,0 +1,1 @@
+0.5
diff --git a/bench/runtime/zero/eg/oddeven.runtime b/bench/runtime/zero/eg/oddeven.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/oddeven.runtime
@@ -0,0 +1,1 @@
+2.8
diff --git a/bench/runtime/zero/eg/pow.runtime b/bench/runtime/zero/eg/pow.runtime
--- a/bench/runtime/zero/eg/pow.runtime
+++ b/bench/runtime/zero/eg/pow.runtime
@@ -1,1 +1,1 @@
-6.9
+7.4
diff --git a/bench/runtime/zero/eg/sort.runtime b/bench/runtime/zero/eg/sort.runtime
--- a/bench/runtime/zero/eg/sort.runtime
+++ b/bench/runtime/zero/eg/sort.runtime
@@ -1,1 +1,1 @@
-2.5
+2.7
diff --git a/bench/runtime/zero/eg/spec.runtime b/bench/runtime/zero/eg/spec.runtime
--- a/bench/runtime/zero/eg/spec.runtime
+++ b/bench/runtime/zero/eg/spec.runtime
@@ -1,1 +1,1 @@
-1.2
+1.1
diff --git a/bench/runtime/zero/versions b/bench/runtime/zero/versions
--- a/bench/runtime/zero/versions
+++ b/bench/runtime/zero/versions
@@ -1,4 +1,4 @@
 GHC 9.0.2
-leancheck-1.0.0
-express-1.0.12
+leancheck-1.0.2
+express-1.0.16
 speculate-0.4.14
diff --git a/bench/self.hs b/bench/self.hs
--- a/bench/self.hs
+++ b/bench/self.hs
@@ -1,6 +1,6 @@
 -- self.hs: conjuring functions through themselves
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/bench/self.out b/bench/self.out
deleted file mode 100644
--- a/bench/self.out
+++ /dev/null
@@ -1,36 +0,0 @@
-(?) :: Int -> Int -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 4 candidates of size 1
--- looking through 15 candidates of size 2
--- looking through 55 candidates of size 3
--- tested 21 candidates
-x ? y  =  x + y
-
-(?) :: Int -> Int -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 4 candidates of size 1
--- looking through 15 candidates of size 2
--- looking through 55 candidates of size 3
--- tested 33 candidates
-x ? y  =  x * y
-
-i :: Int -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 13 candidates of size 3
--- tested 8 candidates
-i x  =  x + 1
-
-d :: Int -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 12 candidates of size 3
--- tested 18 candidates
-cannot conjure
-
diff --git a/bench/self.txt b/bench/self.txt
new file mode 100644
--- /dev/null
+++ b/bench/self.txt
@@ -0,0 +1,36 @@
+(?) :: Int -> Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 4 candidates of size 1
+-- looking through 16 candidates of size 2
+-- looking through 56 candidates of size 3
+-- tested 22 candidates
+x ? y  =  x + y
+
+(?) :: Int -> Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 4 candidates of size 1
+-- looking through 16 candidates of size 2
+-- looking through 56 candidates of size 3
+-- tested 34 candidates
+x ? y  =  x * y
+
+i :: Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 13 candidates of size 3
+-- tested 8 candidates
+i x  =  x + 1
+
+d :: Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 12 candidates of size 3
+-- tested 18 candidates
+cannot conjure
+
diff --git a/bench/take-drop.out b/bench/take-drop.out
deleted file mode 100644
--- a/bench/take-drop.out
+++ /dev/null
@@ -1,32 +0,0 @@
-drop :: Int -> [A] -> [A]
--- testing 360 combinations of argument values
--- pruning with 4/7 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 9 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 28 candidates of size 6
--- looking through 50 candidates of size 7
--- tested 63 candidates
-drop 0 xs  =  xs
-drop x []  =  []
-drop x (y:xs)  =  drop (x - 1) xs
-
-take :: Int -> [A] -> [A]
--- testing 143 combinations of argument values
--- pruning with 14/21 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 9 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 28 candidates of size 6
--- looking through 50 candidates of size 7
--- looking through 83 candidates of size 8
--- looking through 133 candidates of size 9
--- tested 249 candidates
-take 0 xs  =  []
-take x []  =  []
-take x (y:xs)  =  y:take (x - 1) xs
-
diff --git a/bench/take-drop.txt b/bench/take-drop.txt
new file mode 100644
--- /dev/null
+++ b/bench/take-drop.txt
@@ -0,0 +1,32 @@
+drop :: Int -> [A] -> [A]
+-- testing 360 combinations of argument values
+-- pruning with 4/7 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 8 candidates of size 5
+-- looking through 13 candidates of size 6
+-- looking through 24 candidates of size 7
+-- tested 39 candidates
+drop 0 xs  =  xs
+drop x []  =  []
+drop x (y:xs)  =  drop (x - 1) xs
+
+take :: Int -> [A] -> [A]
+-- testing 143 combinations of argument values
+-- pruning with 14/21 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 8 candidates of size 5
+-- looking through 13 candidates of size 6
+-- looking through 24 candidates of size 7
+-- looking through 31 candidates of size 8
+-- looking through 59 candidates of size 9
+-- tested 111 candidates
+take 0 xs  =  []
+take x []  =  []
+take x (y:xs)  =  y:take (x - 1) xs
+
diff --git a/bench/terpret.hs b/bench/terpret.hs
--- a/bench/terpret.hs
+++ b/bench/terpret.hs
@@ -1,6 +1,6 @@
 -- terpret.hs: Benchmark execution-model problems from TerpreT
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 --
 -- You can find the description of these exercises on:
diff --git a/bench/terpret.out b/bench/terpret.out
deleted file mode 100644
--- a/bench/terpret.out
+++ /dev/null
@@ -1,172 +0,0 @@
-TerpreT benchmark #1: invert
-
-invert :: [Bool] -> [Bool]
--- testing 4 combinations of argument values
--- pruning with 41/51 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 10 candidates of size 4
--- looking through 17 candidates of size 5
--- looking through 41 candidates of size 6
--- tested 36 candidates
-invert []  =  []
-invert (p:ps)  =  not p:invert ps
-
-TerpreT benchmark #2: prepend zero
-
-prependZero :: [Bool] -> [Bool]
--- testing 3 combinations of argument values
--- pruning with 41/51 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 5 candidates of size 3
--- tested 5 candidates
-prependZero ps  =  False:ps
-
-TerpreT benchmark #3: binary decrement
-
-decrement :: [Bool] -> [Bool]
--- testing 3 combinations of argument values
--- pruning with 41/51 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 10 candidates of size 4
--- looking through 17 candidates of size 5
--- looking through 41 candidates of size 6
--- looking through 86 candidates of size 7
--- looking through 202 candidates of size 8
--- looking through 487 candidates of size 9
--- tested 418 candidates
-decrement []  =  []
-decrement (p:ps)  =  not p:(if p then ps else decrement ps)
-
-TerpreT benchmark #4: controlled shift
-
-cshift :: (Bool,Bool,Bool) -> (Bool,Bool,Bool)
--- testing 4 combinations of argument values
--- pruning with 41/51 rules
--- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 10 candidates of size 4
--- looking through 125 candidates of size 5
--- looking through 225 candidates of size 6
--- looking through 625 candidates of size 7
--- looking through 1242 candidates of size 8
--- looking through 3087 candidates of size 9
--- looking through 8937 candidates of size 10
--- looking through 102875 candidates of size 11
--- tested 40385 candidates
-cshift (p,q,r)  =  if p
-                   then (p,r,q)
-                   else (p,q,r)
-
-cshift :: Bool -> Bool -> Bool -> (Bool,Bool,Bool)
--- testing 4 combinations of argument values
--- pruning with 41/51 rules
--- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 125 candidates of size 4
--- looking through 225 candidates of size 5
--- looking through 585 candidates of size 6
--- looking through 1242 candidates of size 7
--- looking through 15183 candidates of size 8
--- tested 15459 candidates
-cshift False p q  =  (False,p,q)
-cshift True p q  =  (True,q,p)
-
-TerpreT benchmark #5: full adder
-
-fadder :: Bool -> Bool -> Bool -> (Bool,Bool)
--- testing 8 combinations of argument values
--- pruning with 18/22 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 9 candidates of size 3
--- looking through 18 candidates of size 4
--- looking through 27 candidates of size 5
--- looking through 72 candidates of size 6
--- looking through 245 candidates of size 7
--- looking through 663 candidates of size 8
--- tested 1034 candidates
-fadder False False False  =  (False,False)
-fadder False False True  =  (False,True)
-fadder False True False  =  (False,True)
-fadder False True True  =  (True,False)
-fadder True False False  =  (False,True)
-fadder True False True  =  (True,False)
-fadder True True False  =  (True,False)
-fadder True True True  =  (True,True)
-
-TerpreT benchmark #6: 2-bit adder
-
-adder2 :: (Bool,Bool) -> (Bool,Bool) -> (Bool,Bool,Bool)
--- testing 5 combinations of argument values
--- pruning with 74/92 rules
--- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 128 candidates of size 5
--- looking through 408 candidates of size 6
--- tested 544 candidates
-cannot conjure
-
-TerpreT benchmark #7: access
-
-access :: [A] -> Int -> A
--- testing 5 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 1 candidates of size 3
--- tested 1 candidates
-xs `access` x  =  xs !! x
-
-access :: [A] -> Int -> A
--- testing 5 combinations of argument values
--- pruning with 4/7 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 9 candidates of size 5
--- looking through 17 candidates of size 6
--- looking through 46 candidates of size 7
--- tested 46 candidates
-[] `access` x  =  undefined
-(x:xs) `access` 0  =  x
-(x:xs) `access` y  =  xs `access` (y - 1)
-
-TerpreT benchmark #8: decrement elements
-
-decrelements :: [Int] -> [Int]
--- testing 3 combinations of argument values
--- pruning with 3/23 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 7 candidates of size 4
--- looking through 9 candidates of size 5
--- looking through 29 candidates of size 6
--- looking through 41 candidates of size 7
--- tested 53 candidates
-decrelements []  =  []
-decrelements (x:xs)  =  x - 1:decrelements xs
-
-decrelements :: [Int] -> [Int]
--- testing 3 combinations of argument values
--- pruning with 5/26 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 8 candidates of size 4
--- tested 8 candidates
-decrelements xs  =  map (subtract 1) xs
-
diff --git a/bench/terpret.txt b/bench/terpret.txt
new file mode 100644
--- /dev/null
+++ b/bench/terpret.txt
@@ -0,0 +1,172 @@
+TerpreT benchmark #1: invert
+
+invert :: [Bool] -> [Bool]
+-- testing 4 combinations of argument values
+-- pruning with 41/51 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 15 candidates of size 5
+-- looking through 41 candidates of size 6
+-- tested 33 candidates
+invert []  =  []
+invert (p:ps)  =  not p:invert ps
+
+TerpreT benchmark #2: prepend zero
+
+prependZero :: [Bool] -> [Bool]
+-- testing 3 combinations of argument values
+-- pruning with 41/51 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- tested 4 candidates
+prependZero ps  =  False:ps
+
+TerpreT benchmark #3: binary decrement
+
+decrement :: [Bool] -> [Bool]
+-- testing 3 combinations of argument values
+-- pruning with 41/51 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 15 candidates of size 5
+-- looking through 41 candidates of size 6
+-- looking through 82 candidates of size 7
+-- looking through 202 candidates of size 8
+-- looking through 479 candidates of size 9
+-- tested 411 candidates
+decrement []  =  []
+decrement (p:ps)  =  not p:(if p then ps else decrement ps)
+
+TerpreT benchmark #4: controlled shift
+
+cshift :: (Bool,Bool,Bool) -> (Bool,Bool,Bool)
+-- testing 4 combinations of argument values
+-- pruning with 41/51 rules
+-- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 125 candidates of size 5
+-- looking through 225 candidates of size 6
+-- looking through 625 candidates of size 7
+-- looking through 1242 candidates of size 8
+-- looking through 3087 candidates of size 9
+-- looking through 8937 candidates of size 10
+-- looking through 102875 candidates of size 11
+-- tested 40385 candidates
+cshift (p,q,r)  =  if p
+                   then (p,r,q)
+                   else (p,q,r)
+
+cshift :: Bool -> Bool -> Bool -> (Bool,Bool,Bool)
+-- testing 4 combinations of argument values
+-- pruning with 41/51 rules
+-- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 125 candidates of size 4
+-- looking through 225 candidates of size 5
+-- looking through 585 candidates of size 6
+-- looking through 1242 candidates of size 7
+-- looking through 15183 candidates of size 8
+-- tested 15459 candidates
+cshift False p q  =  (False,p,q)
+cshift True p q  =  (True,q,p)
+
+TerpreT benchmark #5: full adder
+
+fadder :: Bool -> Bool -> Bool -> (Bool,Bool)
+-- testing 8 combinations of argument values
+-- pruning with 18/22 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 9 candidates of size 3
+-- looking through 18 candidates of size 4
+-- looking through 27 candidates of size 5
+-- looking through 72 candidates of size 6
+-- looking through 245 candidates of size 7
+-- looking through 663 candidates of size 8
+-- tested 1034 candidates
+fadder False False False  =  (False,False)
+fadder False False True  =  (False,True)
+fadder False True False  =  (False,True)
+fadder False True True  =  (True,False)
+fadder True False False  =  (False,True)
+fadder True False True  =  (True,False)
+fadder True True False  =  (True,False)
+fadder True True True  =  (True,True)
+
+TerpreT benchmark #6: 2-bit adder
+
+adder2 :: (Bool,Bool) -> (Bool,Bool) -> (Bool,Bool,Bool)
+-- testing 5 combinations of argument values
+-- pruning with 74/92 rules
+-- reasoning produced 2 incorrect properties, please re-run with more tests for faster results
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 8 candidates of size 4
+-- looking through 128 candidates of size 5
+-- looking through 408 candidates of size 6
+-- tested 544 candidates
+cannot conjure
+
+TerpreT benchmark #7: access
+
+access :: [A] -> Int -> A
+-- testing 5 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- tested 1 candidates
+xs `access` x  =  xs !! x
+
+access :: [A] -> Int -> A
+-- testing 5 combinations of argument values
+-- pruning with 4/7 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 6 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 19 candidates of size 7
+-- tested 18 candidates
+[] `access` x  =  undefined
+(x:xs) `access` 0  =  x
+(x:xs) `access` y  =  xs `access` (y - 1)
+
+TerpreT benchmark #8: decrement elements
+
+decrelements :: [Int] -> [Int]
+-- testing 3 combinations of argument values
+-- pruning with 3/23 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 7 candidates of size 4
+-- looking through 8 candidates of size 5
+-- looking through 29 candidates of size 6
+-- looking through 39 candidates of size 7
+-- tested 51 candidates
+decrelements []  =  []
+decrelements (x:xs)  =  x - 1:decrelements xs
+
+decrelements :: [Int] -> [Int]
+-- testing 3 combinations of argument values
+-- pruning with 5/26 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 8 candidates of size 4
+-- tested 7 candidates
+decrelements xs  =  map (subtract 1) xs
+
diff --git a/bench/time b/bench/time
--- a/bench/time
+++ b/bench/time
@@ -2,7 +2,7 @@
 #
 # bench/time: runs a program, discards stdout and print name and runtime
 #
-# Copyright (C) 2021 Rudy Matela
+# Copyright (C) 2021-2024 Rudy Matela
 # Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 printf "%-14s  " "$*"
diff --git a/bench/versions b/bench/versions
--- a/bench/versions
+++ b/bench/versions
@@ -2,7 +2,7 @@
 #
 # bench/versions: print versions of installed dependencies
 #
-# Copyright (C) 2021  Rudy Matela
+# Copyright (C) 2021-2024  Rudy Matela
 # Distributed under the 3-Clause BSD licence (see the file LICENSE).
 get-ghc-v() {
     ghc --version | sed -e "s/.* version/GHC/"
diff --git a/bench/weird.out b/bench/weird.out
deleted file mode 100644
--- a/bench/weird.out
+++ /dev/null
@@ -1,29 +0,0 @@
-(^^^) :: Int -> Int -> Int
--- testing 360 combinations of argument values
--- pruning with 56/91 rules
--- looking through 4 candidates of size 1
--- looking through 15 candidates of size 2
--- looking through 39 candidates of size 3
--- tested 36 candidates
-0 ^^^ x  =  x
-x ^^^ 0  =  x
-x ^^^ y  =  0
-
-(^^^) :: Int -> Int -> Int
--- testing 360 combinations of argument values
--- pruning with 56/91 rules
--- looking through 4 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 9 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 39 candidates of size 5
--- looking through 60 candidates of size 6
--- looking through 225 candidates of size 7
--- looking through 1056 candidates of size 8
--- looking through 1488 candidates of size 9
--- looking through 13020 candidates of size 10
--- tested 7148 candidates
-x ^^^ y  =  if 0 == x * y
-            then x + y
-            else 0
-
diff --git a/bench/weird.txt b/bench/weird.txt
new file mode 100644
--- /dev/null
+++ b/bench/weird.txt
@@ -0,0 +1,29 @@
+(^^^) :: Int -> Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 56/91 rules
+-- looking through 4 candidates of size 1
+-- looking through 16 candidates of size 2
+-- looking through 40 candidates of size 3
+-- tested 37 candidates
+0 ^^^ x  =  x
+x ^^^ 0  =  x
+x ^^^ y  =  0
+
+(^^^) :: Int -> Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 56/91 rules
+-- looking through 4 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 9 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 39 candidates of size 5
+-- looking through 60 candidates of size 6
+-- looking through 225 candidates of size 7
+-- looking through 1056 candidates of size 8
+-- looking through 1488 candidates of size 9
+-- looking through 13020 candidates of size 10
+-- tested 7148 candidates
+x ^^^ y  =  if 0 == x * y
+            then x + y
+            else 0
+
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -2,9 +2,27 @@
 ============================
 
 
-v0.5.8
-------
+v0.5.10 (February 2024)
+-----------------------
 
+* improve pruning of candidate functions;
+* `Conjure`: un-export experimental `equalModuloTesting`
+* `Conjure.Conjurable`: add `conjureListFor`, `conjureSizeFor` & `conjureGrounds`;
+* Reorganize internal modules
+* Add `Conjure.Defn.Redundancy` module for redundant candidates;
+* Add `Conjure.Defn.Test` module testing candidate definitions;
+* Add `Conjure.Reason` module for term-rewriting-based reasoning;
+* Add `Conjure.Red` module for recursive descent;
+* `Conjure.Expr`: add a few auxiliary functions
+* Move functions out of `Conjure.Engine` into new modules
+* add more examples and benchmarks;
+* improved testing of Conjure itself;
+* and several other improvements and fixes.
+
+
+v0.5.8 (January 2024)
+---------------------
+
 * prune redundant mutants using a few new rules
 * rework numeric recursion criteria
 * improve pretty-printing
@@ -14,8 +32,8 @@
 * bump Express requirement to v1.0.14 (bugfix)
 
 
-v0.5.6
-------
+v0.5.6 (November 2023)
+----------------------
 
 * `Conjure` module: no main API changes
 * `Conjure.Engine`: add `equalModuloTesting`
@@ -23,8 +41,8 @@
 * add `bench/redundants` that reports groups of redundant candidates
 
 
-v0.5.4
-------
+v0.5.4 (November 2023)
+----------------------
 
 This has been the "dev" version after v0.5.2
 for almost a couple of years:
@@ -36,8 +54,8 @@
 * add (but not use) `conjureSize` to `Conjurable`
 
 
-v0.5.2
-------
+v0.5.2 (March 2022)
+-------------------
 
 * show number of tested candidates
 * complete `Conjurable` derivation functions
@@ -46,8 +64,8 @@
   to allow computing the near upper/lower limit on pruning
 
 
-v0.5.0
-------
+v0.5.0 (September 2021)
+-----------------------
 
 * allow synthesizing/conjuring from properties with `conjureFromSpec`;
 * complete Haddock documentation;
@@ -56,8 +74,8 @@
 * Makefile: add targets to run GPS(2) and TerpreT benches.
 
 
-v0.4.4
-------
+v0.4.4 (September 2021)
+-----------------------
 
 * remove need for explicit deconstructions:
 	- use `-` and `1` instead of `dec`;
@@ -68,8 +86,8 @@
 * minor fixes in the README.
 
 
-v0.4.2
-------
+v0.4.2 (August 2021)
+--------------------
 
 * default to using top-level patterns on generated functions;
 * memoize function evaluation;
@@ -81,8 +99,8 @@
 * improve tests and benchmarks.
 
 
-v0.4.0
-------
+v0.4.0 (July 2021)
+------------------
 
 * background primitives are now provided with `pr` and `prim`.
 * report number of rules used in pruning
@@ -94,8 +112,8 @@
 * cleanup unused code
 
 
-v0.3.6
-------
+v0.3.6 (June 2021)
+------------------
 
 * add switch for descending recursions
   to allow generation of `gcd`
@@ -105,8 +123,8 @@
   at this point, the old names were misnomers.
 
 
-v0.3.4
-------
+v0.3.4 (June 2021)
+------------------
 
 * reallow recursions under `&&` and `||`
   (simplifies the generated `or`, `and`, `set` and `elem` functions)
@@ -117,8 +135,8 @@
 * add 4 new benchmarks: `count`, `gcd`, `tree` and `setelem`
 
 
-v0.3.2
-------
+v0.3.2 (June 2021)
+------------------
 
 * significant runtime reduction in several benchmarks, e.g.:
 	- take is now reachable in about 5 seconds
@@ -136,30 +154,30 @@
 	- add stub `Conjure.Constructors` module
 
 
-v0.3.0
-------
+v0.3.0 (May 2021)
+-----------------
 
 * only automatically include an `if` for the return type of the given function
 * add the `take-drop` benchmark
 * make bottom-up enumeration more type directed
 
 
-v0.2.8
-------
+v0.2.8 (May 2021)
+-----------------
 
 * export the `A`, `B`, `C`, `D`, `E` and `F` helper types
 
 
-v0.2.6
-------
+v0.2.6 (May 2021)
+-----------------
 
 * require Express v0.1.10 due to `hasHole` being now exported there
 * require Eq result on `conjure1`, `conjure2` and `conjure3`
 * code cleanup and more tests
 
 
-v0.2.4
-------
+v0.2.4 (May 2021)
+-----------------
 
 * allow conjuring from specifications in addition to partial definitions
   (`conjure1`, `conjure2`, `conjure3` and related functions)
@@ -170,21 +188,21 @@
 * add code-optional candidate nubbing and debug functions
 
 
-v0.2.2
-------
+v0.2.2 (May 2021)
+-----------------
 
 * by default, search for 60 argument combinations
   among 100000 enumerated combinations
 
 
-v0.2.0
-------
+v0.2.0 (May 2021)
+-----------------
 
 * search until 100% match is found and exit
 * other misc changes
 
 
-v0.1.2
-------
+v0.1.2 (April 2021)
+-------------------
 
 For the changelog of earlier versions, check the git commit history.
diff --git a/code-conjure.cabal b/code-conjure.cabal
--- a/code-conjure.cabal
+++ b/code-conjure.cabal
@@ -1,9 +1,9 @@
 -- Cabal file for the Conjure program generation library.
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 name:                code-conjure
-version:             0.5.8
+version:             0.5.10
 synopsis:            synthesize Haskell functions out of partial definitions
 description:
   Conjure is a tool that synthesizes Haskell functions out of partial definitions.
@@ -26,11 +26,11 @@
                   , Makefile
                   , bench/bench
                   , bench/*.hs
-                  , bench/*.out
+                  , bench/*.txt
                   , eg/*.hs
-                  , eg/*.out
+                  , eg/*.txt
                   , proto/*.hs
-                  , proto/*.out
+                  , proto/*.txt
                   , mk/All.hs
                   , mk/Toplibs.hs
                   , mk/depend.mk
@@ -49,6 +49,7 @@
                   , bench/runtime/lapmatrud/versions
                   , bench/versions
                   , bench/time
+                  , test/mk
                   , test/sdist
 tested-with: GHC==9.4
            , GHC==9.2
@@ -64,7 +65,7 @@
 source-repository this
   type:            git
   location:        https://github.com/rudymatela/conjure
-  tag:             v0.5.8
+  tag:             v0.5.10
 
 library
   exposed-modules: Conjure
@@ -75,12 +76,16 @@
                  , Conjure.Prim
                  , Conjure.Utils
                  , Conjure.Defn
+                 , Conjure.Defn.Redundancy
+                 , Conjure.Defn.Test
+                 , Conjure.Red
+                 , Conjure.Reason
   other-extensions: TemplateHaskell, CPP
   build-depends: base >= 4 && < 5
                , leancheck >= 1.0.0
                , template-haskell
                , speculate >= 0.4.14
-               , express >= 1.0.14
+               , express >= 1.0.16
   hs-source-dirs:      src
   default-language:    Haskell2010
 
@@ -119,6 +124,14 @@
 test-suite derive
   type:                exitcode-stdio-1.0
   main-is:             derive.hs
+  other-modules:       Test, Test.ListableExpr
+  hs-source-dirs:      test
+  build-depends:       base >= 4 && < 5, leancheck, express, speculate, code-conjure
+  default-language:    Haskell2010
+
+test-suite red
+  type:                exitcode-stdio-1.0
+  main-is:             red.hs
   other-modules:       Test, Test.ListableExpr
   hs-source-dirs:      test
   build-depends:       base >= 4 && < 5, leancheck, express, speculate, code-conjure
diff --git a/eg/arith.hs b/eg/arith.hs
--- a/eg/arith.hs
+++ b/eg/arith.hs
@@ -1,6 +1,6 @@
 -- arith.hs: conjuring simple non-recursive numeric functions
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/eg/arith.out b/eg/arith.out
deleted file mode 100644
--- a/eg/arith.out
+++ /dev/null
@@ -1,62 +0,0 @@
-double :: Int -> Int
--- testing 4 combinations of argument values
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 6 candidates of size 3
--- tested 5 candidates
-double x  =  x + x
-
-triple :: Int -> Int
--- testing 4 combinations of argument values
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 11 candidates of size 5
--- tested 15 candidates
-triple x  =  x + (x + x)
-
-add :: Int -> Int -> Int
--- testing 4 combinations of argument values
--- pruning with 14/25 rules
--- looking through 4 candidates of size 1
--- looking through 15 candidates of size 2
--- looking through 39 candidates of size 3
--- tested 21 candidates
-add x y  =  x + y
-
-square :: Int -> Int
--- testing 3 combinations of argument values
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 4 candidates of size 3
--- tested 7 candidates
-square x  =  x * x
-
-cube :: Int -> Int
--- testing 3 combinations of argument values
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 11 candidates of size 5
--- tested 19 candidates
-cube x  =  x * (x * x)
-
-tnpo :: Int -> Int
--- testing 3 combinations of argument values
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 5 candidates of size 4
--- looking through 11 candidates of size 5
--- looking through 11 candidates of size 6
--- looking through 35 candidates of size 7
--- tested 40 candidates
-tnpo x  =  x + (x + (x + 1))
-
diff --git a/eg/arith.txt b/eg/arith.txt
new file mode 100644
--- /dev/null
+++ b/eg/arith.txt
@@ -0,0 +1,62 @@
+double :: Int -> Int
+-- testing 4 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 6 candidates of size 3
+-- tested 5 candidates
+double x  =  x + x
+
+triple :: Int -> Int
+-- testing 4 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 11 candidates of size 5
+-- tested 13 candidates
+triple x  =  x + (x + x)
+
+add :: Int -> Int -> Int
+-- testing 4 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 4 candidates of size 1
+-- looking through 16 candidates of size 2
+-- looking through 40 candidates of size 3
+-- tested 22 candidates
+add x y  =  x + y
+
+square :: Int -> Int
+-- testing 3 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- tested 7 candidates
+square x  =  x * x
+
+cube :: Int -> Int
+-- testing 3 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 10 candidates of size 5
+-- tested 17 candidates
+cube x  =  x * (x * x)
+
+tnpo :: Int -> Int
+-- testing 3 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 11 candidates of size 5
+-- looking through 7 candidates of size 6
+-- looking through 35 candidates of size 7
+-- tested 35 candidates
+tnpo x  =  x + (x + (x + 1))
+
diff --git a/eg/bools.hs b/eg/bools.hs
--- a/eg/bools.hs
+++ b/eg/bools.hs
@@ -1,6 +1,6 @@
 -- bools.hs: simple recursive functions over boolean lists
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/eg/bools.out b/eg/bools.out
deleted file mode 100644
--- a/eg/bools.out
+++ /dev/null
@@ -1,44 +0,0 @@
-and :: [Bool] -> Bool
--- testing 14 combinations of argument values
--- pruning with 37/47 rules
--- looking through 2 candidates of size 1
--- looking through 6 candidates of size 2
--- looking through 12 candidates of size 3
--- looking through 16 candidates of size 4
--- looking through 28 candidates of size 5
--- tested 42 candidates
-and []  =  True
-and (p:ps)  =  p && and ps
-
-or :: [Bool] -> Bool
--- testing 14 combinations of argument values
--- pruning with 37/47 rules
--- looking through 2 candidates of size 1
--- looking through 6 candidates of size 2
--- looking through 12 candidates of size 3
--- looking through 16 candidates of size 4
--- looking through 28 candidates of size 5
--- tested 39 candidates
-or []  =  False
-or (p:ps)  =  p || or ps
-
-and :: [Bool] -> Bool
--- testing 14 combinations of argument values
--- pruning with 40/50 rules
--- looking through 2 candidates of size 1
--- looking through 6 candidates of size 2
--- looking through 12 candidates of size 3
--- looking through 18 candidates of size 4
--- tested 28 candidates
-and ps  =  foldr (&&) True ps
-
-or :: [Bool] -> Bool
--- testing 14 combinations of argument values
--- pruning with 40/50 rules
--- looking through 2 candidates of size 1
--- looking through 6 candidates of size 2
--- looking through 12 candidates of size 3
--- looking through 18 candidates of size 4
--- tested 27 candidates
-or ps  =  foldr (||) False ps
-
diff --git a/eg/bools.txt b/eg/bools.txt
new file mode 100644
--- /dev/null
+++ b/eg/bools.txt
@@ -0,0 +1,44 @@
+and :: [Bool] -> Bool
+-- testing 14 combinations of argument values
+-- pruning with 37/47 rules
+-- looking through 2 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 10 candidates of size 3
+-- looking through 14 candidates of size 4
+-- looking through 28 candidates of size 5
+-- tested 38 candidates
+and []  =  True
+and (p:ps)  =  p && and ps
+
+or :: [Bool] -> Bool
+-- testing 14 combinations of argument values
+-- pruning with 37/47 rules
+-- looking through 2 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 10 candidates of size 3
+-- looking through 14 candidates of size 4
+-- looking through 28 candidates of size 5
+-- tested 35 candidates
+or []  =  False
+or (p:ps)  =  p || or ps
+
+and :: [Bool] -> Bool
+-- testing 14 combinations of argument values
+-- pruning with 40/50 rules
+-- looking through 2 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 10 candidates of size 3
+-- looking through 16 candidates of size 4
+-- tested 24 candidates
+and ps  =  foldr (&&) True ps
+
+or :: [Bool] -> Bool
+-- testing 14 combinations of argument values
+-- pruning with 40/50 rules
+-- looking through 2 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 10 candidates of size 3
+-- looking through 16 candidates of size 4
+-- tested 23 candidates
+or ps  =  foldr (||) False ps
+
diff --git a/eg/bst.hs b/eg/bst.hs
--- a/eg/bst.hs
+++ b/eg/bst.hs
@@ -1,6 +1,6 @@
 -- bst.hs: conjuring functions over binary search trees (BSTs)
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE CPP, TemplateHaskell #-}
 
diff --git a/eg/bst.out b/eg/bst.out
deleted file mode 100644
--- a/eg/bst.out
+++ /dev/null
@@ -1,122 +0,0 @@
-mem :: Int -> Tree -> Bool
--- testing 360 combinations of argument values
--- pruning with 20/30 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 7 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 31 candidates of size 8
--- looking through 92 candidates of size 9
--- looking through 0 candidates of size 10
--- looking through 304 candidates of size 11
--- looking through 199 candidates of size 12
--- tested 501 candidates
-mem x Leaf  =  False
-mem x (Node t1 y t2)  =  mem x t1 || (mem x t2 || x == y)
-
-mem :: Int -> Tree -> Bool
--- testing 360 combinations of argument values
--- pruning with 1/2 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 6 candidates of size 7
--- looking through 24 candidates of size 8
--- looking through 0 candidates of size 9
--- looking through 192 candidates of size 10
--- looking through 0 candidates of size 11
--- looking through 384 candidates of size 12
--- tested 375 candidates
-mem x Leaf  =  False
-mem x (Node t1 y t2)  =  case x `compare` y of LT -> mem x t1; EQ -> True; GT -> mem x t2
-
-insert :: Int -> Tree -> Tree
--- testing 360 combinations of argument values
--- pruning with 6/7 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 86 candidates of size 7
--- looking through 239 candidates of size 8
--- looking through 104 candidates of size 9
--- looking through 1558 candidates of size 10
--- looking through 3555 candidates of size 11
--- looking through 4028 candidates of size 12
--- tested 9603 candidates
-cannot conjure
-
-before :: Int -> Tree -> Tree
--- pruning with 5/6 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 86 candidates of size 7
--- looking through 239 candidates of size 8
--- looking through 104 candidates of size 9
--- looking through 1558 candidates of size 10
--- looking through 3555 candidates of size 11
--- looking through 4028 candidates of size 12
--- tested 9603 candidates
-cannot conjure
-
-before :: Int -> Tree -> Tree
--- pruning with 2/4 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 68 candidates of size 7
--- looking through 287 candidates of size 8
--- looking through 32 candidates of size 9
--- looking through 1216 candidates of size 10
--- looking through 5103 candidates of size 11
--- looking through 1472 candidates of size 12
--- tested 8211 candidates
-cannot conjure
-
-beyond :: Int -> Tree -> Tree
--- pruning with 2/4 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 68 candidates of size 7
--- looking through 287 candidates of size 8
--- looking through 32 candidates of size 9
--- looking through 1216 candidates of size 10
--- looking through 5103 candidates of size 11
--- looking through 1472 candidates of size 12
--- tested 8211 candidates
-cannot conjure
-
-union :: Tree -> Tree -> Tree
--- testing 360 combinations of argument values
--- pruning with 6/8 rules
--- looking through 3 candidates of size 1
--- looking through 11 candidates of size 2
--- looking through 32 candidates of size 3
--- looking through 84 candidates of size 4
--- looking through 470 candidates of size 5
--- looking through 1074 candidates of size 6
--- looking through 4088 candidates of size 7
--- looking through 16373 candidates of size 8
--- looking through 41366 candidates of size 9
--- tested 63501 candidates
-cannot conjure
-
diff --git a/eg/bst.txt b/eg/bst.txt
new file mode 100644
--- /dev/null
+++ b/eg/bst.txt
@@ -0,0 +1,122 @@
+mem :: Int -> Tree -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 20/30 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 31 candidates of size 8
+-- looking through 92 candidates of size 9
+-- looking through 0 candidates of size 10
+-- looking through 304 candidates of size 11
+-- looking through 199 candidates of size 12
+-- tested 497 candidates
+mem x Leaf  =  False
+mem x (Node t1 y t2)  =  mem x t1 || (mem x t2 || x == y)
+
+mem :: Int -> Tree -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 1/2 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 6 candidates of size 7
+-- looking through 24 candidates of size 8
+-- looking through 0 candidates of size 9
+-- looking through 192 candidates of size 10
+-- looking through 0 candidates of size 11
+-- looking through 384 candidates of size 12
+-- tested 371 candidates
+mem x Leaf  =  False
+mem x (Node t1 y t2)  =  case x `compare` y of LT -> mem x t1; EQ -> True; GT -> mem x t2
+
+insert :: Int -> Tree -> Tree
+-- testing 360 combinations of argument values
+-- pruning with 6/7 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 21 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 86 candidates of size 7
+-- looking through 239 candidates of size 8
+-- looking through 104 candidates of size 9
+-- looking through 1558 candidates of size 10
+-- looking through 3555 candidates of size 11
+-- looking through 4028 candidates of size 12
+-- tested 9599 candidates
+cannot conjure
+
+before :: Int -> Tree -> Tree
+-- pruning with 5/6 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 21 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 86 candidates of size 7
+-- looking through 239 candidates of size 8
+-- looking through 104 candidates of size 9
+-- looking through 1558 candidates of size 10
+-- looking through 3555 candidates of size 11
+-- looking through 4028 candidates of size 12
+-- tested 9599 candidates
+cannot conjure
+
+before :: Int -> Tree -> Tree
+-- pruning with 2/4 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 21 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 68 candidates of size 7
+-- looking through 287 candidates of size 8
+-- looking through 32 candidates of size 9
+-- looking through 1216 candidates of size 10
+-- looking through 5103 candidates of size 11
+-- looking through 1472 candidates of size 12
+-- tested 8207 candidates
+cannot conjure
+
+beyond :: Int -> Tree -> Tree
+-- pruning with 2/4 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 21 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 68 candidates of size 7
+-- looking through 287 candidates of size 8
+-- looking through 32 candidates of size 9
+-- looking through 1216 candidates of size 10
+-- looking through 5103 candidates of size 11
+-- looking through 1472 candidates of size 12
+-- tested 8207 candidates
+cannot conjure
+
+union :: Tree -> Tree -> Tree
+-- testing 360 combinations of argument values
+-- pruning with 6/8 rules
+-- looking through 3 candidates of size 1
+-- looking through 12 candidates of size 2
+-- looking through 32 candidates of size 3
+-- looking through 58 candidates of size 4
+-- looking through 434 candidates of size 5
+-- looking through 922 candidates of size 6
+-- looking through 3088 candidates of size 7
+-- looking through 14022 candidates of size 8
+-- looking through 31810 candidates of size 9
+-- tested 50381 candidates
+cannot conjure
+
diff --git a/eg/count.out b/eg/count.out
deleted file mode 100644
--- a/eg/count.out
+++ /dev/null
@@ -1,29 +0,0 @@
-count :: A -> [A] -> Int
--- testing 13 combinations of argument values
--- pruning with 1/2 rules
--- looking through 0 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 1 candidates of size 5
--- tested 2 candidates
-count x xs  =  length (filter (x ==) xs)
-
-count :: A -> [A] -> Int
--- testing 13 combinations of argument values
--- pruning with 8/13 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 8 candidates of size 5
--- looking through 14 candidates of size 6
--- looking through 24 candidates of size 7
--- looking through 58 candidates of size 8
--- looking through 134 candidates of size 9
--- looking through 302 candidates of size 10
--- looking through 633 candidates of size 11
--- tested 909 candidates
-count x []  =  0
-count x (y:xs)  =  count x xs + (if x == y then 1 else 0)
-
diff --git a/eg/count.txt b/eg/count.txt
new file mode 100644
--- /dev/null
+++ b/eg/count.txt
@@ -0,0 +1,29 @@
+count :: A -> [A] -> Int
+-- testing 13 combinations of argument values
+-- pruning with 1/2 rules
+-- looking through 0 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 1 candidates of size 5
+-- tested 2 candidates
+count x xs  =  length (filter (x ==) xs)
+
+count :: A -> [A] -> Int
+-- testing 13 combinations of argument values
+-- pruning with 8/13 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 10 candidates of size 6
+-- looking through 20 candidates of size 7
+-- looking through 54 candidates of size 8
+-- looking through 130 candidates of size 9
+-- looking through 298 candidates of size 10
+-- looking through 629 candidates of size 11
+-- tested 875 candidates
+count x []  =  0
+count x (y:xs)  =  count x xs + (if x == y then 1 else 0)
+
diff --git a/eg/dupos.hs b/eg/dupos.hs
--- a/eg/dupos.hs
+++ b/eg/dupos.hs
@@ -1,6 +1,6 @@
 -- dupos.hs: duplicates and positions
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 import Test.LeanCheck  -- needed for duplicatesSpec only
diff --git a/eg/dupos.out b/eg/dupos.out
deleted file mode 100644
--- a/eg/dupos.out
+++ /dev/null
@@ -1,72 +0,0 @@
-duplicates :: [Int] -> [Int]
--- testing 6 combinations of argument values
--- pruning with 21/26 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 1 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 3 candidates of size 7
--- looking through 8 candidates of size 8
--- looking through 16 candidates of size 9
--- looking through 25 candidates of size 10
--- looking through 36 candidates of size 11
--- looking through 63 candidates of size 12
--- looking through 133 candidates of size 13
--- looking through 299 candidates of size 14
--- looking through 602 candidates of size 15
--- looking through 1116 candidates of size 16
--- looking through 2031 candidates of size 17
--- tested 2451 candidates
-duplicates []  =  []
-duplicates (x:xs)  =  if elem x xs && not (elem x (duplicates xs))
-                      then x:duplicates xs
-                      else duplicates xs
-
-duplicates :: [Int] -> [Int]
--- pruning with 21/26 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 1 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 3 candidates of size 7
--- looking through 8 candidates of size 8
--- looking through 16 candidates of size 9
--- looking through 25 candidates of size 10
--- looking through 36 candidates of size 11
--- looking through 63 candidates of size 12
--- looking through 133 candidates of size 13
--- looking through 299 candidates of size 14
--- looking through 602 candidates of size 15
--- looking through 1116 candidates of size 16
--- looking through 2031 candidates of size 17
--- tested 2451 candidates
-duplicates []  =  []
-duplicates (x:xs)  =  if elem x xs && not (elem x (duplicates xs))
-                      then x:duplicates xs
-                      else duplicates xs
-
-positionsFrom :: Int -> A -> [A] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 5/10 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 5 candidates of size 4
--- looking through 13 candidates of size 5
--- looking through 18 candidates of size 6
--- looking through 47 candidates of size 7
--- looking through 77 candidates of size 8
--- looking through 193 candidates of size 9
--- looking through 293 candidates of size 10
--- looking through 738 candidates of size 11
--- looking through 1173 candidates of size 12
--- looking through 2879 candidates of size 13
--- looking through 4537 candidates of size 14
--- tested 5610 candidates
-positionsFrom x y []  =  []
-positionsFrom x y (z:xs)  =  (if y == z then (x :) else id) (positionsFrom (x + 1) y xs)
-
diff --git a/eg/dupos.txt b/eg/dupos.txt
new file mode 100644
--- /dev/null
+++ b/eg/dupos.txt
@@ -0,0 +1,72 @@
+duplicates :: [Int] -> [Int]
+-- testing 6 combinations of argument values
+-- pruning with 21/26 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 3 candidates of size 7
+-- looking through 8 candidates of size 8
+-- looking through 16 candidates of size 9
+-- looking through 25 candidates of size 10
+-- looking through 36 candidates of size 11
+-- looking through 63 candidates of size 12
+-- looking through 133 candidates of size 13
+-- looking through 299 candidates of size 14
+-- looking through 602 candidates of size 15
+-- looking through 1116 candidates of size 16
+-- looking through 2031 candidates of size 17
+-- tested 2450 candidates
+duplicates []  =  []
+duplicates (x:xs)  =  if elem x xs && not (elem x (duplicates xs))
+                      then x:duplicates xs
+                      else duplicates xs
+
+duplicates :: [Int] -> [Int]
+-- pruning with 21/26 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 3 candidates of size 7
+-- looking through 8 candidates of size 8
+-- looking through 16 candidates of size 9
+-- looking through 25 candidates of size 10
+-- looking through 36 candidates of size 11
+-- looking through 63 candidates of size 12
+-- looking through 133 candidates of size 13
+-- looking through 299 candidates of size 14
+-- looking through 602 candidates of size 15
+-- looking through 1116 candidates of size 16
+-- looking through 2031 candidates of size 17
+-- tested 2450 candidates
+duplicates []  =  []
+duplicates (x:xs)  =  if elem x xs && not (elem x (duplicates xs))
+                      then x:duplicates xs
+                      else duplicates xs
+
+positionsFrom :: Int -> A -> [A] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 5/10 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 5 candidates of size 4
+-- looking through 9 candidates of size 5
+-- looking through 16 candidates of size 6
+-- looking through 43 candidates of size 7
+-- looking through 73 candidates of size 8
+-- looking through 185 candidates of size 9
+-- looking through 285 candidates of size 10
+-- looking through 722 candidates of size 11
+-- looking through 1157 candidates of size 12
+-- looking through 2847 candidates of size 13
+-- looking through 4505 candidates of size 14
+-- tested 5484 candidates
+positionsFrom x y []  =  []
+positionsFrom x y (z:xs)  =  (if y == z then (x :) else id) (positionsFrom (x + 1) y xs)
+
diff --git a/eg/either.hs b/eg/either.hs
new file mode 100644
--- /dev/null
+++ b/eg/either.hs
@@ -0,0 +1,67 @@
+-- either.hs: conjuring functions over either values
+--
+-- Copyright (C) 2024 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+
+isLeft' :: Either A A -> Bool
+isLeft' (Left 0)  =  True
+isLeft' (Left 1)  =  True
+isLeft' (Right 0)  =  False
+isLeft' (Right 1)  =  False
+
+isRight' :: Either A A -> Bool
+isRight' (Left 0)  =  False
+isRight' (Left 1)  =  False
+isRight' (Right 0)  =  True
+isRight' (Right 1)  =  True
+
+fromLeft' :: A -> Either A A -> A
+fromLeft' 0 (Left 1)  =  1
+fromLeft' 0 (Left 2)  =  2
+fromLeft' 1 (Left 0)  =  0
+fromLeft' 0 (Right 1)  =  0
+fromLeft' 1 (Right 0)  =  1
+
+fromRight' :: A -> Either A A -> A
+fromRight' 0 (Left 1)  =  0
+fromRight' 0 (Left 2)  =  0
+fromRight' 1 (Left 0)  =  1
+fromRight' 0 (Right 1)  =  1
+fromRight' 1 (Right 0)  =  0
+
+eitherSpec :: ((A -> A) -> (A -> A) -> Either A A -> A) -> Bool
+eitherSpec either  =  and
+  [ either (+1) (+2) (Left 0) == 1
+  , either (+1) (+2) (Right 0) == 2
+  , either (*10) (*100) (Left 1) == 10
+  , either (*10) (*100) (Right 2) == 200
+  ]
+
+lefts' :: [Either A A] -> [A]
+lefts' []  =  []
+lefts' [Right 0]  =  []
+lefts' [Left 0, Right 1]  =  [0]
+lefts' [Right 0, Left 1]  =  [1]
+lefts' [Left 0, Left 1]  =  [0,1]
+
+main :: IO ()
+main = do
+  conjure "isLeft" isLeft' primitives
+  conjure "isRight" isRight' primitives
+  conjure "fromLeft" fromLeft' primitives
+  conjure "fromLeft" fromRight' primitives
+  conjureFromSpec "either" eitherSpec primitives
+  conjure "lefts" lefts' primitives
+
+primitives :: [Prim]
+primitives  =
+  [ prim "Left"  (Left :: A -> Either A A)
+  , prim "Right" (Right :: A -> Either A A)
+
+  , pr False
+  , pr True
+
+  , pr ([] :: [A])
+  , prim ":" ((:) :: A -> [A] -> [A])
+  ]
diff --git a/eg/either.txt b/eg/either.txt
new file mode 100644
--- /dev/null
+++ b/eg/either.txt
@@ -0,0 +1,54 @@
+isLeft :: Either A A -> Bool
+-- testing 4 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- tested 4 candidates
+isLeft (Left x)  =  True
+isLeft (Right x)  =  False
+
+isRight :: Either A A -> Bool
+-- testing 4 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- tested 3 candidates
+isRight (Left x)  =  False
+isRight (Right x)  =  True
+
+fromLeft :: A -> Either A A -> A
+-- testing 5 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 3 candidates of size 2
+-- tested 3 candidates
+fromLeft x (Left y)  =  y
+fromLeft x (Right y)  =  x
+
+fromLeft :: A -> Either A A -> A
+-- testing 5 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 3 candidates of size 2
+-- tested 2 candidates
+fromLeft x (Left y)  =  x
+fromLeft x (Right y)  =  y
+
+either :: (A -> A) -> (A -> A) -> Either A A -> A
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 12 candidates of size 4
+-- tested 11 candidates
+either f g (Left x)  =  f x
+either f g (Right x)  =  g x
+
+lefts :: [Either A A] -> [A]
+-- testing 5 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 1 candidates
+cannot conjure
+
diff --git a/eg/factorial.hs b/eg/factorial.hs
--- a/eg/factorial.hs
+++ b/eg/factorial.hs
@@ -1,6 +1,6 @@
 -- factorial.hs: conjuring a factorial function
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/eg/factorial.out b/eg/factorial.out
deleted file mode 100644
--- a/eg/factorial.out
+++ /dev/null
@@ -1,26 +0,0 @@
-factorial :: Int -> Int
--- testing 4 combinations of argument values
--- pruning with 27/65 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 7 candidates of size 3
--- looking through 13 candidates of size 4
--- looking through 35 candidates of size 5
--- looking through 61 candidates of size 6
--- looking through 219 candidates of size 7
--- tested 153 candidates
-factorial 0  =  1
-factorial x  =  x * factorial (x - 1)
-
-factorial :: Int -> Int
--- testing 4 combinations of argument values
--- pruning with 32/72 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 7 candidates of size 3
--- looking through 13 candidates of size 4
--- looking through 35 candidates of size 5
--- looking through 101 candidates of size 6
--- tested 89 candidates
-factorial x  =  foldr (*) 1 [1..x]
-
diff --git a/eg/factorial.txt b/eg/factorial.txt
new file mode 100644
--- /dev/null
+++ b/eg/factorial.txt
@@ -0,0 +1,26 @@
+factorial :: Int -> Int
+-- testing 4 combinations of argument values
+-- pruning with 27/65 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 7 candidates of size 3
+-- looking through 8 candidates of size 4
+-- looking through 28 candidates of size 5
+-- looking through 35 candidates of size 6
+-- looking through 179 candidates of size 7
+-- tested 95 candidates
+factorial 0  =  1
+factorial x  =  x * factorial (x - 1)
+
+factorial :: Int -> Int
+-- testing 4 combinations of argument values
+-- pruning with 32/72 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 7 candidates of size 3
+-- looking through 8 candidates of size 4
+-- looking through 28 candidates of size 5
+-- looking through 75 candidates of size 6
+-- tested 74 candidates
+factorial x  =  foldr (*) 1 [1..x]
+
diff --git a/eg/fib01.out b/eg/fib01.out
deleted file mode 100644
--- a/eg/fib01.out
+++ /dev/null
@@ -1,27 +0,0 @@
-fib01 :: Int -> Int -> Int -> Int
--- testing 8 combinations of argument values
--- pruning with 6/10 rules
--- looking through 4 candidates of size 1
--- looking through 24 candidates of size 2
--- looking through 115 candidates of size 3
--- looking through 470 candidates of size 4
--- looking through 1657 candidates of size 5
--- tested 2270 candidates
-cannot conjure
-
-fib01 :: Int -> Int -> Int -> Int
--- testing 8 combinations of argument values
--- pruning with 18/37 rules
--- looking through 4 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 10 candidates of size 3
--- looking through 16 candidates of size 4
--- looking through 44 candidates of size 5
--- looking through 92 candidates of size 6
--- looking through 234 candidates of size 7
--- looking through 544 candidates of size 8
--- looking through 1332 candidates of size 9
--- looking through 7796 candidates of size 10
--- tested 10076 candidates
-cannot conjure
-
diff --git a/eg/fib01.txt b/eg/fib01.txt
new file mode 100644
--- /dev/null
+++ b/eg/fib01.txt
@@ -0,0 +1,27 @@
+fib01 :: Int -> Int -> Int -> Int
+-- testing 8 combinations of argument values
+-- pruning with 6/10 rules
+-- looking through 4 candidates of size 1
+-- looking through 27 candidates of size 2
+-- looking through 117 candidates of size 3
+-- looking through 464 candidates of size 4
+-- looking through 1564 candidates of size 5
+-- tested 2176 candidates
+cannot conjure
+
+fib01 :: Int -> Int -> Int -> Int
+-- testing 8 combinations of argument values
+-- pruning with 18/37 rules
+-- looking through 4 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 10 candidates of size 3
+-- looking through 16 candidates of size 4
+-- looking through 44 candidates of size 5
+-- looking through 92 candidates of size 6
+-- looking through 234 candidates of size 7
+-- looking through 544 candidates of size 8
+-- looking through 1332 candidates of size 9
+-- looking through 10676 candidates of size 10
+-- tested 12956 candidates
+cannot conjure
+
diff --git a/eg/fibonacci.out b/eg/fibonacci.out
deleted file mode 100644
--- a/eg/fibonacci.out
+++ /dev/null
@@ -1,20 +0,0 @@
-fibonacci :: Int -> Int
--- testing 7 combinations of argument values
--- pruning with 21/44 rules
--- looking through 4 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 9 candidates of size 3
--- looking through 11 candidates of size 4
--- looking through 34 candidates of size 5
--- looking through 41 candidates of size 6
--- looking through 187 candidates of size 7
--- looking through 204 candidates of size 8
--- looking through 957 candidates of size 9
--- looking through 1059 candidates of size 10
--- looking through 5295 candidates of size 11
--- looking through 6052 candidates of size 12
--- tested 8126 candidates
-fibonacci 0  =  1
-fibonacci 1  =  1
-fibonacci x  =  fibonacci (x - 1) + fibonacci (x - 2)
-
diff --git a/eg/fibonacci.txt b/eg/fibonacci.txt
new file mode 100644
--- /dev/null
+++ b/eg/fibonacci.txt
@@ -0,0 +1,20 @@
+fibonacci :: Int -> Int
+-- testing 7 combinations of argument values
+-- pruning with 21/44 rules
+-- looking through 4 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 9 candidates of size 3
+-- looking through 9 candidates of size 4
+-- looking through 30 candidates of size 5
+-- looking through 30 candidates of size 6
+-- looking through 156 candidates of size 7
+-- looking through 157 candidates of size 8
+-- looking through 813 candidates of size 9
+-- looking through 797 candidates of size 10
+-- looking through 4449 candidates of size 11
+-- looking through 4438 candidates of size 12
+-- tested 6539 candidates
+fibonacci 0  =  1
+fibonacci 1  =  1
+fibonacci x  =  fibonacci (x - 1) + fibonacci (x - 2)
+
diff --git a/eg/gcd.hs b/eg/gcd.hs
--- a/eg/gcd.hs
+++ b/eg/gcd.hs
@@ -1,6 +1,6 @@
 -- gcd.hs: conjuring a GCD implementation
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/eg/gcd.out b/eg/gcd.out
deleted file mode 100644
--- a/eg/gcd.out
+++ /dev/null
@@ -1,13 +0,0 @@
-gcd :: Int -> Int -> Int
--- testing 11 combinations of argument values
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 50 candidates of size 4
--- looking through 98 candidates of size 5
--- looking through 359 candidates of size 6
--- tested 171 candidates
-gcd x 0  =  x
-gcd x y  =  gcd y (x `mod` y)
-
diff --git a/eg/gcd.txt b/eg/gcd.txt
new file mode 100644
--- /dev/null
+++ b/eg/gcd.txt
@@ -0,0 +1,13 @@
+gcd :: Int -> Int -> Int
+-- testing 11 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 50 candidates of size 4
+-- looking through 98 candidates of size 5
+-- looking through 344 candidates of size 6
+-- tested 173 candidates
+gcd x 0  =  x
+gcd x y  =  gcd y (x `mod` y)
+
diff --git a/eg/higher.hs b/eg/higher.hs
--- a/eg/higher.hs
+++ b/eg/higher.hs
@@ -9,8 +9,6 @@
              && (abs $ (-2)) == 2
              && (negate $ 1) == -1
 
--- composeSpec :: ((Int->Int) -> (Int->Int) -> Int->Int) -> 
-
 composeSpec :: ((Int->Int) -> (Int->Int) -> Int->Int) -> Bool
 composeSpec (.)  =  ((*2) . (*3)) 1 == 6
                  && (abs . negate) 7 == 7
diff --git a/eg/higher.out b/eg/higher.out
deleted file mode 100644
--- a/eg/higher.out
+++ /dev/null
@@ -1,69 +0,0 @@
-($) :: (Int -> Int) -> Int -> Int
--- pruning with 3/3 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- tested 2 candidates
-f $ x  =  f x
-
-(.) :: (Int -> Int) -> (Int -> Int) -> Int -> Int
--- pruning with 3/3 rules
--- looking through 1 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 4 candidates of size 3
--- tested 5 candidates
-(f . g) x  =  f (g x)
-
-flip :: (Int -> Int -> Int) -> Int -> Int -> Int
--- pruning with 3/3 rules
--- looking through 2 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 4 candidates of size 3
--- tested 5 candidates
-flip f x y  =  f y x
-
-map :: (Int -> Int) -> [Int] -> [Int]
--- pruning with 3/3 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 6 candidates of size 6
--- looking through 9 candidates of size 7
--- tested 17 candidates
-map f []  =  []
-map f (x:xs)  =  f x:map f xs
-
-fold :: (Int -> Int -> Int) -> Int -> [Int] -> Int
--- pruning with 3/3 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 23 candidates of size 6
--- looking through 26 candidates of size 7
--- tested 45 candidates
-fold f x []  =  x
-fold f x (y:xs)  =  fold f (f x y) xs
-
-filter :: (Int -> Bool) -> [Int] -> [Int]
--- pruning with 3/3 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 6 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 22 candidates of size 8
--- looking through 0 candidates of size 9
--- looking through 65 candidates of size 10
--- looking through 0 candidates of size 11
--- looking through 219 candidates of size 12
--- tested 166 candidates
-filter f []  =  []
-filter f (x:xs)  =  if f x
-                    then x:filter f xs
-                    else filter f xs
-
diff --git a/eg/higher.txt b/eg/higher.txt
new file mode 100644
--- /dev/null
+++ b/eg/higher.txt
@@ -0,0 +1,69 @@
+($) :: (Int -> Int) -> Int -> Int
+-- pruning with 3/3 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- tested 2 candidates
+f $ x  =  f x
+
+(.) :: (Int -> Int) -> (Int -> Int) -> Int -> Int
+-- pruning with 3/3 rules
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 4 candidates of size 3
+-- tested 5 candidates
+(f . g) x  =  f (g x)
+
+flip :: (Int -> Int -> Int) -> Int -> Int -> Int
+-- pruning with 3/3 rules
+-- looking through 2 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 4 candidates of size 3
+-- tested 5 candidates
+flip f x y  =  f y x
+
+map :: (Int -> Int) -> [Int] -> [Int]
+-- pruning with 3/3 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 7 candidates of size 7
+-- tested 13 candidates
+map f []  =  []
+map f (x:xs)  =  f x:map f xs
+
+fold :: (Int -> Int -> Int) -> Int -> [Int] -> Int
+-- pruning with 3/3 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 23 candidates of size 6
+-- looking through 19 candidates of size 7
+-- tested 38 candidates
+fold f x []  =  x
+fold f x (y:xs)  =  fold f (f x y) xs
+
+filter :: (Int -> Bool) -> [Int] -> [Int]
+-- pruning with 3/3 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 17 candidates of size 8
+-- looking through 0 candidates of size 9
+-- looking through 44 candidates of size 10
+-- looking through 0 candidates of size 11
+-- looking through 142 candidates of size 12
+-- tested 72 candidates
+filter f []  =  []
+filter f (x:xs)  =  if f x
+                    then x:filter f xs
+                    else filter f xs
+
diff --git a/eg/id.out b/eg/id.out
deleted file mode 100644
--- a/eg/id.out
+++ /dev/null
@@ -1,14 +0,0 @@
-id :: Int -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 1 candidates of size 1
--- tested 1 candidates
-id x  =  x
-
-const :: Int -> Int -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 2 candidates of size 1
--- tested 1 candidates
-const x y  =  x
-
diff --git a/eg/id.txt b/eg/id.txt
new file mode 100644
--- /dev/null
+++ b/eg/id.txt
@@ -0,0 +1,14 @@
+id :: Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- tested 1 candidates
+id x  =  x
+
+const :: Int -> Int -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- tested 1 candidates
+const x y  =  x
+
diff --git a/eg/ints.hs b/eg/ints.hs
--- a/eg/ints.hs
+++ b/eg/ints.hs
@@ -1,6 +1,6 @@
 -- ints.hs: conjuring functions over lists of ints
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/eg/ints.out b/eg/ints.out
deleted file mode 100644
--- a/eg/ints.out
+++ /dev/null
@@ -1,63 +0,0 @@
-second :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- tested 2 candidates
-second xs  =  head (tail xs)
-
-third :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 1 candidates of size 4
--- tested 3 candidates
-third xs  =  head (tail (tail xs))
-
-sum :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 14/25 rules
--- looking through 2 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 6 candidates of size 5
--- tested 15 candidates
-sum []  =  0
-sum (x:xs)  =  x + sum xs
-
-product :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 14/25 rules
--- looking through 2 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 6 candidates of size 5
--- tested 20 candidates
-product []  =  1
-product (x:xs)  =  x * product xs
-
-sum :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 15/26 rules
--- looking through 2 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 9 candidates of size 4
--- tested 9 candidates
-sum xs  =  foldr (+) 0 xs
-
-product :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 15/26 rules
--- looking through 2 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 9 candidates of size 4
--- tested 11 candidates
-product xs  =  foldr (*) 1 xs
-
diff --git a/eg/ints.txt b/eg/ints.txt
new file mode 100644
--- /dev/null
+++ b/eg/ints.txt
@@ -0,0 +1,63 @@
+second :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- tested 2 candidates
+second xs  =  head (tail xs)
+
+third :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- tested 3 candidates
+third xs  =  head (tail (tail xs))
+
+sum :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 6 candidates of size 5
+-- tested 13 candidates
+sum []  =  0
+sum (x:xs)  =  x + sum xs
+
+product :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 6 candidates of size 5
+-- tested 18 candidates
+product []  =  1
+product (x:xs)  =  x * product xs
+
+sum :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 15/26 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 9 candidates of size 4
+-- tested 7 candidates
+sum xs  =  foldr (+) 0 xs
+
+product :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 15/26 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 9 candidates of size 4
+-- tested 9 candidates
+product xs  =  foldr (*) 1 xs
+
diff --git a/eg/list.hs b/eg/list.hs
--- a/eg/list.hs
+++ b/eg/list.hs
@@ -1,6 +1,6 @@
 -- list.hs: conjuring functions over lists (of ints)
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
@@ -58,6 +58,11 @@
 zip' [x,y] [a,b]  =  [(x,a),(y,b)]
 zip' [x,y,z] [a,b,c]  =  [(x,a),(y,b),(z,c)]
 
+last' :: [Int] -> Int
+last' [x]  =  x
+last' [x,y]  =  y
+last' [x,y,z]  =  z
+
 main :: IO ()
 main = do
   conjure "length" length'
@@ -81,6 +86,14 @@
     [ pr ([] :: [Int])
     , prim ":" ((:) :: Int -> [Int] -> [Int])
     , prim "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])
+    ]
+
+  conjure "last" last'
+    [ pr ([] :: [Int])
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "null" (null :: [Int] -> Bool)
+    , prif (undefined :: Int)
+    , prim "undefined" (undefined :: Int)
     ]
 
   conjure "zip" (zip')
diff --git a/eg/list.out b/eg/list.out
deleted file mode 100644
--- a/eg/list.out
+++ /dev/null
@@ -1,115 +0,0 @@
-length :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 4/8 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 2 candidates of size 5
--- tested 9 candidates
-length []  =  0
-length (x:xs)  =  length xs + 1
-
-reverse :: [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 4/4 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 7 candidates of size 6
--- looking through 10 candidates of size 7
--- tested 27 candidates
-reverse []  =  []
-reverse (x:xs)  =  reverse xs ++ [x]
-
-(++) :: [Int] -> [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 7 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 37 candidates of size 4
--- looking through 98 candidates of size 5
--- looking through 94 candidates of size 6
--- tested 194 candidates
-[] ++ xs  =  xs
-(x:xs) ++ ys  =  x:(xs ++ ys)
-
-(++) :: [Int] -> [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 2/2 rules
--- looking through 3 candidates of size 1
--- looking through 7 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 41 candidates of size 4
--- tested 48 candidates
-xs ++ ys  =  foldr (:) ys xs
-
-zip :: [Int] -> [Int] -> [(Int,Int)]
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 8 candidates of size 4
--- looking through 6 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 14 candidates of size 7
--- looking through 9 candidates of size 8
--- looking through 31 candidates of size 9
--- tested 50 candidates
-zip [] xs  =  []
-zip (x:xs) []  =  []
-zip (x:xs) (y:ys)  =  (x,y):zip xs ys
-
-(\/) :: [Int] -> [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 3 candidates of size 1
--- looking through 7 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 37 candidates of size 4
--- looking through 98 candidates of size 5
--- looking through 94 candidates of size 6
--- tested 196 candidates
-[] \/ xs  =  xs
-(x:xs) \/ ys  =  x:ys \/ xs
-
-ordered :: [Int] -> Bool
--- testing 360 combinations of argument values
--- pruning with 29/39 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 12 candidates of size 6
--- looking through 20 candidates of size 7
--- looking through 30 candidates of size 8
--- looking through 56 candidates of size 9
--- looking through 114 candidates of size 10
--- looking through 216 candidates of size 11
--- tested 333 candidates
-ordered []  =  True
-ordered (x:xs)  =  ordered xs && (null xs || x <= head xs)
-
-merge :: [Int] -> [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 1/2 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 22 candidates of size 5
--- looking through 32 candidates of size 6
--- looking through 75 candidates of size 7
--- looking through 108 candidates of size 8
--- looking through 256 candidates of size 9
--- looking through 520 candidates of size 10
--- looking through 1329 candidates of size 11
--- looking through 2632 candidates of size 12
--- tested 4992 candidates
-cannot conjure
-
diff --git a/eg/list.txt b/eg/list.txt
new file mode 100644
--- /dev/null
+++ b/eg/list.txt
@@ -0,0 +1,131 @@
+length :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 4/8 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 2 candidates of size 5
+-- tested 8 candidates
+length []  =  0
+length (x:xs)  =  length xs + 1
+
+reverse :: [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 7 candidates of size 6
+-- looking through 10 candidates of size 7
+-- tested 26 candidates
+reverse []  =  []
+reverse (x:xs)  =  reverse xs ++ [x]
+
+(++) :: [Int] -> [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 8 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 23 candidates of size 4
+-- looking through 86 candidates of size 5
+-- looking through 72 candidates of size 6
+-- tested 149 candidates
+[] ++ xs  =  xs
+(x:xs) ++ ys  =  x:(xs ++ ys)
+
+(++) :: [Int] -> [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 2/2 rules
+-- looking through 3 candidates of size 1
+-- looking through 8 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 27 candidates of size 4
+-- tested 35 candidates
+xs ++ ys  =  foldr (:) ys xs
+
+last :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 5/5 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 4 candidates of size 7
+-- tested 5 candidates
+last []  =  undefined
+last (x:xs)  =  if null xs
+                then x
+                else last xs
+
+zip :: [Int] -> [Int] -> [(Int,Int)]
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 6 candidates of size 7
+-- looking through 6 candidates of size 8
+-- looking through 30 candidates of size 9
+-- tested 25 candidates
+zip [] xs  =  []
+zip (x:xs) []  =  []
+zip (x:xs) (y:ys)  =  (x,y):zip xs ys
+
+(\/) :: [Int] -> [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 3 candidates of size 1
+-- looking through 8 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 23 candidates of size 4
+-- looking through 86 candidates of size 5
+-- looking through 72 candidates of size 6
+-- tested 151 candidates
+[] \/ xs  =  xs
+(x:xs) \/ ys  =  x:ys \/ xs
+
+ordered :: [Int] -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 29/39 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 12 candidates of size 6
+-- looking through 20 candidates of size 7
+-- looking through 30 candidates of size 8
+-- looking through 56 candidates of size 9
+-- looking through 114 candidates of size 10
+-- looking through 216 candidates of size 11
+-- tested 331 candidates
+ordered []  =  True
+ordered (x:xs)  =  ordered xs && (null xs || x <= head xs)
+
+merge :: [Int] -> [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 1/2 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 21 candidates of size 5
+-- looking through 26 candidates of size 6
+-- looking through 61 candidates of size 7
+-- looking through 92 candidates of size 8
+-- looking through 203 candidates of size 9
+-- looking through 430 candidates of size 10
+-- looking through 1086 candidates of size 11
+-- looking through 2068 candidates of size 12
+-- tested 4004 candidates
+cannot conjure
+
diff --git a/eg/maybe.hs b/eg/maybe.hs
new file mode 100644
--- /dev/null
+++ b/eg/maybe.hs
@@ -0,0 +1,84 @@
+-- maybe.hs: conjuring functions over maybe values
+--
+-- Copyright (C) 2024 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+
+isNothing' :: Maybe A -> Bool
+isNothing' Nothing   =  True
+isNothing' (Just 0)  =  False
+isNothing' (Just 1)  =  False
+
+isJust' :: Maybe A -> Bool
+isJust' Nothing   =  False
+isJust' (Just 0)  =  True
+isJust' (Just 1)  =  True
+
+fromMaybe' :: A -> Maybe A -> A
+fromMaybe' 0 Nothing  =  0
+fromMaybe' 1 Nothing  =  1
+fromMaybe' 0 (Just 1)  =  1
+fromMaybe' 1 (Just 2)  =  2
+
+maybeSpec :: (A -> (A -> A) -> Maybe A -> A) -> Bool
+maybeSpec maybe  =  and
+  [ maybe 0 undefined Nothing == 0
+  , maybe 1 undefined Nothing == 1
+  , maybe undefined (+1) (Just 1) == 2
+  , maybe undefined (*2) (Just 3) == 6
+  ]
+
+listToMaybe' :: [A] -> Maybe A
+listToMaybe' []  =  Nothing
+listToMaybe' [2]  =  Just 2
+listToMaybe' [0,1]  =  Just 0
+listToMaybe' [1,0]  =  Just 1
+
+maybeToList' :: Maybe A -> [A]
+maybeToList' Nothing   =  []
+maybeToList' (Just 0)  =  [0]
+maybeToList' (Just 1)  =  [1]
+maybeToList' (Just 2)  =  [2]
+
+catMaybes' :: [Maybe A] -> [A]
+catMaybes' []  =  []
+catMaybes' [Nothing]  =  []
+catMaybes' [Just x]  =  [x]
+catMaybes' [Just x, Nothing, Just y]  =  [x,y]
+
+main :: IO ()
+main = do
+  conjure "isNothing"     isNothing'   primitives
+  conjure "isJust"        isJust'      primitives
+  conjure "fromMaybe"     fromMaybe'   primitives
+  conjureFromSpec "maybe" maybeSpec    primitives
+  conjure "listToMaybe"   listToMaybe' primitives
+  conjure "maybeToList"   maybeToList' primitives
+
+  -- only top-level break downs, so would need morePrimitives
+  conjure "catMaybes"     catMaybes'   primitives
+  -- conjure "mapMaybe" mapMaybe' primitives  -- same
+
+primitives :: [Prim]
+primitives  =
+  [ pr (Nothing :: Maybe A)
+  , prim "Just" (Just :: A -> Maybe A)
+
+  , pr False
+  , pr True
+
+  , pr ([] :: [A])
+  , prim ":" ((:) :: A -> [A] -> [A])
+  ]
+
+{-
+morePrimitives :: [Prim]
+morePrimitives  =  primitives ++
+  [ prim "isNothing" (isNothing :: Maybe A -> Bool)
+  , prim "isJust"    (isJust    :: Maybe A -> Bool)
+  , prim "fromJust"  (fromJust :: Maybe A -> A)
+  , prif (undefined :: A)
+  , prif (undefined :: Maybe A)
+  , prif (undefined :: [A])
+  ]
+-}
diff --git a/eg/maybe.txt b/eg/maybe.txt
new file mode 100644
--- /dev/null
+++ b/eg/maybe.txt
@@ -0,0 +1,65 @@
+isNothing :: Maybe A -> Bool
+-- testing 3 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- tested 3 candidates
+isNothing Nothing  =  True
+isNothing (Just x)  =  False
+
+isJust :: Maybe A -> Bool
+-- testing 3 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- tested 3 candidates
+isJust Nothing  =  False
+isJust (Just x)  =  True
+
+fromMaybe :: A -> Maybe A -> A
+-- testing 4 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- tested 2 candidates
+fromMaybe x Nothing  =  x
+fromMaybe x (Just y)  =  y
+
+maybe :: A -> (A -> A) -> Maybe A -> A
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 5 candidates of size 3
+-- tested 6 candidates
+maybe x f Nothing  =  x
+maybe x f (Just y)  =  f y
+
+listToMaybe :: [A] -> Maybe A
+-- testing 4 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- tested 2 candidates
+listToMaybe []  =  Nothing
+listToMaybe (x:xs)  =  Just x
+
+maybeToList :: Maybe A -> [A]
+-- testing 4 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- tested 2 candidates
+maybeToList Nothing  =  []
+maybeToList (Just x)  =  [x]
+
+catMaybes :: [Maybe A] -> [A]
+-- testing 44 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- tested 1 candidates
+cannot conjure
+
diff --git a/eg/oddeven.hs b/eg/oddeven.hs
new file mode 100644
--- /dev/null
+++ b/eg/oddeven.hs
@@ -0,0 +1,52 @@
+-- oddeven.hs: conjuring even and odd from two sets of primitives
+--
+-- Copyright (C) 2024 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+import Prelude hiding (odd, even)
+
+odd :: Int -> Bool
+odd 0  =  False
+odd 1  =  True
+odd 2  =  False
+odd 3  =  True
+odd 4  =  False
+odd 5  =  True
+
+even :: Int -> Bool
+even 0  =  True
+even 1  =  False
+even 2  =  True
+even 3  =  False
+even 4  =  True
+even 5  =  False
+
+main :: IO ()
+main = do
+  conjure "odd"  odd  primitives1
+  conjure "even" even primitives1
+  conjure "odd"  odd  primitives2
+  conjure "even" even primitives2
+
+primitives1 :: [Prim]
+primitives1 =
+  [ pr (0::Int)
+  , pr (1::Int)
+  , pr (2::Int)
+  , prim "+" ((+) :: Int -> Int -> Int)
+
+  , prim "-" ((-) :: Int -> Int -> Int)
+  , pr False
+  , pr True
+  ]
+
+primitives2 :: [Prim]
+primitives2 =
+  [ pr (0::Int)
+  , pr (1::Int)
+  , pr (2::Int)
+  , prim "+" ((+) :: Int -> Int -> Int)
+
+  , prim "`mod`" (mod :: Int -> Int -> Int)
+  , prim "==" ((==) :: Int -> Int -> Bool)
+  ]
diff --git a/eg/oddeven.txt b/eg/oddeven.txt
new file mode 100644
--- /dev/null
+++ b/eg/oddeven.txt
@@ -0,0 +1,52 @@
+odd :: Int -> Bool
+-- testing 6 combinations of argument values
+-- pruning with 21/44 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 2 candidates of size 7
+-- tested 8 candidates
+odd 0  =  False
+odd 1  =  True
+odd x  =  odd (x - 2)
+
+even :: Int -> Bool
+-- testing 6 combinations of argument values
+-- pruning with 21/44 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 1 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 2 candidates of size 7
+-- tested 8 candidates
+even 0  =  True
+even 1  =  False
+even x  =  even (x - 2)
+
+odd :: Int -> Bool
+-- testing 6 combinations of argument values
+-- pruning with 36/55 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 50 candidates of size 5
+-- tested 35 candidates
+odd x  =  1 == x `mod` 2
+
+even :: Int -> Bool
+-- testing 6 combinations of argument values
+-- pruning with 36/55 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 49 candidates of size 5
+-- tested 26 candidates
+even x  =  0 == x `mod` 2
+
diff --git a/eg/pow.hs b/eg/pow.hs
--- a/eg/pow.hs
+++ b/eg/pow.hs
@@ -1,6 +1,6 @@
 -- pow.hs: conjuring exponentiation
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
diff --git a/eg/pow.out b/eg/pow.out
deleted file mode 100644
--- a/eg/pow.out
+++ /dev/null
@@ -1,27 +0,0 @@
-pow :: Int -> Int -> Int
--- testing 5 combinations of argument values
--- pruning with 14/30 rules
--- looking through 4 candidates of size 1
--- looking through 15 candidates of size 2
--- looking through 45 candidates of size 3
--- looking through 168 candidates of size 4
--- looking through 491 candidates of size 5
--- looking through 1729 candidates of size 6
--- looking through 5420 candidates of size 7
--- looking through 17952 candidates of size 8
--- tested 8593 candidates
-pow x 0  =  1
-pow x y  =  x * pow x (y - 1)
-
-pow :: Int -> Int -> Int
--- testing 5 combinations of argument values
--- pruning with 15/19 rules
--- looking through 4 candidates of size 1
--- looking through 17 candidates of size 2
--- looking through 59 candidates of size 3
--- looking through 190 candidates of size 4
--- looking through 594 candidates of size 5
--- looking through 1784 candidates of size 6
--- tested 2648 candidates
-cannot conjure
-
diff --git a/eg/pow.txt b/eg/pow.txt
new file mode 100644
--- /dev/null
+++ b/eg/pow.txt
@@ -0,0 +1,27 @@
+pow :: Int -> Int -> Int
+-- testing 5 combinations of argument values
+-- pruning with 14/30 rules
+-- looking through 4 candidates of size 1
+-- looking through 16 candidates of size 2
+-- looking through 46 candidates of size 3
+-- looking through 159 candidates of size 4
+-- looking through 433 candidates of size 5
+-- looking through 1382 candidates of size 6
+-- looking through 4156 candidates of size 7
+-- looking through 13406 candidates of size 8
+-- tested 6403 candidates
+pow x 0  =  1
+pow x y  =  x * pow x (y - 1)
+
+pow :: Int -> Int -> Int
+-- testing 5 combinations of argument values
+-- pruning with 15/19 rules
+-- looking through 4 candidates of size 1
+-- looking through 18 candidates of size 2
+-- looking through 58 candidates of size 3
+-- looking through 174 candidates of size 4
+-- looking through 485 candidates of size 5
+-- looking through 1387 candidates of size 6
+-- tested 2126 candidates
+cannot conjure
+
diff --git a/eg/replicate.hs b/eg/replicate.hs
--- a/eg/replicate.hs
+++ b/eg/replicate.hs
@@ -1,6 +1,6 @@
 -- replicate.hs: replicate and other functions
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 import Data.List (transpose)
diff --git a/eg/replicate.out b/eg/replicate.out
deleted file mode 100644
--- a/eg/replicate.out
+++ /dev/null
@@ -1,52 +0,0 @@
-replicate :: Int -> Char -> [Char]
--- testing 360 combinations of argument values
--- pruning with 4/7 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 6 candidates of size 6
--- looking through 8 candidates of size 7
--- looking through 19 candidates of size 8
--- tested 33 candidates
-replicate 0 c  =  ""
-replicate x c  =  c:replicate (x - 1) c
-
-replicates :: [Char] -> Int -> [Char]
--- testing 360 combinations of argument values
--- pruning with 2/2 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 1 candidates of size 5
--- tested 3 candidates
-replicates cs x  =  concat (transpose (replicate x cs))
-
-replicates :: [Char] -> Int -> [Char]
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 1 candidates of size 5
--- tested 2 candidates
-replicates cs x  =  concat (map (replicate x) cs)
-
-replicates :: [Char] -> Int -> [Char]
--- testing 360 combinations of argument values
--- pruning with 9/14 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 7 candidates of size 3
--- looking through 23 candidates of size 4
--- looking through 62 candidates of size 5
--- looking through 155 candidates of size 6
--- looking through 446 candidates of size 7
--- looking through 1231 candidates of size 8
--- tested 751 candidates
-replicates "" x  =  ""
-replicates (c:cs) x  =  replicate x c ++ replicates cs x
-
diff --git a/eg/replicate.txt b/eg/replicate.txt
new file mode 100644
--- /dev/null
+++ b/eg/replicate.txt
@@ -0,0 +1,52 @@
+replicate :: Int -> Char -> [Char]
+-- testing 360 combinations of argument values
+-- pruning with 4/7 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 3 candidates of size 5
+-- looking through 2 candidates of size 6
+-- looking through 3 candidates of size 7
+-- looking through 3 candidates of size 8
+-- tested 12 candidates
+replicate 0 c  =  ""
+replicate x c  =  c:replicate (x - 1) c
+
+replicates :: [Char] -> Int -> [Char]
+-- testing 360 combinations of argument values
+-- pruning with 2/2 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 1 candidates of size 5
+-- tested 3 candidates
+replicates cs x  =  concat (transpose (replicate x cs))
+
+replicates :: [Char] -> Int -> [Char]
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 1 candidates of size 5
+-- tested 2 candidates
+replicates cs x  =  concat (map (replicate x) cs)
+
+replicates :: [Char] -> Int -> [Char]
+-- testing 360 combinations of argument values
+-- pruning with 9/14 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 7 candidates of size 3
+-- looking through 22 candidates of size 4
+-- looking through 59 candidates of size 5
+-- looking through 152 candidates of size 6
+-- looking through 442 candidates of size 7
+-- looking through 1223 candidates of size 8
+-- tested 736 candidates
+replicates "" x  =  ""
+replicates (c:cs) x  =  replicate x c ++ replicates cs x
+
diff --git a/eg/setelem.out b/eg/setelem.out
deleted file mode 100644
--- a/eg/setelem.out
+++ /dev/null
@@ -1,30 +0,0 @@
-elem :: Int -> [Int] -> Bool
--- testing 360 combinations of argument values
--- pruning with 44/57 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 20 candidates of size 4
--- looking through 48 candidates of size 5
--- looking through 75 candidates of size 6
--- looking through 149 candidates of size 7
--- looking through 368 candidates of size 8
--- tested 396 candidates
-elem x []  =  False
-elem x (y:xs)  =  elem x xs || x == y
-
-set :: [Int] -> Bool
--- testing 360 combinations of argument values
--- pruning with 46/57 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 11 candidates of size 4
--- looking through 20 candidates of size 5
--- looking through 41 candidates of size 6
--- looking through 100 candidates of size 7
--- looking through 234 candidates of size 8
--- tested 200 candidates
-set []  =  True
-set (x:xs)  =  set xs && not (elem x xs)
-
diff --git a/eg/setelem.txt b/eg/setelem.txt
new file mode 100644
--- /dev/null
+++ b/eg/setelem.txt
@@ -0,0 +1,30 @@
+elem :: Int -> [Int] -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 44/57 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 5 candidates of size 3
+-- looking through 16 candidates of size 4
+-- looking through 38 candidates of size 5
+-- looking through 67 candidates of size 6
+-- looking through 134 candidates of size 7
+-- looking through 345 candidates of size 8
+-- tested 340 candidates
+elem x []  =  False
+elem x (y:xs)  =  elem x xs || x == y
+
+set :: [Int] -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 46/57 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 20 candidates of size 5
+-- looking through 41 candidates of size 6
+-- looking through 100 candidates of size 7
+-- looking through 234 candidates of size 8
+-- tested 198 candidates
+set []  =  True
+set (x:xs)  =  set xs && not (elem x xs)
+
diff --git a/eg/sort.hs b/eg/sort.hs
--- a/eg/sort.hs
+++ b/eg/sort.hs
@@ -1,6 +1,6 @@
 -- sort.hs: conjuring a sort function
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 import Data.List (insert, sort)
diff --git a/eg/sort.out b/eg/sort.out
deleted file mode 100644
--- a/eg/sort.out
+++ /dev/null
@@ -1,61 +0,0 @@
-sort :: [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 6/7 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 23 candidates of size 5
--- tested 24 candidates
-sort []  =  []
-sort (x:xs)  =  insert x (sort xs)
-
-sort :: [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 1/2 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 1 candidates of size 3
--- looking through 4 candidates of size 4
--- tested 6 candidates
-sort xs  =  foldr insert [] xs
-
-qsort :: [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 8/8 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 3 candidates of size 4
--- looking through 6 candidates of size 5
--- looking through 9 candidates of size 6
--- looking through 22 candidates of size 7
--- looking through 37 candidates of size 8
--- looking through 84 candidates of size 9
--- looking through 169 candidates of size 10
--- looking through 352 candidates of size 11
--- looking through 767 candidates of size 12
--- looking through 1600 candidates of size 13
--- looking through 3499 candidates of size 14
--- tested 3668 candidates
-qsort []  =  []
-qsort (x:xs)  =  filter (x >) (qsort xs) ++ (x:filter (x <=) (qsort xs))
-
-merge :: [Int] -> [Int] -> [Int]
--- testing 360 combinations of argument values
--- pruning with 4/4 rules
--- looking through 3 candidates of size 1
--- looking through 7 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 37 candidates of size 4
--- looking through 98 candidates of size 5
--- looking through 94 candidates of size 6
--- looking through 383 candidates of size 7
--- looking through 375 candidates of size 8
--- looking through 1263 candidates of size 9
--- looking through 2252 candidates of size 10
--- looking through 4090 candidates of size 11
--- looking through 13481 candidates of size 12
--- tested 22094 candidates
-cannot conjure
-
diff --git a/eg/sort.txt b/eg/sort.txt
new file mode 100644
--- /dev/null
+++ b/eg/sort.txt
@@ -0,0 +1,61 @@
+sort :: [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 6/7 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 4 candidates of size 3
+-- looking through 11 candidates of size 4
+-- looking through 23 candidates of size 5
+-- tested 22 candidates
+sort []  =  []
+sort (x:xs)  =  insert x (sort xs)
+
+sort :: [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 1/2 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 4 candidates of size 4
+-- tested 5 candidates
+sort xs  =  foldr insert [] xs
+
+qsort :: [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 8/8 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 1 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 6 candidates of size 5
+-- looking through 9 candidates of size 6
+-- looking through 22 candidates of size 7
+-- looking through 37 candidates of size 8
+-- looking through 84 candidates of size 9
+-- looking through 169 candidates of size 10
+-- looking through 352 candidates of size 11
+-- looking through 767 candidates of size 12
+-- looking through 1600 candidates of size 13
+-- looking through 3499 candidates of size 14
+-- tested 3667 candidates
+qsort []  =  []
+qsort (x:xs)  =  filter (x >) (qsort xs) ++ (x:filter (x <=) (qsort xs))
+
+merge :: [Int] -> [Int] -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 3 candidates of size 1
+-- looking through 8 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 23 candidates of size 4
+-- looking through 86 candidates of size 5
+-- looking through 72 candidates of size 6
+-- looking through 297 candidates of size 7
+-- looking through 322 candidates of size 8
+-- looking through 939 candidates of size 9
+-- looking through 1966 candidates of size 10
+-- looking through 2972 candidates of size 11
+-- looking through 11011 candidates of size 12
+-- tested 17710 candidates
+cannot conjure
+
diff --git a/eg/spec.out b/eg/spec.out
deleted file mode 100644
--- a/eg/spec.out
+++ /dev/null
@@ -1,39 +0,0 @@
-square :: Int -> Int
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 6 candidates of size 3
--- tested 9 candidates
-square x  =  x * x
-
-square :: Int -> Int
--- pruning with 14/25 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 6 candidates of size 3
--- tested 9 candidates
-square x  =  x * x
-
-sum :: [Int] -> Int
--- pruning with 4/8 rules
--- looking through 1 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 5 candidates of size 5
--- tested 11 candidates
-sum []  =  0
-sum (x:xs)  =  x + sum xs
-
-(++) :: [Int] -> [Int] -> [Int]
--- pruning with 3/3 rules
--- looking through 2 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 11 candidates of size 3
--- looking through 32 candidates of size 4
--- looking through 100 candidates of size 5
--- looking through 244 candidates of size 6
--- tested 234 candidates
-[] ++ xs  =  xs
-(x:xs) ++ ys  =  x:(xs ++ ys)
-
diff --git a/eg/spec.txt b/eg/spec.txt
new file mode 100644
--- /dev/null
+++ b/eg/spec.txt
@@ -0,0 +1,39 @@
+square :: Int -> Int
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 6 candidates of size 3
+-- tested 9 candidates
+square x  =  x * x
+
+square :: Int -> Int
+-- pruning with 14/25 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 6 candidates of size 3
+-- tested 9 candidates
+square x  =  x * x
+
+sum :: [Int] -> Int
+-- pruning with 4/8 rules
+-- looking through 1 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 3 candidates of size 4
+-- looking through 5 candidates of size 5
+-- tested 9 candidates
+sum []  =  0
+sum (x:xs)  =  x + sum xs
+
+(++) :: [Int] -> [Int] -> [Int]
+-- pruning with 3/3 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 31 candidates of size 4
+-- looking through 94 candidates of size 5
+-- looking through 225 candidates of size 6
+-- tested 212 candidates
+[] ++ xs  =  xs
+(x:xs) ++ ys  =  x:(xs ++ ys)
+
diff --git a/eg/subset.hs b/eg/subset.hs
--- a/eg/subset.hs
+++ b/eg/subset.hs
@@ -1,6 +1,6 @@
 -- subset.hs: conjuring the subset function
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE CPP #-}
 import Conjure
diff --git a/eg/subset.out b/eg/subset.out
deleted file mode 100644
--- a/eg/subset.out
+++ /dev/null
@@ -1,26 +0,0 @@
-subset :: [Int] -> [Int] -> Bool
--- testing 44 combinations of argument values
--- pruning with 29/39 rules
--- looking through 2 candidates of size 1
--- looking through 4 candidates of size 2
--- looking through 8 candidates of size 3
--- looking through 34 candidates of size 4
--- looking through 88 candidates of size 5
--- looking through 40 candidates of size 6
--- looking through 138 candidates of size 7
--- looking through 644 candidates of size 8
--- tested 790 candidates
-subset [] xs  =  True
-subset (x:xs) ys  =  subset xs ys && elem x ys
-
-subset :: [Int] -> [Int] -> Bool
--- testing 44 combinations of argument values
--- pruning with 3/3 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 2 candidates of size 5
--- tested 9 candidates
-subset xs ys  =  sort xs `isSubsequenceOf` sort ys
-
diff --git a/eg/subset.txt b/eg/subset.txt
new file mode 100644
--- /dev/null
+++ b/eg/subset.txt
@@ -0,0 +1,26 @@
+subset :: [Int] -> [Int] -> Bool
+-- testing 44 combinations of argument values
+-- pruning with 29/39 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 8 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 64 candidates of size 5
+-- looking through 40 candidates of size 6
+-- looking through 64 candidates of size 7
+-- looking through 522 candidates of size 8
+-- tested 553 candidates
+subset [] xs  =  True
+subset (x:xs) ys  =  subset xs ys && elem x ys
+
+subset :: [Int] -> [Int] -> Bool
+-- testing 44 combinations of argument values
+-- pruning with 3/3 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 2 candidates of size 5
+-- tested 9 candidates
+subset xs ys  =  sort xs `isSubsequenceOf` sort ys
+
diff --git a/eg/tapps.hs b/eg/tapps.hs
--- a/eg/tapps.hs
+++ b/eg/tapps.hs
@@ -1,6 +1,6 @@
 -- tapps.hs: conjure with (portable) type applications
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ < 800
diff --git a/eg/tapps.out b/eg/tapps.out
deleted file mode 100644
--- a/eg/tapps.out
+++ /dev/null
@@ -1,32 +0,0 @@
-third :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 14/25 rules
--- looking through 2 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 12 candidates of size 4
--- tested 16 candidates
-third xs  =  head (tail (tail xs))
-
-product :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 14/25 rules
--- looking through 2 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 18 candidates of size 5
--- tested 30 candidates
-product []  =  1
-product (x:xs)  =  x * product xs
-
-product :: [Int] -> Int
--- testing 360 combinations of argument values
--- pruning with 15/26 rules
--- looking through 2 candidates of size 1
--- looking through 5 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 15 candidates of size 4
--- tested 18 candidates
-product xs  =  foldr (*) 1 xs
-
diff --git a/eg/tapps.txt b/eg/tapps.txt
new file mode 100644
--- /dev/null
+++ b/eg/tapps.txt
@@ -0,0 +1,32 @@
+third :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 2 candidates of size 1
+-- looking through 5 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 10 candidates of size 4
+-- tested 12 candidates
+third xs  =  head (tail (tail xs))
+
+product :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 14/25 rules
+-- looking through 2 candidates of size 1
+-- looking through 5 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 10 candidates of size 4
+-- looking through 18 candidates of size 5
+-- tested 26 candidates
+product []  =  1
+product (x:xs)  =  x * product xs
+
+product :: [Int] -> Int
+-- testing 360 combinations of argument values
+-- pruning with 15/26 rules
+-- looking through 2 candidates of size 1
+-- looking through 5 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 13 candidates of size 4
+-- tested 14 candidates
+product xs  =  foldr (*) 1 xs
+
diff --git a/eg/tree.hs b/eg/tree.hs
--- a/eg/tree.hs
+++ b/eg/tree.hs
@@ -1,6 +1,6 @@
 -- tree.hs: conjuring functions over trees
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE CPP, TemplateHaskell #-}
 
diff --git a/eg/tree.out b/eg/tree.out
deleted file mode 100644
--- a/eg/tree.out
+++ /dev/null
@@ -1,155 +0,0 @@
-leftmost :: Tree -> Int
--- testing 360 combinations of argument values
--- pruning with 3/3 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 4 candidates of size 6
--- looking through 16 candidates of size 7
--- tested 9 candidates
-leftmost Leaf  =  undefined
-leftmost (Node t1 x t2)  =  if nil t1
-                            then x
-                            else leftmost t1
-
-rightmost :: Tree -> Int
--- testing 360 combinations of argument values
--- pruning with 3/3 rules
--- looking through 1 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 4 candidates of size 6
--- looking through 16 candidates of size 7
--- tested 18 candidates
-rightmost Leaf  =  undefined
-rightmost (Node t1 x t2)  =  if nil t2
-                             then x
-                             else rightmost t2
-
-size :: Tree -> Int
--- testing 360 combinations of argument values
--- pruning with 4/8 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 4 candidates of size 5
--- looking through 8 candidates of size 6
--- looking through 12 candidates of size 7
--- looking through 24 candidates of size 8
--- tested 42 candidates
-size Leaf  =  0
-size (Node t1 x t2)  =  size t1 + (size t2 + 1)
-
-height :: Tree -> Int
--- testing 360 combinations of argument values
--- pruning with 49/65 rules
--- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 14 candidates of size 5
--- looking through 34 candidates of size 6
--- looking through 98 candidates of size 7
--- looking through 283 candidates of size 8
--- tested 202 candidates
-height Leaf  =  -1
-height (Node t1 x t2)  =  1 + max (height t1) (height t2)
-
-mem :: Int -> Tree -> Bool
--- testing 360 combinations of argument values
--- pruning with 11/17 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 5 candidates of size 4
--- looking through 0 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 20 candidates of size 8
--- looking through 0 candidates of size 9
--- looking through 0 candidates of size 10
--- looking through 0 candidates of size 11
--- looking through 96 candidates of size 12
--- tested 92 candidates
-mem x Leaf  =  False
-mem x (Node t1 y t2)  =  mem x t1 || (mem x t2 || x == y)
-
-ordered :: Tree -> Bool
--- testing 360 combinations of argument values
--- pruning with 29/39 rules
--- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 20 candidates of size 6
--- looking through 0 candidates of size 7
--- looking through 32 candidates of size 8
--- looking through 80 candidates of size 9
--- looking through 56 candidates of size 10
--- looking through 450 candidates of size 11
--- looking through 708 candidates of size 12
--- tested 1361 candidates
-cannot conjure
-
-ordered :: Tree -> Bool
--- testing 360 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 3 candidates of size 3
--- tested 3 candidates
-ordered t1  =  strictlyOrdered (inorder t1)
-
-preorder :: Tree -> [Int]
--- testing 360 combinations of argument values
--- pruning with 4/4 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 4 candidates of size 7
--- looking through 9 candidates of size 8
--- tested 17 candidates
-preorder Leaf  =  []
-preorder (Node t1 x t2)  =  x:(preorder t1 ++ preorder t2)
-
-inorder :: Tree -> [Int]
--- testing 360 combinations of argument values
--- pruning with 4/4 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 4 candidates of size 7
--- looking through 9 candidates of size 8
--- tested 21 candidates
-inorder Leaf  =  []
-inorder (Node t1 x t2)  =  inorder t1 ++ (x:inorder t2)
-
-posorder :: Tree -> [Int]
--- testing 360 combinations of argument values
--- pruning with 4/4 rules
--- looking through 1 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 4 candidates of size 7
--- looking through 9 candidates of size 8
--- looking through 14 candidates of size 9
--- looking through 17 candidates of size 10
--- tested 52 candidates
-posorder Leaf  =  []
-posorder (Node t1 x t2)  =  posorder t1 ++ (posorder t2 ++ [x])
-
diff --git a/eg/tree.txt b/eg/tree.txt
new file mode 100644
--- /dev/null
+++ b/eg/tree.txt
@@ -0,0 +1,155 @@
+leftmost :: Tree -> Int
+-- testing 360 combinations of argument values
+-- pruning with 3/3 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 4 candidates of size 6
+-- looking through 16 candidates of size 7
+-- tested 7 candidates
+leftmost Leaf  =  undefined
+leftmost (Node t1 x t2)  =  if nil t1
+                            then x
+                            else leftmost t1
+
+rightmost :: Tree -> Int
+-- testing 360 combinations of argument values
+-- pruning with 3/3 rules
+-- looking through 1 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 4 candidates of size 6
+-- looking through 16 candidates of size 7
+-- tested 16 candidates
+rightmost Leaf  =  undefined
+rightmost (Node t1 x t2)  =  if nil t2
+                             then x
+                             else rightmost t2
+
+size :: Tree -> Int
+-- testing 360 combinations of argument values
+-- pruning with 4/8 rules
+-- looking through 2 candidates of size 1
+-- looking through 2 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 2 candidates of size 4
+-- looking through 4 candidates of size 5
+-- looking through 8 candidates of size 6
+-- looking through 12 candidates of size 7
+-- looking through 24 candidates of size 8
+-- tested 40 candidates
+size Leaf  =  0
+size (Node t1 x t2)  =  size t1 + (size t2 + 1)
+
+height :: Tree -> Int
+-- testing 360 combinations of argument values
+-- pruning with 49/65 rules
+-- looking through 3 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 14 candidates of size 5
+-- looking through 34 candidates of size 6
+-- looking through 98 candidates of size 7
+-- looking through 283 candidates of size 8
+-- tested 200 candidates
+height Leaf  =  -1
+height (Node t1 x t2)  =  1 + max (height t1) (height t2)
+
+mem :: Int -> Tree -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 11/17 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 20 candidates of size 8
+-- looking through 0 candidates of size 9
+-- looking through 0 candidates of size 10
+-- looking through 0 candidates of size 11
+-- looking through 96 candidates of size 12
+-- tested 88 candidates
+mem x Leaf  =  False
+mem x (Node t1 y t2)  =  mem x t1 || (mem x t2 || x == y)
+
+ordered :: Tree -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 29/39 rules
+-- looking through 2 candidates of size 1
+-- looking through 1 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 0 candidates of size 4
+-- looking through 10 candidates of size 5
+-- looking through 20 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 32 candidates of size 8
+-- looking through 80 candidates of size 9
+-- looking through 56 candidates of size 10
+-- looking through 450 candidates of size 11
+-- looking through 708 candidates of size 12
+-- tested 1359 candidates
+cannot conjure
+
+ordered :: Tree -> Bool
+-- testing 360 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 0 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 3
+-- tested 1 candidates
+ordered t1  =  strictlyOrdered (inorder t1)
+
+preorder :: Tree -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 4 candidates of size 7
+-- looking through 9 candidates of size 8
+-- tested 15 candidates
+preorder Leaf  =  []
+preorder (Node t1 x t2)  =  x:(preorder t1 ++ preorder t2)
+
+inorder :: Tree -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 4 candidates of size 7
+-- looking through 9 candidates of size 8
+-- tested 19 candidates
+inorder Leaf  =  []
+inorder (Node t1 x t2)  =  inorder t1 ++ (x:inorder t2)
+
+posorder :: Tree -> [Int]
+-- testing 360 combinations of argument values
+-- pruning with 4/4 rules
+-- looking through 1 candidates of size 1
+-- looking through 0 candidates of size 2
+-- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 4
+-- looking through 2 candidates of size 5
+-- looking through 5 candidates of size 6
+-- looking through 4 candidates of size 7
+-- looking through 9 candidates of size 8
+-- looking through 14 candidates of size 9
+-- looking through 17 candidates of size 10
+-- tested 50 candidates
+posorder Leaf  =  []
+posorder (Node t1 x t2)  =  posorder t1 ++ (posorder t2 ++ [x])
+
diff --git a/mk/depend.mk b/mk/depend.mk
--- a/mk/depend.mk
+++ b/mk/depend.mk
@@ -8,23 +8,48 @@
   mk/toplibs
 bench/candidates.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
   bench/candidates.hs
+bench/erroneous: \
+  bench/erroneous.hs \
+  mk/toplibs
+bench/erroneous.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  src/Conjure/Conjurable/Derive.hs \
+  bench/erroneous.hs
 bench/gps2: \
   bench/gps2.hs \
   mk/toplibs
 bench/gps2.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -34,10 +59,14 @@
   mk/toplibs
 bench/gps.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -47,10 +76,14 @@
   mk/toplibs
 bench/ill-hit.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -60,10 +93,14 @@
   mk/toplibs
 bench/longshot.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -73,10 +110,14 @@
   mk/toplibs
 bench/lowtests.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -86,10 +127,14 @@
   mk/toplibs
 bench/p12.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -99,10 +144,14 @@
   mk/toplibs
 bench/p30.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -112,10 +161,14 @@
   mk/toplibs
 bench/redundants.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -125,10 +178,14 @@
   mk/toplibs
 bench/self.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -138,10 +195,14 @@
   mk/toplibs
 bench/take-drop.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -151,10 +212,14 @@
   mk/toplibs
 bench/terpret.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -164,10 +229,14 @@
   mk/toplibs
 bench/weird.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -177,10 +246,14 @@
   mk/toplibs
 eg/arith.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -190,10 +263,14 @@
   mk/toplibs
 eg/bools.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -203,10 +280,14 @@
   mk/toplibs
 eg/bst.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -216,10 +297,14 @@
   mk/toplibs
 eg/count.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -229,23 +314,48 @@
   mk/toplibs
 eg/dupos.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
   eg/dupos.hs
+eg/either: \
+  eg/either.hs \
+  mk/toplibs
+eg/either.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  src/Conjure/Conjurable/Derive.hs \
+  eg/either.hs
 eg/factorial: \
   eg/factorial.hs \
   mk/toplibs
 eg/factorial.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -255,10 +365,14 @@
   mk/toplibs
 eg/fib01.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -268,10 +382,14 @@
   mk/toplibs
 eg/fibonacci.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -281,10 +399,14 @@
   mk/toplibs
 eg/gcd.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -294,10 +416,14 @@
   mk/toplibs
 eg/higher.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -307,10 +433,14 @@
   mk/toplibs
 eg/id.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -320,10 +450,14 @@
   mk/toplibs
 eg/ints.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -333,23 +467,65 @@
   mk/toplibs
 eg/list.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
   eg/list.hs
+eg/maybe: \
+  eg/maybe.hs \
+  mk/toplibs
+eg/maybe.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  src/Conjure/Conjurable/Derive.hs \
+  eg/maybe.hs
+eg/oddeven: \
+  eg/oddeven.hs \
+  mk/toplibs
+eg/oddeven.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  src/Conjure/Conjurable/Derive.hs \
+  eg/oddeven.hs
 eg/pow: \
   eg/pow.hs \
   mk/toplibs
 eg/pow.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -359,10 +535,14 @@
   mk/toplibs
 eg/replicate.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -372,10 +552,14 @@
   mk/toplibs
 eg/setelem.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -385,10 +569,14 @@
   mk/toplibs
 eg/sort.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -398,10 +586,14 @@
   mk/toplibs
 eg/spec.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -411,10 +603,14 @@
   mk/toplibs
 eg/subset.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -424,10 +620,14 @@
   mk/toplibs
 eg/tapps.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -437,20 +637,28 @@
   mk/toplibs
 eg/tree.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
   eg/tree.hs
 mk/All.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -459,10 +667,14 @@
   test/Test.hs \
   test/Test/ListableExpr.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs \
@@ -487,11 +699,26 @@
   src/Conjure/Utils.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Defn.hs
+src/Conjure/Defn/Redundancy.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Defn/Redundancy.hs \
+  src/Conjure/Defn.hs
+src/Conjure/Defn/Test.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs
 src/Conjure/Engine.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs
 src/Conjure/Expr.o: \
@@ -499,10 +726,14 @@
   src/Conjure/Expr.hs
 src/Conjure.o: \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
@@ -512,6 +743,16 @@
   src/Conjure/Expr.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs
+src/Conjure/Reason.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Reason.hs \
+  src/Conjure/Expr.hs
+src/Conjure/Red.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs
 src/Conjure/Utils.o: \
   src/Conjure/Utils.hs
 test/conjurable.o: \
@@ -519,10 +760,14 @@
   test/Test/ListableExpr.hs \
   test/conjurable.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
@@ -536,10 +781,14 @@
   test/Test/ListableExpr.hs \
   test/defn.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
@@ -553,10 +802,14 @@
   test/Test/ListableExpr.hs \
   test/derive.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
@@ -570,10 +823,14 @@
   test/Test/ListableExpr.hs \
   test/expr.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
@@ -582,16 +839,41 @@
   test/Test/ListableExpr.hs \
   test/expr.hs \
   mk/toplibs
+test/red.o: \
+  test/Test.hs \
+  test/Test/ListableExpr.hs \
+  test/red.hs \
+  src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  src/Conjure/Conjurable/Derive.hs
+test/red: \
+  test/Test.hs \
+  test/Test/ListableExpr.hs \
+  test/red.hs \
+  mk/toplibs
 test/Test/ListableExpr.o: \
   test/Test/ListableExpr.hs
 test/Test.o: \
   test/Test.hs \
   test/Test/ListableExpr.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
@@ -604,10 +886,14 @@
   test/Test.hs \
   test/Test/ListableExpr.hs \
   src/Conjure/Utils.hs \
+  src/Conjure/Red.hs \
+  src/Conjure/Reason.hs \
   src/Conjure/Prim.hs \
   src/Conjure.hs \
   src/Conjure/Expr.hs \
   src/Conjure/Engine.hs \
+  src/Conjure/Defn/Test.hs \
+  src/Conjure/Defn/Redundancy.hs \
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   src/Conjure/Conjurable/Derive.hs
diff --git a/mk/ghcdeps b/mk/ghcdeps
--- a/mk/ghcdeps
+++ b/mk/ghcdeps
@@ -2,7 +2,7 @@
 #
 # ghcdeps: generate Haskell make dependencies for compiling with GHC.
 #
-# Copyright (c) 2015-2021 Rudy Matela.
+# Copyright (c) 2015-2024 Rudy Matela.
 # Distributed under the 3-Clause BSD licence.
 #
 # From a list of files provided on standard input,
diff --git a/mk/haddock-i b/mk/haddock-i
--- a/mk/haddock-i
+++ b/mk/haddock-i
@@ -2,7 +2,7 @@
 #
 # haddock-i: list haddock's -i parameters.
 #
-# Copyright (c) 2015-2021 Rudy Matela.
+# Copyright (c) 2015-2024 Rudy Matela.
 # Distributed under the 3-Clause BSD licence.
 #
 # $ haddock-i <package1> <package2> ... <packageN>
diff --git a/mk/install-on b/mk/install-on
--- a/mk/install-on
+++ b/mk/install-on
@@ -2,7 +2,7 @@
 #
 # mk/install-on: install or updates the mk folder on a Haskell project
 #
-# Copyright (c) 2019-2021 Rudy Matela.
+# Copyright (c) 2019-2024 Rudy Matela.
 # Distributed under the 3-Clause BSD licence.
 #
 # usage: ./mk/install-on path/to/project
diff --git a/proto/u-conjure.hs b/proto/u-conjure.hs
--- a/proto/u-conjure.hs
+++ b/proto/u-conjure.hs
@@ -4,7 +4,7 @@
 -- out of partially implemented functions.
 --
 --
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 --
 --
diff --git a/proto/u-conjure.out b/proto/u-conjure.out
deleted file mode 100644
--- a/proto/u-conjure.out
+++ /dev/null
@@ -1,24 +0,0 @@
-square :: Int -> Int
-square x  =  x * x
-
-add :: Int -> Int -> Int
-add x y  =  x + y
-
-factorial :: Int -> Int
-cannot conjure
-
-factorial :: Int -> Int
-factorial x  =  foldr (*) 1 (enumFromTo 1 x)
-
-second :: [Int] -> Int
-second xs  =  head (tail xs)
-
-(++) :: [Int] -> [Int] -> [Int]
-xs ++ ys  =  foldr (:) ys xs
-
-reverse :: [Int] -> [Int]
-cannot conjure
-
-reverse :: [Int] -> [Int]
-reverse xs  =  foldr (foldr (:) . unit) [] xs
-
diff --git a/proto/u-conjure.txt b/proto/u-conjure.txt
new file mode 100644
--- /dev/null
+++ b/proto/u-conjure.txt
@@ -0,0 +1,24 @@
+square :: Int -> Int
+square x  =  x * x
+
+add :: Int -> Int -> Int
+add x y  =  x + y
+
+factorial :: Int -> Int
+cannot conjure
+
+factorial :: Int -> Int
+factorial x  =  foldr (*) 1 (enumFromTo 1 x)
+
+second :: [Int] -> Int
+second xs  =  head (tail xs)
+
+(++) :: [Int] -> [Int] -> [Int]
+xs ++ ys  =  foldr (:) ys xs
+
+reverse :: [Int] -> [Int]
+cannot conjure
+
+reverse :: [Int] -> [Int]
+reverse xs  =  foldr (foldr (:) . unit) [] xs
+
diff --git a/src/Conjure.hs b/src/Conjure.hs
--- a/src/Conjure.hs
+++ b/src/Conjure.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
diff --git a/src/Conjure/Conjurable.hs b/src/Conjure/Conjurable.hs
--- a/src/Conjure/Conjurable.hs
+++ b/src/Conjure/Conjurable.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure.Conjurable
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -23,12 +23,12 @@
   , conjurePats
   , conjureHoles
   , conjureTiersFor
+  , conjureListFor
+  , conjureSizeFor
+  , conjureGrounds
   , conjureAreEqual
   , conjureMkEquation
   , A, B, C, D, E, F
-  , conjureIsDeconstruction
-  , candidateDeconstructionsFrom
-  , candidateDeconstructionsFromHoled
   , conjureIsUnbreakable
   , conjureReification
   , conjureReification1
@@ -49,7 +49,6 @@
 import Test.LeanCheck.Error (errorToFalse)
 import Conjure.Expr hiding (application)
 import Conjure.Defn
-import Test.Speculate.Expr
 import Data.Functor ((<$>))
 import Control.Applicative ((<*>))
 import Data.Dynamic
@@ -214,7 +213,6 @@
 -- 'conjureMkEquation',
 -- 'conjureAreEqual',
 -- 'conjureTiersFor',
--- 'conjureIsDeconstructor',
 -- 'conjureNamesFor',
 -- 'conjureIsUnbreakable',
 -- etc.
@@ -297,7 +295,7 @@
   (-==-)  =  conjureMkEquation f
   e1 === e2  =  isTrue $ e1 -==- e2
   isTrue  =  all (errorToFalse . eval False) . gs
-  gs  =  take maxTests . grounds (conjureTiersFor f)
+  gs  =  take maxTests . conjureGrounds f
 
 -- | Compute 'tiers' of values encoded as 'Expr's
 --   of the type of the given 'Expr'.
@@ -311,8 +309,16 @@
                       ((e':_):_) | typ e' == typ e -> etiers
                       _                            -> tf etc
 
+conjureGrounds :: Conjurable f => f -> Expr -> [Expr]
+conjureGrounds  =  grounds . conjureTiersFor
+
+-- | Compure a 'list' of values encoded as 'Expr's
+--   of the type of the given 'Expr'.
+conjureListFor :: Conjurable f => f -> Expr -> [Expr]
+conjureListFor f  =  concat . conjureTiersFor f
+
 conjureIsNumeric :: Conjurable f => f -> Expr -> Bool
-conjureIsNumeric f e  =  case concat $ conjureTiersFor f e of
+conjureIsNumeric f e  =  case conjureListFor f e of
                          -- We assume tiers of numeric values start with 0
                          -- not so unfair...
                          (Value "0" _):_ -> True
@@ -328,78 +334,22 @@
 conjureMostGeneralCanonicalVariation f  =  canonicalizeWith (conjureNamesFor f)
                                         .  fastMostGeneralVariation
 
--- | Checks if an expression is a deconstruction.
---
--- There should be a single 'hole' in the expression.
---
--- It should decrease the size of all arguments that have
--- a size greater than 0.
---
--- (cf. 'conjureIsDeconstructor')
-conjureIsDeconstruction :: Conjurable f => f -> Int -> Expr -> Bool
-conjureIsDeconstruction f maxTests ed  =  length (holes ed) == 1
-                                       && typ h == typ ed
-                                       && all is gs
-  where
-  gs  =  take maxTests $ grounds (conjureTiersFor f) ed
-  [h]  =  holes ed
-  sz  =  head [sz | (_, _, _, _, _, sz) <- conjureReification f
-                  , isWellTyped (sz :$ h)]
-  esz e  =  eval (0::Int) (sz :$ e)
-  x << 0  =  True
-  x << y  =  x < y
-  is e  =  errorToFalse $ esz e << esz (holeValue e)
-  holeValue e  =  fromMaybe err
-               .  lookup h
-               .  fromMaybe err
-               $  e `match` ed
-  err  =  error "conjureIsDeconstructor: the impossible happened"
 
-
--- | Compute candidate deconstructions from an 'Expr'.
---
--- This is used in the implementation of 'Conjure.Engine.candidateDefnsC'
--- followed by 'conjureIsDeconstruction'.
---
--- > > candidateDeconstructionsFrom (xx `mod'` yy)
--- > [ _ `mod` y
--- > , x `mod` _
--- > ]
---
--- To be constrasted with 'candidateDeconstructionsFromHoled'.
-candidateDeconstructionsFrom :: Expr -> [Expr]
-candidateDeconstructionsFrom e  =
-  [ e'
-  | v <- vars e
-  , typ v == typ e
-  , let e' = e //- [(v, holeAsTypeOf v)]
-  , length (holes e') == 1
-  ]
-
--- | Compute candidate deconstructions from an 'Expr'.
---
--- This is used in the implementation of 'Conjure.Engine.candidateExprs'
--- followed by 'conjureIsDeconstruction'.
+-- | Conjures an 'Expr'-encoded size function for the given expression type.
 --
--- This is similar to 'canonicalVariations'
--- but always leaves a hole
--- of the same return type as the given expression.
+-- > > conjureSizeFor (undefined :: [Int] -> [Bool]) i_
+-- > conjureSize :: Int -> Int
 --
--- > > candidateDeconstructionsFrom (i_ `mod'` i_)
--- > [ _ `mod` x
--- > , x `mod` _
--- > ]
+-- > > conjureSizeFor (undefined :: [Int] -> [Bool]) is_
+-- > conjureSize :: [Int] -> Int
 --
--- To be contrasted with 'candidateDeconstructionsFrom'
-candidateDeconstructionsFromHoled :: Expr -> [Expr]
-candidateDeconstructionsFromHoled e  =  map (//- [(v, h)])
-                                     $  concatMap canonicalVariations
-                                     $  deholings v e
-  where
-  h  =  holeAsTypeOf e
-  v  =  "_#_" `varAsTypeOf` e  -- a marker variable with an invalid name
-  -- at some point I should get rid of candidateDeconstructionsFrom in favour
-  -- of this one
+-- > > conjureSizeFor (undefined :: [Int] -> [Bool]) bs_
+-- > conjureSize :: [Bool] -> Int
+conjureSizeFor :: Conjurable f => f -> Expr -> Expr
+conjureSizeFor f eh  =
+  case [esz | (_,_,_,_,_,esz) <- conjureReification f, isWellTyped (esz :$ eh)] of
+  (esz:_) -> esz
+  _ -> error $ "Conjure.conjureSizeFor: could not find size for " ++ show eh
 
 -- | Checks if an 'Expr' is of an unbreakable type.
 conjureIsUnbreakable :: Conjurable f => f -> Expr -> Bool
@@ -551,8 +501,8 @@
                        , value "Right" (Right ->: exy) :$ hole y
                        ]
     where
-    x  =  Left undefined -: exy
-    y  =  Right undefined -: exy
+    Left x  =  Left undefined -: exy
+    Right y  =  Right undefined -: exy
   conjureEquality elr  =  from <$> conjureEquality l <*> conjureEquality r
     where
     Left l   =  elr
diff --git a/src/Conjure/Conjurable/Derive.hs b/src/Conjure/Conjurable/Derive.hs
--- a/src/Conjure/Conjurable/Derive.hs
+++ b/src/Conjure/Conjurable/Derive.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE TemplateHaskell, CPP #-}
 -- |
 -- Module      : Conjure.Conjurable.Derive
--- Copyright   : (c) 2019-2021 Rudy Matela
+-- Copyright   : (c) 2019-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
diff --git a/src/Conjure/Defn.hs b/src/Conjure/Defn.hs
--- a/src/Conjure/Defn.hs
+++ b/src/Conjure/Defn.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure.Defn
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -21,21 +21,14 @@
   , showDefn
   , printDefn
   , defnApparentlyTerminates
-  , isRedundantDefn
-  , isRedundantBySubsumption
-  , isRedundantByRepetition
-  , isRedundantByIntroduction
-  , hasRedundantRecursion
   , isCompleteDefn
   , isCompleteBndn
-  , simplifyDefn
   , canonicalizeBndn
   , canonicalizeBndnLast
   , hasUnbound
   , noUnbound
   , isUndefined
   , isDefined
-  , introduceVariableAt
   , isBaseCase
   , isRecursiveCase
   , isRecursiveDefn
@@ -229,155 +222,6 @@
 defnApparentlyTerminates [(efxs, e)]  =  apparentlyTerminates efxs e
 defnApparentlyTerminates _  =  True
 
--- | Returns whether the given 'Defn' is redundant
---   with regards to repetitions on RHSs.
---
--- Here is an example of a redundant 'Defn':
---
--- > 0 ? 0  =  1
--- > 0 ? x  =  1
--- > x ? 0  =  x
--- > x ? y  =  x
---
--- It is redundant because it is equivalent to:
---
--- > 0 ? _  =  1
--- > x ? _  =  x
---
--- This function safely handles holes on the RHSs
--- by being conservative in cases these are found:
--- nothing can be said before their fillings.
-isRedundantDefn :: Defn -> Bool
-isRedundantDefn d  =  isRedundantBySubsumption d
-                   || isRedundantByRepetition d
---                 || isRedundantByIntroduction d
--- we do not use isRedundantByIntroduction above
--- as it does not pay off in terms of runtime vs number of pruned candidates
---
--- The number of candidates is reduced usually by less than 1%
--- and the runtime increases by 50% or sometimes 100%.
-
--- | Returns whether the given 'Defn' is redundant
---   with regards to repetitions on RHSs.
---
--- Here is an example of a redundant 'Defn':
---
--- > 0 ? 0  =  1
--- > 0 ? x  =  1
--- > x ? 0  =  x
--- > x ? y  =  x
---
--- It is redundant because it is equivalent to:
---
--- > 0 ? _  =  1
--- > x ? _  =  x
---
--- @1@ and @x@ are repeated in the results for when
--- the first arguments are @0@ and @x@.
-isRedundantByRepetition :: Defn -> Bool
-isRedundantByRepetition d  =  any anyAllEqual shovels
-  where
-  nArgs  =  length . tail . unfoldApp . fst $ head d
-  shovels :: [Expr -> Expr]
-  shovels  =  [digApp n | n <- [1..nArgs]]
-  anyAllEqual :: (Expr -> Expr) -> Bool
-  anyAllEqual shovel  =  any (\bs -> allEqual2 bs && isDefined bs)
-                      .  classifyOn fst
-                      .  map (canonicalizeBndn . first shovel)
-                      $  d
-
--- | Returns whether the given 'Defn' is redundant
---   with regards to case elimination
---
--- The following is redundant according to this criterium:
---
--- > foo []  =  []
--- > foo (x:xs)  =  x:xs
---
--- It is equivalent to:
---
--- > foo xs = xs
---
--- The following is also redundant:
---
--- > [] ?? xs  =  []
--- > (x:xs) ?? ys  =  x:xs
---
--- as it is equivalent to:
---
--- > xs ?? ys == xs
---
--- This function is not used as one of the criteria in 'isRedundantDefn'
--- because it does not pay-off
--- in terms of runtime vs number of pruned candidates.
-isRedundantByIntroduction :: Defn -> Bool
-isRedundantByIntroduction d  =  any anyAllEqual [1..nArgs]
-  where
-  nArgs  =  length . tail . unfoldApp . fst $ head d
-  anyAllEqual :: Int -> Bool
-  anyAllEqual i  =  any (\bs -> length bs >= 2 && isDefined bs && noConflicts i bs)
-                 .  classifyOn (digApp i . fst)
-                 .  map (canonicalizeBndnLast i)
-                 $  d
-  noConflicts :: Int -> [Bndn] -> Bool
-  noConflicts i bs  =  case listConflicts (map snd bs) of
-                       [] -> True
-                       [es] -> es == [efxs $!! i | (efxs,_) <- bs]
-                       _ -> False
-
--- | Returns whether the given 'Defn' is redundant
---   with regards to recursions
---
--- The following is redundant:
---
--- > xs ?? []  =  []
--- > xs ?? (x:ys)  =  xs ?? []
---
--- The LHS of a base-case pattern, matches the RHS of a recursive pattern.
--- The second RHS may be replaced by simply @[]@ which makes it redundant.
-hasRedundantRecursion :: Defn -> Bool
-hasRedundantRecursion d  =  not (null rs) && any matchesRHS bs
-  where
-  (bs,rs)  =  partition isBaseCase d
-  matchesRHS (lhs,_)  =  any ((`hasAppInstanceOf` lhs) . snd) rs
-
--- | Introduces a hole at a given position in the binding:
---
--- > > introduceVariableAt 1 (xxs -?- (yy -:- yys), (yy -:- yys) -++- (yy -:- yys))
--- > (xs ? (y:ys) :: [Int],(y:ys) ++ (y:ys) :: [Int])
---
--- > > introduceVariableAt 2 (xxs -?- (yy -:- yys), (yy -:- yys) -++- (yy -:- yys))
--- > (xs ? x :: [Int],x ++ x :: [Int])
---
--- Relevant occurrences are replaced.
-introduceVariableAt :: Int -> Bndn -> Bndn
-introduceVariableAt i b@(l,r)
-  | isVar p    =  b -- already a variable
--- | isGround p  =  (newVar, r)  -- enabling catches a different set of candidates
-  | otherwise  =  unfoldPair
-               $  foldPair b // [(p,newVar)]
-  where
-  p  =  l $!! i
-  newVar  =  newName `varAsTypeOf` p
-  newName  =  head $ variableNamesFromTemplate "x" \\ varnames l
-  varnames :: Expr -> [String]
-  varnames e  =  [n | Value ('_':n) _ <- vars e]
-
--- | Returns whether the given 'Defn' is redundant
---   with regards to subsumption by latter patterns
---
--- Here is an example of a redundant 'Defn' by this criterium:
---
--- > foo 0  =  0
--- > foo x  =  x
-isRedundantBySubsumption :: Defn -> Bool
-isRedundantBySubsumption  =  is . map foldPair . filter isCompleteBndn
-  -- above, we could have used noUnbound instead of isCompleteBndn
-  -- we use isCompleteBndn as it is faster
-  where
-  is []  =  False
-  is (b:bs)  =  any (b `isInstanceOf`) bs || is bs
-
 -- | Returns whether the definition is complete,
 --   i.e., whether it does not have any holes in the RHS.
 isCompleteDefn :: Defn -> Bool
@@ -387,21 +231,6 @@
 --   i.e., whether it does not have any holes in the RHS.
 isCompleteBndn :: Bndn -> Bool
 isCompleteBndn (_,rhs)  =  isComplete rhs
-
--- | Simplifies a definition by removing redundant patterns
---
--- This may be useful in the following case:
---
--- > 0 ^^^ 0  =  0
--- > 0 ^^^ x  =  x
--- > x ^^^ 0  =  x
--- > _ ^^^ _  =  0
---
--- The first pattern is subsumed by the last pattern.
-simplifyDefn :: Defn -> Defn
-simplifyDefn []  =  []
-simplifyDefn (b:bs)  =  [b | none (foldPair b `isInstanceOf`) $ map foldPair bs]
-                     ++ simplifyDefn bs
 
 canonicalizeBndn :: Bndn -> Bndn
 canonicalizeBndn  =  unfoldPair . canonicalize . foldPair
diff --git a/src/Conjure/Defn/Redundancy.hs b/src/Conjure/Defn/Redundancy.hs
new file mode 100644
--- /dev/null
+++ b/src/Conjure/Defn/Redundancy.hs
@@ -0,0 +1,246 @@
+-- |
+-- Module      : Conjure.Defn.Redundancy
+-- Copyright   : (c) 2021-2024 Rudy Matela
+-- License     : 3-Clause BSD  (see the file LICENSE)
+-- Maintainer  : Rudy Matela <rudy@matela.com.br>
+--
+-- This module is part of "Conjure".
+--
+-- This module exports functions that check redundancy in 'Defn's.
+--
+-- You are probably better off importing "Conjure".
+module Conjure.Defn.Redundancy
+  ( isRedundantDefn
+  , isRedundantBySubsumption
+  , isRedundantByRepetition
+  , isRedundantByIntroduction
+  , isRedundantModuloRewriting
+  , hasRedundantRecursion
+  , subsumedWith
+  , simplifyDefn
+  , introduceVariableAt
+  )
+where
+
+import Conjure.Defn
+
+-- | Returns whether the given 'Defn' is redundant
+--   with regards to repetitions on RHSs.
+--
+-- Here is an example of a redundant 'Defn':
+--
+-- > 0 ? 0  =  1
+-- > 0 ? x  =  1
+-- > x ? 0  =  x
+-- > x ? y  =  x
+--
+-- It is redundant because it is equivalent to:
+--
+-- > 0 ? _  =  1
+-- > x ? _  =  x
+--
+-- This function safely handles holes on the RHSs
+-- by being conservative in cases these are found:
+-- nothing can be said before their fillings.
+isRedundantDefn :: Defn -> Bool
+isRedundantDefn d  =  isRedundantBySubsumption d
+                   || isRedundantByRepetition d
+                   || isRedundantByRootRecursions d
+--                 || isRedundantByIntroduction d
+-- we do not use isRedundantByIntroduction above
+-- as it does not pay off in terms of runtime vs number of pruned candidates
+--
+-- The number of candidates is reduced usually by less than 1%
+-- and the runtime increases by 50% or sometimes 100%.
+
+
+-- | Returns whether the given 'Defn' is redundant
+--   with regards to repetitions on RHSs.
+--
+-- Here is an example of a redundant 'Defn':
+--
+-- > 0 ? 0  =  1
+-- > 0 ? x  =  1
+-- > x ? 0  =  x
+-- > x ? y  =  x
+--
+-- It is redundant because it is equivalent to:
+--
+-- > 0 ? _  =  1
+-- > x ? _  =  x
+--
+-- @1@ and @x@ are repeated in the results for when
+-- the first arguments are @0@ and @x@.
+isRedundantByRepetition :: Defn -> Bool
+isRedundantByRepetition d  =  any anyAllEqual shovels
+  where
+  nArgs  =  length . tail . unfoldApp . fst $ head d
+  shovels :: [Expr -> Expr]
+  shovels  =  [digApp n | n <- [1..nArgs]]
+  anyAllEqual :: (Expr -> Expr) -> Bool
+  anyAllEqual shovel  =  any (\bs -> allEqual2 bs && isDefined bs)
+                      .  classifyOn fst
+                      .  map (canonicalizeBndn . first shovel)
+                      $  d
+
+-- | Returns whether the given 'Defn' is redundant
+--   with regards to case elimination
+--
+-- The following is redundant according to this criterium:
+--
+-- > foo []  =  []
+-- > foo (x:xs)  =  x:xs
+--
+-- It is equivalent to:
+--
+-- > foo xs = xs
+--
+-- The following is also redundant:
+--
+-- > [] ?? xs  =  []
+-- > (x:xs) ?? ys  =  x:xs
+--
+-- as it is equivalent to:
+--
+-- > xs ?? ys == xs
+--
+-- This function is not used as one of the criteria in 'isRedundantDefn'
+-- because it does not pay-off
+-- in terms of runtime vs number of pruned candidates.
+isRedundantByIntroduction :: Defn -> Bool
+isRedundantByIntroduction d  =  any anyAllEqual [1..nArgs]
+  where
+  nArgs  =  length . tail . unfoldApp . fst $ head d
+  anyAllEqual :: Int -> Bool
+  anyAllEqual i  =  any (\bs -> length bs >= 2 && isDefined bs && noConflicts i bs)
+                 .  classifyOn (digApp i . fst)
+                 .  map (canonicalizeBndnLast i)
+                 $  d
+  noConflicts :: Int -> [Bndn] -> Bool
+  noConflicts i bs  =  case listConflicts (map snd bs) of
+                       [] -> True
+                       [es] -> es == [efxs $!! i | (efxs,_) <- bs]
+                       _ -> False
+
+-- | Returns whether the given 'Defn' is redundant
+--   with regards to recursions
+--
+-- The following is redundant:
+--
+-- > xs ?? []  =  []
+-- > xs ?? (x:ys)  =  xs ?? []
+--
+-- The LHS of a base-case pattern, matches the RHS of a recursive pattern.
+-- The second RHS may be replaced by simply @[]@ which makes it redundant.
+hasRedundantRecursion :: Defn -> Bool
+hasRedundantRecursion d  =  not (null rs) && any matchesRHS bs
+  where
+  (bs,rs)  =  partition isBaseCase d
+  matchesRHS (lhs,_)  =  any ((`hasAppInstanceOf` lhs) . snd) rs
+
+-- | Returns whether a given 'Defn' is redundant
+--   with regards to root recursions.
+--
+-- When there is a single base case and all recursive calls
+-- are at the root: we have a redundant function.
+-- (Modulo error functions, which are undesired anyway.)
+--
+-- > xs ? []  =  []
+-- > xs ? (x:ys)  =  xs ? ys
+--
+-- Above it does not really pays off to follow the recursive calls,
+-- at the end we always reach an empty list.
+--
+-- The same goes for the following:
+--
+-- > xs ? []  =  xs
+-- > xs ? (x:ys)  =  xs ? ys
+isRedundantByRootRecursions :: Defn -> Bool
+isRedundantByRootRecursions d  =  case partition isGround $ map snd d of
+  ([b], rs@(_:_))  ->  all isHole rs
+  (bs@(_:_), rs@(_:_))  -> all isHole rs && all isGround bs && allEqual bs
+  _  -> False
+
+-- | Introduces a hole at a given position in the binding:
+--
+-- > > introduceVariableAt 1 (xxs -?- (yy -:- yys), (yy -:- yys) -++- (yy -:- yys))
+-- > (xs ? (y:ys) :: [Int],(y:ys) ++ (y:ys) :: [Int])
+--
+-- > > introduceVariableAt 2 (xxs -?- (yy -:- yys), (yy -:- yys) -++- (yy -:- yys))
+-- > (xs ? x :: [Int],x ++ x :: [Int])
+--
+-- Relevant occurrences are replaced.
+introduceVariableAt :: Int -> Bndn -> Bndn
+introduceVariableAt i b@(l,r)
+  | isVar p    =  b -- already a variable
+-- | isGround p  =  (newVar, r)  -- enabling catches a different set of candidates
+  | otherwise  =  unfoldPair
+               $  foldPair b // [(p,newVar)]
+  where
+  p  =  l $!! i
+  newVar  =  newName `varAsTypeOf` p
+  newName  =  head $ variableNamesFromTemplate "x" \\ varnames l
+  varnames :: Expr -> [String]
+  varnames e  =  [n | Value ('_':n) _ <- vars e]
+
+-- | Returns whether the given 'Defn' is redundant
+--   with regards to subsumption by latter patterns
+--
+-- Here is an example of a redundant 'Defn' by this criterium:
+--
+-- > foo 0  =  0
+-- > foo x  =  x
+isRedundantBySubsumption :: Defn -> Bool
+isRedundantBySubsumption  =  is . map foldPair . filter isCompleteBndn
+  -- above, we could have used noUnbound instead of isCompleteBndn
+  -- we use isCompleteBndn as it is faster
+  where
+  is []  =  False
+  is (b:bs)  =  any (b `isInstanceOf`) bs || is bs
+
+-- | Returns whether the given 'Defn' is redundant modulo
+--   subsumption and rewriting.
+--
+-- (cf. 'subsumedWith')
+isRedundantModuloRewriting :: (Expr -> Expr) -> Defn -> Bool
+isRedundantModuloRewriting normalize  =  is
+  where
+  is []  =  False
+  is (b:bs)  =  any (subsumedWith normalize b) bs
+             || is bs
+
+-- | Simplifies a definition by removing redundant patterns
+--
+-- This may be useful in the following case:
+--
+-- > 0 ^^^ 0  =  0
+-- > 0 ^^^ x  =  x
+-- > x ^^^ 0  =  x
+-- > _ ^^^ _  =  0
+--
+-- The first pattern is subsumed by the last pattern.
+simplifyDefn :: Defn -> Defn
+simplifyDefn []  =  []
+simplifyDefn (b:bs)  =  [b | none (foldPair b `isInstanceOf`) $ map foldPair bs]
+                     ++ simplifyDefn bs
+
+-- | Returns whether a binding is subsumed by another modulo rewriting
+--
+-- > > let normalize = (// [(zero -+- zero, zero)])
+-- > > subsumedWith normalize (ff zero, zero) (ff xx, xx -+- xx)
+-- > True
+--
+-- > > subsumedWith normalize (ff zero, zero) (ff xx, xx -+- one)
+-- > False
+--
+-- > > subsumedWith normalize (zero -?- xx, zero) (xx -?- yy, xx -+- xx)
+-- > True
+--
+-- (cf. 'isRedundantModuloRewriting')
+subsumedWith :: (Expr -> Expr) -> Bndn -> Bndn -> Bool
+subsumedWith normalize (lhs1,rhs1) (lhs2,rhs2)
+  | hasHole rhs2  =  False
+  | otherwise  =  case lhs1 `match` lhs2 of
+                  Nothing -> False
+                  Just bs -> snd (canonicalizeBndn (lhs2, normalize $ rhs2 //- bs))
+                          == snd (canonicalizeBndn (lhs1, rhs1))
diff --git a/src/Conjure/Defn/Test.hs b/src/Conjure/Defn/Test.hs
new file mode 100644
--- /dev/null
+++ b/src/Conjure/Defn/Test.hs
@@ -0,0 +1,86 @@
+-- |
+-- Module      : Conjure.Defn.Test
+-- Copyright   : (c) 2021-2024 Rudy Matela
+-- License     : 3-Clause BSD  (see the file LICENSE)
+-- Maintainer  : Rudy Matela <rudy@matela.com.br>
+--
+-- This module is part of "Conjure".
+--
+-- This module exports functions that test 'Defn's using ground values.
+--
+-- You are probably better off importing "Conjure".
+module Conjure.Defn.Test
+  ( equalModuloTesting
+  , erroneousCandidate
+  , findDefnError
+  )
+where
+
+import Conjure.Defn
+import Conjure.Conjurable
+
+import Test.LeanCheck.Error (errorToFalse, errorToNothing)
+
+import Data.Dynamic (fromDyn, dynApp)
+
+
+equalModuloTesting :: Conjurable f => Int -> Int -> String -> f -> Defn -> Defn -> Bool
+equalModuloTesting maxTests maxEvalRecursions nm f  =  (===)
+  where
+  testGrounds  =  nonNegativeAppGrounds maxTests maxEvalRecursions nm f
+  d1 === d2  =  all are $ testGrounds
+    where
+    -- silences errors, ok since this is for optional measuring of optimal pruning
+    are :: Expr -> Bool
+    are e  =  isError (ee d1 d1 e)
+           && isError (ee d2 d2 e)
+           || errorToFalse (ee d1 d2 e)
+           where  ee  =  devlEqual maxEvalRecursions f
+
+
+-- | For debugging purposes.
+--
+-- This may be taken out of the API at any moment.
+erroneousCandidate :: Conjurable f => Int -> Int -> String -> f -> Defn -> Bool
+erroneousCandidate maxTests maxEvalRecursions nm f  =
+  isJust . findDefnError maxTests maxEvalRecursions nm f
+
+
+-- | For debugging purposes,
+--   finds a set of arguments that triggers an error in the candidate 'Defn'.
+--
+-- Warning: this is an experimental function
+-- which may be taken out of the API at any moment.
+findDefnError :: Conjurable f => Int -> Int -> String -> f -> Defn -> Maybe Expr
+findDefnError maxTests maxEvalRecursions nm f d  =
+  find is testGrounds
+  where
+  testGrounds  =  nonNegativeAppGrounds maxTests maxEvalRecursions nm f
+  is :: Expr -> Bool
+  is e  =  isError (devlEqual maxEvalRecursions f d d e)
+
+
+nonNegativeAppGrounds :: Conjurable f => Int -> Int -> String -> f -> [Expr]
+nonNegativeAppGrounds maxTests maxEvalRecursions nm f
+  =  filter (none isNegative . unfoldApp)
+  $  take maxTests
+  $  conjureGrounds f (conjureVarApplication nm f)
+
+
+devlEqual :: Conjurable f => Int -> f -> Defn -> Defn -> Expr -> Bool
+devlEqual maxEvalRecursions f d1 d2 e  =
+  eq `dynApp` evalDyn d1 e
+     `dynApp` evalDyn d2 e `fromDyn` err
+  where
+  evalDyn d e  =  fromMaybe err (toDynamicWithDefn (conjureExpress f) maxEvalRecursions d e)
+  eq  =  conjureDynamicEq f
+  err  =  error "Conjure.devlEqual: evaluation error"
+  -- We cannot use conjureMkEquation here because
+  -- we need different Defns at each side of the equation
+  -- so they have to be evaluated independently.
+
+-- | Is the argument value an error value?
+isError :: a -> Bool
+isError  =  isNothing . errorToNothing
+-- There should not be a problem if this ever appears in LeanCheck:
+-- imports are qualfied in this module.
diff --git a/src/Conjure/Engine.hs b/src/Conjure/Engine.hs
--- a/src/Conjure/Engine.hs
+++ b/src/Conjure/Engine.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure.Engine
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -31,11 +31,9 @@
   , candidateDefnsC
   , conjureTheory
   , conjureTheoryWith
-  , equalModuloTesting
   , module Data.Express
   , module Data.Express.Fixtures
-  , module Test.Speculate.Engine
-  , module Test.Speculate.Reason
+  , module Conjure.Reason
   )
 where
 
@@ -43,22 +41,20 @@
 
 import Data.Express
 import Data.Express.Fixtures hiding ((-==-))
-import qualified Data.Express.Triexpr as T
 
-import Data.Dynamic (fromDyn, dynApp)
-
 import Test.LeanCheck
 import Test.LeanCheck.Tiers
-import Test.LeanCheck.Error (errorToTrue, errorToFalse, errorToNothing)
+import Test.LeanCheck.Error (errorToFalse)
 import Test.LeanCheck.Utils (classifyOn)
 
-import Test.Speculate.Reason (Thy, rules, equations, invalid, canReduceTo, printThy, closureLimit, doubleCheck)
-import Test.Speculate.Engine (theoryFromAtoms, grounds, groundBinds, boolTy)
-
 import Conjure.Expr
 import Conjure.Conjurable
 import Conjure.Prim
 import Conjure.Defn
+import Conjure.Defn.Redundancy
+import Conjure.Defn.Test
+import Conjure.Red
+import Conjure.Reason
 
 
 -- | Conjures an implementation of a partially defined function.
@@ -338,25 +334,6 @@
                       else candidateDefns1
 
 
-nubCandidates :: Conjurable f => Args -> String -> f -> [[Defn]] -> [[Defn]]
-nubCandidates Args{..} nm f  =
-  discardLaterT $ equalModuloTesting maxTests maxEvalRecursions nm f
-
-
-equalModuloTesting :: Conjurable f => Int -> Int -> String -> f -> Defn -> Defn -> Bool
-equalModuloTesting maxTests maxEvalRecursions nm f  =  (===)
-  where
-  err  =  error "nubCandidates: unexpected evaluation error."
-  eq  =  conjureDynamicEq f
-  d1 === d2  =  all are $ take maxTests $ grounds (conjureTiersFor f) (conjureVarApplication nm f)
-    where
-    are :: Expr -> Bool
-    are e  =  errorToFalse -- silences errors, ok since this is for optional measuring of optimal pruning
-           $  (`fromDyn` err)
-           $  eq `dynApp` fromMaybe err (toDynamicWithDefn (conjureExpress f) maxEvalRecursions d1 e)
-                 `dynApp` fromMaybe err (toDynamicWithDefn (conjureExpress f) maxEvalRecursions d2 e)
-
-
 -- | Return apparently unique candidate definitions
 --   where there is a single body.
 candidateDefns1 :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy)
@@ -435,8 +412,8 @@
     keepNumeric e  =  isFun e || isConst e || not (isGround e)
 
   ps2fss :: [Expr] -> [[Defn]]
-  ps2fss pats  =  discardT isRedundantDefn
-               .  discardT (allEqual2 . map snd)
+  ps2fss pats  =  discardT (isRedundantModuloRewriting $ normalize thy)
+               .  discardT isRedundantDefn
                .  products
                $  map p2eess pats
     where
@@ -508,78 +485,6 @@
   errRV  =  error "candidateDefnsC: unexpected variables.  You have found a bug, please report it."
 
 
--- | Returns whether the given recursive call
---   deconstructs one of its arguments.
---
--- > > deconstructs1 ... (factorial' (dec' xx))
--- > True
---
--- > > deconstructs1 ... (factorial' (xx -+- one))
--- > False
---
--- > > deconstructs1 ... (xxs -++- yys)
--- > False
---
--- > > deconstructs1 ... (xxs -++- tail' yys)
--- > True
---
--- > > deconstructs1 ... (zero-:-xxs -++- tail' yys)
--- > True
---
--- 'deconstructs1' implies 'descends'.
-deconstructs1 :: (Expr -> Bool) -> Expr -> Expr -> Bool
-deconstructs1 isDec _ e  =  any isDeconstruction exs
-  where
-  (ef:exs)  =  unfoldApp e
-  isDeconstruction e  =  not (null cs) && all isDec cs
-    where
-    cs  =  consts e
-
--- | Returns whether a non-empty subset of arguments
---   descends arguments by deconstruction.
---
--- > > descends isDec (xxs -++- yys) (xxs -++- tail' yys)
--- > True
---
--- > > descends isDec (xxs -++- yys) (xxs -++- yys)
--- > False
---
--- > > descends isDec (xxs -++- yys) (head' xxs -:- tail xxs  -++-  head' yys -:- tail yys)
--- > False
-
--- > > descends isDec (xxs -\/- yys) (yys -\/- tail' xxs)
--- > True
---
--- The following are not so obvious:
---
--- > > descends isDec (xxs -++- yys) (tail' yys -++- yys)
--- > False
---
--- > > descends isDec (xxs -++- yys) (xx-:-xxs -++- tail' yys)
--- > True
---
--- For all possible sets of arguments (2^n - 1 elements: 1 3 7 15 31),
--- see if any projects the same variables while only using deconstructions
--- and where there is at least a single deconstruction.
-descends :: (Expr -> Expr -> Bool) -> Expr -> Expr -> Bool
-descends isDecOf e' e  =  any d1 ss
-  where
-  desc  =  any d1 . uncurry useMatches . unzip
-  d1 exys  =  all isNotConstruction exys
-           && any isDeconstruction exys
-  ss  =  init $ sets exys
-  exys  =  zip exs eys
-  (_:exs)  =  unfoldApp e'
-  (_:eys)  =  unfoldApp e
-  isDeconstruction (p,e) | isVar p    =  e `isDecOf` p
-                         | otherwise  =  size e < size p
-    where
-    cs  =  consts e
-  isNotConstruction (p,e) | isVar p    =  e == p || e `isDecOf` p
-                          | otherwise  =  size e <= size p -- TODO: allow filter and id somehow
--- TODO: improve this function with better isNotConstruction
-
-
 -- | Checks if the given pattern is a ground pattern.
 --
 -- A pattern is a ground pattern when its arguments are fully defined
@@ -635,44 +540,22 @@
 keepIf _  =  error "Conjure.Engine.keepIf: not an if"
 
 
+-- equality between candidates
 
---- normality checks ---
+nubCandidates :: Conjurable f => Args -> String -> f -> [[Defn]] -> [[Defn]]
+nubCandidates Args{..} nm f  =
+  discardLaterT $ equalModuloTesting maxTests maxEvalRecursions nm f
 
-isRootNormal :: Thy -> Expr -> Bool
-isRootNormal thy e  =  null $ T.lookup e trie
-  where
-  trie  =  T.fromList (rules thy)
 
--- the logic of this function is a bit twisted for performance
--- but nevertheless correct
-isRootNormalC :: Thy -> Expr -> Bool
-isRootNormalC thy e | not (isRootNormal thy e)  =  False
-isRootNormalC thy (ef :$ ex :$ ey)
-  | ex <= ey  =  True
-  | not (isCommutative thy ef)  =  True
-  | isRootNormal thy (ef :$ ey :$ ex)  =  False
-isRootNormalC _ _  =  True
-
-isRootNormalE :: Thy -> Expr -> Bool
-isRootNormalE thy e  =  isRootNormal thy e
-                    &&  null (filter (e ->-) [e2 //- bs | (_,bs,e2) <- T.lookup e trie])
-  where
-  trie  =  T.fromList $ equations thy ++ map swap (equations thy)
-  (->-)  =  canReduceTo thy
-
-isCommutative :: Thy -> Expr -> Bool
-isCommutative thy eo  =  eo `elem` commutativeOperators thy
-
-commutativeOperators :: Thy -> [Expr]
-commutativeOperators thy  =  [ ef
-                             | (ef :$ ex :$ ey, ef' :$ ey' :$ ex') <- equations thy
-                             , ef == ef'
-                             , ex == ex'
-                             , ey == ey'
-                             ]
+--- tiers utils ---
 
+productsThat :: (a -> [a] -> Bool) -> [ [[a]] ] -> [[ [a] ]]
+productsThat p  =  foldr (productWithThat (:) p) [[[]]]
 
---- tiers utils ---
+productWithThat :: (a->b->c) -> (a->b->Bool) -> [[a]] -> [[b]] -> [[c]]
+productWithThat f p xss yss  =  mapT (uncurry f)
+                             .  filterT (uncurry p)
+                             $  xss >< yss
 
 productsWith :: ([a] -> a) -> [ [[a]] ] -> [[a]]
 productsWith f  =  mapT f . products
@@ -684,3 +567,6 @@
 
 foldAppProducts :: Expr -> [ [[Expr]] ] -> [[Expr]]
 foldAppProducts ef  =  delayedProductsWith (foldApp . (ef:))
+
+boolTy :: TypeRep
+boolTy  =  typ b_
diff --git a/src/Conjure/Expr.hs b/src/Conjure/Expr.hs
--- a/src/Conjure/Expr.hs
+++ b/src/Conjure/Expr.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure.Expr
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -31,6 +31,8 @@
   , deholings
   , varToConst
   , hasAppInstanceOf
+  , isNegative
+  , isStrictSubexprOf
 
   , enumerateAppsFor
   , enumerateFillings
@@ -43,6 +45,11 @@
   , conflicts
   , listConflicts
 
+  , grounds
+  , groundBinds
+
+  , rvars
+
   , module Conjure.Utils
   )
 where
@@ -60,6 +67,8 @@
 import Test.LeanCheck.Tiers (products)
 import Test.LeanCheck.Utils.Types (A, B, C, D, E, F)
 
+import Test.Speculate.Expr (grounds, groundBinds)
+
 -- | /O(n)/.
 -- Compares the simplicity of two 'Expr's.
 -- An expression /e1/ is /strictly simpler/ than another expression /e2/
@@ -530,6 +539,36 @@
   where
   fun (ef :$ _)  =  ef
   arg (_ :$ ex)  =  ex
+
+-- | Is the expression encoding a negative number.
+--
+-- This function is sort of a hack.
+isNegative :: Expr -> Bool
+isNegative (Value ('-':_) _)  =  True
+isNegative _  =  False
+
+-- | Lists all variables in an expression
+--   that are of the same type of the expression itself.
+--
+-- > > rvars (ff xx)
+-- > [x :: Int]
+--
+-- > > rvars (xx -:- xxs -++- yys)
+-- > [xs :: [Int], ys :: [Int]]
+--
+-- They are listed and without repetitions in 'Expr' order:
+--
+-- > > rvars (xx -:- yys -++- xxs -++- xxs)
+-- > [xs :: [Int],ys :: [Int]]
+--
+-- (cf. nubVars)
+rvars :: Expr -> [Expr]
+rvars e  =  [ex | ex <- nubVars e, typ ex == typ e]
+
+-- | Is this a /strict/ subexpression?
+isStrictSubexprOf :: Expr -> Expr -> Bool
+isStrictSubexprOf e1 e2  =  e1 /= e2
+                         && e1 `isSubexprOf` e2
 
 instance Express A where  expr  =  val
 instance Express B where  expr  =  val
diff --git a/src/Conjure/Prim.hs b/src/Conjure/Prim.hs
--- a/src/Conjure/Prim.hs
+++ b/src/Conjure/Prim.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure.Prim
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -27,7 +27,6 @@
 import Conjure.Utils
 import Test.LeanCheck.Error (errorToFalse)
 import Test.LeanCheck.Utils
-import Test.Speculate.Expr
 
 
 -- | A primtive expression (paired with instance reification).
@@ -91,7 +90,13 @@
   (-==-)  =  cjMkEquation ps
   e1 === e2  =  isTrue $ e1 -==- e2
   isTrue  =  all (errorToFalse . eval False) . gs
-  gs  =  take maxTests . grounds (cjTiersFor ps)
+  gs  =  take maxTests . cjGrounds ps
+
+-- | Given a list of 'Prim's,
+--   computes a grounds function that lists
+--   ground expressions of an 'Expr'.
+cjGrounds :: [Prim] -> Expr -> [Expr]
+cjGrounds  =  grounds . cjTiersFor
 
 -- | Given a list of 'Prim's,
 --   returns a function that given an 'Expr'
diff --git a/src/Conjure/Reason.hs b/src/Conjure/Reason.hs
new file mode 100644
--- /dev/null
+++ b/src/Conjure/Reason.hs
@@ -0,0 +1,80 @@
+-- |
+-- Module      : Conjure.Reason
+-- Copyright   : (c) 2021-2024 Rudy Matela
+-- License     : 3-Clause BSD  (see the file LICENSE)
+-- Maintainer  : Rudy Matela <rudy@matela.com.br>
+--
+-- An internal module of "Conjure",
+-- a library for Conjuring function implementations
+-- from tests or partial definitions.
+-- (a.k.a.: functional inductive programming)
+--
+-- This module re-exports some functions from "Test.Speculate"
+-- along with a few additional utilities.
+module Conjure.Reason
+  ( Thy
+  , rules
+  , equations
+  , invalid
+  , canReduceTo
+  , printThy
+  , closureLimit
+  , doubleCheck
+  , normalize
+  , theoryFromAtoms
+  , isRootNormalC
+  , isRootNormalE
+  , isCommutative
+  , commutativeOperators
+  )
+where
+
+import Test.Speculate.Reason
+  ( Thy
+  , rules
+  , equations
+  , invalid
+  , canReduceTo
+  , printThy
+  , closureLimit
+  , doubleCheck
+  , normalize
+  )
+import Test.Speculate.Engine (theoryFromAtoms)
+import Conjure.Expr
+import qualified Data.Express.Triexpr as T
+
+--- normality checks ---
+
+isRootNormal :: Thy -> Expr -> Bool
+isRootNormal thy e  =  null $ T.lookup e trie
+  where
+  trie  =  T.fromList (rules thy)
+
+-- the logic of this function is a bit twisted for performance
+-- but nevertheless correct
+isRootNormalC :: Thy -> Expr -> Bool
+isRootNormalC thy e | not (isRootNormal thy e)  =  False
+isRootNormalC thy (ef :$ ex :$ ey)
+  | ex <= ey  =  True
+  | not (isCommutative thy ef)  =  True
+  | isRootNormal thy (ef :$ ey :$ ex)  =  False
+isRootNormalC _ _  =  True
+
+isRootNormalE :: Thy -> Expr -> Bool
+isRootNormalE thy e  =  isRootNormal thy e
+                    &&  null (filter (e ->-) [e2 //- bs | (_,bs,e2) <- T.lookup e trie])
+  where
+  trie  =  T.fromList $ equations thy ++ map swap (equations thy)
+  (->-)  =  canReduceTo thy
+
+isCommutative :: Thy -> Expr -> Bool
+isCommutative thy eo  =  eo `elem` commutativeOperators thy
+
+commutativeOperators :: Thy -> [Expr]
+commutativeOperators thy  =  [ ef
+                             | (ef :$ ex :$ ey, ef' :$ ey' :$ ex') <- equations thy
+                             , ef == ef'
+                             , ex == ex'
+                             , ey == ey'
+                             ]
diff --git a/src/Conjure/Red.hs b/src/Conjure/Red.hs
new file mode 100644
--- /dev/null
+++ b/src/Conjure/Red.hs
@@ -0,0 +1,150 @@
+-- |
+-- Module      : Conjure.Red
+-- Copyright   : (c) 2021-2024 Rudy Matela
+-- License     : 3-Clause BSD  (see the file LICENSE)
+-- Maintainer  : Rudy Matela <rudy@matela.com.br>
+--
+-- This module is part of "Conjure".
+--
+-- This defines functions that deal with recursive descent and deconstructions
+module Conjure.Red
+  ( conjureIsDeconstruction
+  , descends
+  , candidateDeconstructionsFrom
+  , candidateDeconstructionsFromHoled
+  )
+where
+
+import Conjure.Defn
+import Conjure.Conjurable
+import Test.LeanCheck.Error (errorToFalse)
+
+-- | Checks if an expression is a deconstruction.
+--
+-- There should be a single 'hole' in the expression.
+--
+-- It should decrease the size of all arguments that have
+-- a size greater than 0.
+conjureIsDeconstruction :: Conjurable f => f -> Int -> Expr -> Bool
+conjureIsDeconstruction f maxTests ed
+  =  length (holes ed) == 1  -- Well formed deconstruction, single hole.
+  && typ h == typ ed         -- We can only deconstruct to the same type.
+  && all is sizes            -- Do we always reduce size?
+  && not (all iz sizes)      -- Disallow always mapping to values of size 0.
+                             -- In this case, we are better off not recursing
+                             -- and returning a constant value!
+  where
+  x << 0  =  True
+  x << y  =  x < y
+  is (sd,sx)  =  errorToFalse $ sd << sx
+  iz (sd,sx)  =  errorToFalse $ sd == 0 || sx == 0
+  -- We cannot simply conjureTiers for h here, because the deconstruction
+  -- expression may contain variables, e.g.: @x `mod` _@.
+  -- So conjureGrounds and the holeValue trick are required.
+  sizes  =  map evalSize2 . take maxTests $ conjureGrounds f ed
+  [h]  =  holes ed
+  evalSize2 e  =  (evalSize e, evalSize $ holeValue e)
+  evalSize e  =  eval (0::Int) (esize :$ e)
+  esize  =  conjureSizeFor f h
+  holeValue e  =  fromMaybe err . lookup h . fromMaybe err $ e `match` ed
+  err  =  error "Conjure.conjureIsDeconstruction: the impossible happened"
+
+-- | Returns whether a non-empty subset of arguments
+--   descends arguments by deconstruction.
+--
+-- > > descends isDec (xxs -++- yys) (xxs -++- tail' yys)
+-- > True
+--
+-- > > descends isDec (xxs -++- yys) (xxs -++- yys)
+-- > False
+--
+-- > > descends isDec (xxs -++- yys) (head' xxs -:- tail xxs  -++-  head' yys -:- tail yys)
+-- > False
+
+-- > > descends isDec (xxs -\/- yys) (yys -\/- tail' xxs)
+-- > True
+--
+-- The following are not so obvious:
+--
+-- > > descends isDec (xxs -++- yys) (tail' yys -++- yys)
+-- > False
+--
+-- > > descends isDec (xxs -++- yys) (xx-:-xxs -++- tail' yys)
+-- > True
+--
+-- For all possible sets of arguments (2^n - 1 elements: 1 3 7 15 31),
+-- see if any projects the same variables while only using deconstructions
+-- and where there is at least a single deconstruction.
+descends :: (Expr -> Expr -> Bool) -> Expr -> Expr -> Bool
+descends isDecOf efls efrs  =  any hasDeconstruction
+                            $  classifyOn (typ . fst) (zip ls rs)
+  where
+  (_:ls)  =  unfoldApp efls
+  (_:rs)  =  unfoldApp efrs
+
+  hasDeconstruction :: [(Expr,Expr)] -> Bool
+  hasDeconstruction lrs  =  or [b *<< bs | (b,bs) <- choices lrs]
+
+  r << l  =  any (r `isDecOf`) (rvars l)
+          || r `isStrictSubexprOf` l
+          || isGround r && not (isGround l) && size r < size l
+
+  r <<= l  =  r == l
+           || r << l
+
+  (l,r) *<< bs  =  r << l
+                || or [ (l',r) *<<= bs'
+                      | ((l',r'),bs') <- choices bs
+                      , r' << l
+                      ]
+
+  (l,r) *<<= bs  =  r <<= l
+                 || or [ (l',r) *<<= bs'
+                       | ((l',r'),bs') <- choices bs
+                       , r' <<= l
+                       ]
+
+-- | Compute candidate deconstructions from an 'Expr'.
+--
+-- This is used in the implementation of 'Conjure.Engine.candidateDefnsC'
+-- followed by 'conjureIsDeconstruction'.
+--
+-- > > candidateDeconstructionsFrom (xx `mod'` yy)
+-- > [ _ `mod` y
+-- > , x `mod` _
+-- > ]
+--
+-- To be constrasted with 'candidateDeconstructionsFromHoled'.
+candidateDeconstructionsFrom :: Expr -> [Expr]
+candidateDeconstructionsFrom e  =
+  [ e'
+  | v <- vars e
+  , typ v == typ e
+  , let e' = e //- [(v, holeAsTypeOf v)]
+  , length (holes e') == 1
+  ]
+
+-- | Compute candidate deconstructions from an 'Expr'.
+--
+-- This is used in the implementation of 'Conjure.Engine.candidateExprs'
+-- followed by 'conjureIsDeconstruction'.
+--
+-- This is similar to 'canonicalVariations'
+-- but always leaves a hole
+-- of the same return type as the given expression.
+--
+-- > > candidateDeconstructionsFrom (i_ `mod'` i_)
+-- > [ _ `mod` x
+-- > , x `mod` _
+-- > ]
+--
+-- To be contrasted with 'candidateDeconstructionsFrom'
+candidateDeconstructionsFromHoled :: Expr -> [Expr]
+candidateDeconstructionsFromHoled e  =  map (//- [(v, h)])
+                                     $  concatMap canonicalVariations
+                                     $  deholings v e
+  where
+  h  =  holeAsTypeOf e
+  v  =  "_#_" `varAsTypeOf` e  -- a marker variable with an invalid name
+  -- at some point I should get rid of candidateDeconstructionsFrom in favour
+  -- of this one
diff --git a/src/Conjure/Utils.hs b/src/Conjure/Utils.hs
--- a/src/Conjure/Utils.hs
+++ b/src/Conjure/Utils.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Conjure.Utils
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -45,6 +45,7 @@
   , second
   , both
   , (+++)
+  , isSubsetOf
   )
 where
 
@@ -57,6 +58,7 @@
 
 import System.IO.Unsafe
 
+import Data.Express.Utils.List (isSubsetOf)
 import Test.LeanCheck.Stats (classify, classifyBy, classifyOn)
 
 
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,6 +1,6 @@
 # Stack file for the Conjure program generation library.
 #
-# Copyright (C) 2021 Rudy Matela
+# Copyright (C) 2021-2024 Rudy Matela
 # Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 resolver: lts-19.19 # or ghc-9.0.2
@@ -11,4 +11,4 @@
 extra-deps:
 - leancheck-1.0.2
 - speculate-0.4.14
-- express-1.0.14
+- express-1.0.16
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Test
--- Copyright   : (c) 2021 Rudy Matela
+-- Copyright   : (c) 2021-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
@@ -15,6 +15,7 @@
   , module Test.ListableExpr
 
   , mainTest
+  , conjurableOK
   )
 where
 
@@ -51,3 +52,20 @@
 
 printLines :: Show a => [a] -> IO ()
 printLines = putStrLn . unlines . map show
+
+
+-- checks if the functions conjureEquality, conjureExpress and conjureTiers
+-- were correctly generated.
+conjurableOK :: (Eq a, Show a, Express a, Listable a, Conjurable a) => a -> Bool
+conjurableOK x  =  and
+  [ holds 60 $ (-==-) ==== (==)
+  , holds 60 $ expr' === expr
+  , tiers =| 6 |= (tiers -: [[x]])
+  , all isWellTyped cases'
+  , all (\c -> typ c == typeOf x) cases'
+  ]
+  where
+  (-==-)  =  evl (fromJust $ conjureEquality x) -:> x
+  tiers'  =  mapT evl (fromJust $ conjureTiers x) -: [[x]]
+  expr'  =  (conjureExpress x . val) -:> x
+  cases'  =  conjureCases x
diff --git a/test/Test/ListableExpr.hs b/test/Test/ListableExpr.hs
--- a/test/Test/ListableExpr.hs
+++ b/test/Test/ListableExpr.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      : Test.ListableExpr
--- Copyright   : (c) 2019-2021 Rudy Matela
+-- Copyright   : (c) 2019-2024 Rudy Matela
 -- License     : 3-Clause BSD  (see the file LICENSE)
 -- Maintainer  : Rudy Matela <rudy@matela.com.br>
 --
diff --git a/test/conjurable.hs b/test/conjurable.hs
--- a/test/conjurable.hs
+++ b/test/conjurable.hs
@@ -1,4 +1,4 @@
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 {-# Language DeriveDataTypeable, StandaloneDeriving #-}  -- for GHC < 7.10
@@ -224,42 +224,6 @@
          ]
        ]
 
-  , isDecon (minus :$ i_ :$ one) == True
-  , isDecon (minusOne -+- i_)    == True
-  , isDecon (div' i_ two)        == True
-  , isDecon (tail' is_)          == True
-  , isDecon (init' is_)          == True
-
-  -- counter-intuitive but true: x `mod` y is a deconstruction of y:
-  -- x `mod` y < y  for  y > 0
-  , isDecon (mod' xx i_)         == True
-
-  , isDecon (mod' i_ two)        == False -- does not deconstruct 1
-  , isDecon (mod' i_ xx)         == False -- may not deconstruct 1
-  , isDecon (div' xx yy)         == False -- must have a hole to indicate the value being deconstructed
-  , isDecon (div' i_ i_)         == False -- two holes are not allowed
-  , isDecon (head' is_)          == False -- must deconstruct to the same type
-  , isDecon (i_ -*- two)         == False -- increases the size
-
-  , candidateDeconstructionsFrom (div' xx yy) == [ div' i_ yy
-                                                 , div' xx i_
-                                                 ]
-  , candidateDeconstructionsFrom (div' xx xx) == []
-  , candidateDeconstructionsFrom ((xx -+- xx) -+- yy) == [(xx -+- xx) -+- i_]
-
-  , candidateDeconstructionsFromHoled (div' i_ i_) == [ div' i_ xx
-                                                      , div' xx i_
-                                                      ]
-  , candidateDeconstructionsFromHoled (div' xx yy) == []
-  , candidateDeconstructionsFromHoled ((i_ -+- i_) -+- i_) ==
-      [ (i_ -+- xx) -+- yy
-      , (i_ -+- xx) -+- xx
-      , (xx -+- i_) -+- yy
-      , (xx -+- i_) -+- xx
-      , (xx -+- yy) -+- i_
-      , (xx -+- xx) -+- i_
-      ]
-
   , fromDynamic (conjureDynamicEq ((+) :: Int -> Int -> Int) `dynApp` toDyn (1::Int) `dynApp` toDyn (2::Int))
     == Just False
   , fromDynamic (conjureDynamicEq ((+) :: Int -> Int -> Int) `dynApp` toDyn (1::Int) `dynApp` toDyn (1::Int))
@@ -270,10 +234,66 @@
   , isNumeric bee == False
   , isNumeric (expr [0::Int]) == False
   , isNumeric true == False
-  ]
 
-isDecon :: Expr -> Bool
-isDecon =  conjureIsDeconstruction (undefined :: [Int] -> [Char] -> [Bool]) 60
+  -- the following conjurableOK calls take 5 seconds to compile!
+  , conjurableOK (undefined :: ())
+  , conjurableOK (undefined :: Bool)
+  , conjurableOK (undefined :: Int)
+  , conjurableOK (undefined :: Char)
+  , conjurableOK (undefined :: Integer)
+  , conjurableOK (undefined :: Ordering)
+  , conjurableOK (undefined :: Float)
+  , conjurableOK (undefined :: Double)
+  , conjurableOK (undefined :: Rational)
+
+  , conjurableOK (undefined :: A)
+  , conjurableOK (undefined :: B)
+  , conjurableOK (undefined :: C)
+  , conjurableOK (undefined :: D)
+  , conjurableOK (undefined :: E)
+  , conjurableOK (undefined :: F)
+
+  , conjurableOK (undefined :: [()])
+  , conjurableOK (undefined :: [Bool])
+  , conjurableOK (undefined :: [Int])
+  , conjurableOK (undefined :: String)
+
+  , conjurableOK (undefined :: ((),()))
+  , conjurableOK (undefined :: (Bool,Bool))
+  , conjurableOK (undefined :: (Int,Int))
+  , conjurableOK (undefined :: (Char,String))
+  , conjurableOK (undefined :: (Bool,[Int]))
+
+  , conjurableOK (undefined :: (Int,Int,Int))
+  , conjurableOK (undefined :: (Bool,Int,Char))
+  , conjurableOK (undefined :: ([Int],[Bool],String))
+
+  , conjurableOK (undefined :: Maybe ())
+  , conjurableOK (undefined :: Maybe Bool)
+  , conjurableOK (undefined :: Maybe Int)
+  , conjurableOK (undefined :: Maybe Char)
+  , conjurableOK (undefined :: Maybe String)
+
+  , conjurableOK (undefined :: Either () ())
+  , conjurableOK (undefined :: Either Bool Bool)
+  , conjurableOK (undefined :: Either Int Int)
+  , conjurableOK (undefined :: Either String Int)
+  , conjurableOK (undefined :: Either String Char)
+
+  , conjurableOK (undefined :: (Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int))
+  , conjurableOK (undefined :: (Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int))
+
+  -- little sanity check (conjurableOK should catch it anyway)
+  , take 6 (conjureListFor (undefined :: Int) i_)
+    == [zero, one, minusOne, two, minusTwo, three]
+  ]
 
 isNumeric :: Expr -> Bool
 isNumeric  =  conjureIsNumeric (undefined :: [Int] -> [Char] -> [Bool] -> [Integer])
diff --git a/test/defn.hs b/test/defn.hs
--- a/test/defn.hs
+++ b/test/defn.hs
@@ -1,8 +1,9 @@
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 import Test
 import Conjure.Defn
+import Conjure.Defn.Redundancy
 import Test.LeanCheck.Error (errorToLeft)
 import Test.LeanCheck.Function ()
 import Data.Express.Fixtures
@@ -153,6 +154,36 @@
   , not $ isBaseCase      (ff (xx -:- xxs), ff xxs)
   ,       isRecursiveCase (ff (xx -:- xxs), ff xxs)
   , not $ isRecursiveCase (ff (xx -:- nil), xx)
+
+  , subsumedWith (// [(zero -+- zero, zero)]) (ff zero, zero) (ff xx, xx -+- xx) == True
+  , subsumedWith (// [(zero -+- zero, zero)]) (ff zero, zero) (ff xx, xx -+- zero) == True
+  , subsumedWith (// [(zero -+- zero, zero)]) (ff zero, zero) (ff xx, xx -+- one) == False
+  , subsumedWith (// [(zero -+- zero, zero)]) (zero -?- xx, zero) (xx -?- yy, xx -+- xx) == True
+  , subsumedWith (// [(zero -+- zero, zero)]) (zero -?- xx, zero) (xx -?- yy, xx -+- zero) == True
+  , subsumedWith (// [(zero -+- zero, zero)]) (zero -?- xx, zero) (xx -?- yy, xx -+- one) == False
+  , subsumedWith (// [(zero -+- zero, zero)]) (zero -?- xx, zero) (xx -?- yy, xx -+- yy) == False
+
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(ff zero, zero),(ff xx, xx -+- xx)] == True
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(ff zero, zero),(ff xx, xx -+- zero)] == True
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(ff zero, zero),(ff xx, xx -+- one)] == False
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(zero -?- xx, zero),(xx -?- yy, xx -+- xx)] == True
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(zero -?- xx, zero),(xx -?- yy, xx -+- zero)] == True
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(zero -?- xx, zero),(xx -?- yy, xx -+- one)] == False
+  , isRedundantModuloRewriting  (// [(zero -+- zero, zero)]) [(zero -?- xx, zero),(xx -?- yy, xx -+- yy)] == False
+
+  , isRedundantModuloRewriting (// [(xx -+- zero, xx)])
+      [ (zero -?- xx, xx)
+      , (xx -?- zero, xx)
+      , (xx -?- yy, xx -+- xx)
+      ] == False
+
+  , subsumedWith (// [(xx -+- zero, xx)]) (xx -?- zero, xx) (xx -?- yy, xx -+- yy) == True
+
+  , isRedundantModuloRewriting (// [(xx -+- zero, xx)])
+      [ (zero -?- xx, xx)
+      , (xx -?- zero, xx)
+      , (xx -?- yy, xx -+- yy)
+      ] == True
   ]
 
 dvl :: Typeable a => Defn -> Expr -> a
diff --git a/test/derive.hs b/test/derive.hs
--- a/test/derive.hs
+++ b/test/derive.hs
@@ -1,4 +1,4 @@
--- Copyright (c) 2019-2021 Rudy Matela.
+-- Copyright (c) 2019-2024 Rudy Matela.
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE DeriveDataTypeable #-}
@@ -150,20 +150,6 @@
                                             , hole (undefined :: Bool)
                                             ]
   ]
-
-
--- checks if the functions conjureEquality, conjureExpress and conjureTiers
--- were correctly generated.
-conjurableOK :: (Eq a, Show a, Express a, Listable a, Conjurable a) => a -> Bool
-conjurableOK x  =  and
-  [ holds 60 $ (-==-) ==== (==)
-  , holds 60 $ expr' === expr
-  , tiers =| 6 |= (tiers -: [[x]])
-  ]
-  where
-  (-==-)  =  evl (fromJust $ conjureEquality x) -:> x
-  tiers'  =  mapT evl (fromJust $ conjureTiers x) -: [[x]]
-  expr'  =  (conjureExpress x . val) -:> x
 
 
 -- proxies --
diff --git a/test/expr.hs b/test/expr.hs
--- a/test/expr.hs
+++ b/test/expr.hs
@@ -1,4 +1,4 @@
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 import Test
@@ -151,6 +151,27 @@
   , listConflicts [(one -+- zz), (two -+- yy), (three -+- xx)] == [[zz,yy,xx],[one,two,three]]
 
   , holds n $ \e1 e2 -> map listPair (conflicts e1 e2) == listConflicts [e1,e2]
+
+  , rvars xx == [xx]
+  , rvars (xx -?- yy) == [xx, yy]
+  , rvars (xx -?- yy -?- zz) == [xx, yy, zz]
+  , rvars (yy -?- yy -?- xx) == [xx, yy]
+
+  , rvars xxs == [xxs]
+  , rvars (xx -:- xxs) == [xxs]
+  , rvars (xx -:- yy -:- xxs) == [xxs]
+  , rvars (xxs -++- yys) == [xxs, yys]
+  , rvars (xx -:- xxs -++- yys) == [xxs, yys]
+  , rvars (xx -:- yys -++- xxs -++- xxs) == [xxs, yys]
+
+  , rvars (pp -&&- qq) == [pp, qq]
+  , rvars (qq -&&- pp) == [pp, qq]
+  , rvars (pp -||- qq -&&- pp) == [pp, qq]
+
+  , xx `isStrictSubexprOf` xx == False
+  , xx `isStrictSubexprOf` (xx -+- yy) == True
+  , xx `isStrictSubexprOf` (yy -+- yy) == False
+  , (xx -+- yy) `isStrictSubexprOf` (xx -+- yy) == False
   ]
 
 listPair :: (a,a) -> [a]
diff --git a/test/mk b/test/mk
new file mode 100644
--- /dev/null
+++ b/test/mk
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# test/mk: tests the makefile of Conjure itself
+#
+# This tests that the makefile is thorough and actually
+# runs all tests scripts and benchmarks when asked to do so.
+#
+# Copyright (c) 2024 Rudy Matela.
+# Distributed under the 3-Clause BSD licence.
+
+set -xe
+
+export LC_ALL=C  # consistent sort
+diff="diff --color -rud"
+
+tmp=`mktemp -d /tmp/test-mk-XXXXXXXXXX`
+[ -d "$tmp" ] || exit 1
+
+rmhs() { sed -e 's/.hs$//'; }
+rmtarget() { sed -e 's/:.*//'; }
+flt() {
+	rmhs |     # excludes extensions from the result of find
+	rmtarget | # exclude Makefile target indicators
+	grep -v '^bench/avgs$' | # not an actual benchmark
+	grep -v '^.*/[A-Z].*$' # test/benchmark/example scripts begin with lowercase
+}
+
+make -s ls-eg ls-test                                   | sort >$tmp/ls-mk
+find eg bench proto test -name '*.hs' -maxdepth 1 | flt | sort >$tmp/ls-find
+grep -E "^[^/]*/[^.]*:" mk/depend.mk              | flt | sort >$tmp/ls-depend
+grep -E "(eg|bench|proto|test)/" .gitignore       | flt | sort >$tmp/ls-gitignore
+$diff $tmp/ls-{mk,find}      # compares make variables with actual directory
+$diff $tmp/ls-{mk,depend}    # compares make variables with mk/depend.mk
+$diff $tmp/ls-{mk,gitignore} # compare make variables with .gitignore
+rm -r $tmp
diff --git a/test/red.hs b/test/red.hs
new file mode 100644
--- /dev/null
+++ b/test/red.hs
@@ -0,0 +1,165 @@
+-- Copyright (C) 2021-2024 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+
+import Test
+import Conjure.Red
+import Data.Dynamic
+
+main :: IO ()
+main  =  mainTest tests 5040
+
+tests :: Int -> [Bool]
+tests n  =
+  [ True
+
+  -- tests of conjureIsDeconstruction --
+
+  -- obvious deconstructions
+  , isDecon (minus :$ i_ :$ one) == True
+  , isDecon (minus :$ i_ :$ two) == True
+  , isDecon (div' i_ two) == True
+  , isDecon (tail' is_) == True
+  , isDecon (init' is_) == True
+  , isDecon (drop' one is_) == True
+
+  -- obvious constructions
+  , isDecon (i_ -+- one) == False
+  , isDecon (i_ -+- two) == False
+  , isDecon (i_ -*- two)  == False
+  , isDecon (xx -:- is_) == False
+  , isDecon (is_ -++- unit xx) == False
+
+  -- doing nothing is not deconstructing
+  , isDecon (i_) == False
+  , isDecon (is_) == False
+
+  -- double deconstructions & constructions
+  , isDecon (minusOne -+- i_) == True
+  , isDecon (minus :$ (minus :$ i_ :$ one) :$ one) == True
+  , isDecon (minus :$ i_ :$ three) == True
+  , isDecon (minus :$ i_ :$ four) == True
+  , isDecon (minus :$ i_ :$ five) == True
+  , isDecon (minus :$ i_ :$ six) == True
+  , isDecon (drop' two is_) == True
+  , isDecon (drop' three is_) == True
+  , isDecon (drop' xx is_) == False -- may not deconstruct!
+
+  , isDecon (tail' (tail' is_)) == False -- does not deconstruct [1]
+  , isDecon (init' (init' is_)) == False -- does not deconstruct [1]
+  , isDecon (init' (tail' is_)) == False -- does not deconstruct [1]
+
+  , isDecon (drop' one (drop' one is_)) == True
+  , isDecon (drop' one (tail' is_)) == True
+
+  , isDecon (take' one is_) == False -- does not deconstruct [1]
+  , isDecon (take' two is_) == False -- does not deconstruct [1,1]
+
+  -- counter-intuitive but true: x `mod` y is a deconstruction of y:
+  -- x `mod` y < y  for  y > 0
+  , isDecon (mod' xx i_) == True
+
+  , isDecon (mod' i_ two) == False -- does not deconstruct 1
+  , isDecon (mod' i_ xx)  == False -- may not deconstruct 1
+  , isDecon (div' xx yy)  == False -- must have a hole to indicate the value being deconstructed
+  , isDecon (div' i_ i_)  == False -- two holes are not allowed
+  , isDecon (head' is_)   == False -- must deconstruct to the same type
+
+  -- constant "deconstructions"
+  , isDecon (const' zero i_) == False -- always mapping to size 0 is not allowed!
+  , isDecon (const' nil is_) == False -- always mapping to size 0 is not allowed!
+  , isDecon (const' one i_)  == False -- does not deconstruct 1
+
+  -- negative "deconstructions"
+  , isDecon (minus :$ zero :$ i_) == False
+  , isDecon (minus :$ one :$ i_)  == False
+
+  -- boolean "deconstructions"
+  , isDecon (not' b_) == False -- always mapping to size 0 is not allowed!
+  , isDecon (false -||- b_) == False -- always mapping to size 0 is not allowed!
+
+  , candidateDeconstructionsFrom (div' xx yy) == [ div' i_ yy
+                                                 , div' xx i_
+                                                 ]
+  , candidateDeconstructionsFrom (div' xx xx) == []
+  , candidateDeconstructionsFrom ((xx -+- xx) -+- yy) == [(xx -+- xx) -+- i_]
+
+  , candidateDeconstructionsFromHoled (div' i_ i_) == [ div' i_ xx
+                                                      , div' xx i_
+                                                      ]
+  , candidateDeconstructionsFromHoled (div' xx yy) == []
+  , candidateDeconstructionsFromHoled ((i_ -+- i_) -+- i_) ==
+      [ (i_ -+- xx) -+- yy
+      , (i_ -+- xx) -+- xx
+      , (xx -+- i_) -+- yy
+      , (xx -+- i_) -+- xx
+      , (xx -+- yy) -+- i_
+      , (xx -+- xx) -+- i_
+      ]
+
+  -- simple integer descent
+  , descends isDecOf (ff xx) (ff xx) == False
+  , descends isDecOf (ff xx) (ff (xx -+- one)) == False
+  , descends isDecOf (ff xx) (ff (dec xx)) == True
+  , descends isDecOf (ff xx) (ff (yy `mod'` xx)) == True
+
+  -- simple list descent
+  , descends isDecOf (ff xxs) (ff xxs) == False
+  , descends isDecOf (ff xxs) (ff (tail' xxs)) == True
+  , descends isDecOf (ff (xx -:- xxs)) (ff xxs) == True
+  , descends isDecOf (ff xxs) (ff (xxs -++- xxs)) == False
+
+  -- double integer descent
+  , descends isDecOf (ff2 xx yy) (ff2 xx yy) == False
+  , descends isDecOf (ff2 xx yy) (ff2 (xx -+- one) yy) == False
+  , descends isDecOf (ff2 xx yy) (ff2 (dec xx) yy) == True
+  , descends isDecOf (ff2 xx yy) (ff2 (dec yy) xx) == True
+  , descends isDecOf (ff2 xx yy) (ff2 xx (dec yy)) == True
+  , descends isDecOf (ff2 xx yy) (ff2 yy (dec xx)) == True
+  , descends isDecOf (ff2 xx yy) (ff2 (dec xx) (dec yy)) == True
+  , descends isDecOf (ff2 xx yy) (ff2 (dec yy) (dec xx)) == True
+
+  -- double list descent
+  , descends isDecOf (xxs -++- yys) (xxs -++- yys) == False
+  , descends isDecOf (xxs -++- yys) (xxs -++- tail' yys) == True
+
+  , descends isDecOf (xxs -++- yys) (tail' yys -++- yys) == False
+  , descends isDecOf (xxs -++- yys) ((xx -:- xxs) -++- tail' yys) == True
+
+  , descends isDecOf (xxs -++- yys) (head' xxs -:- tail' xxs  -++-  head' yys -:- tail' yys) == False
+
+  -- gcd descent
+  , descends isDecOf (ff2 xx yy) (ff2 yy (xx `mod'` yy)) == True -- actual gcd descent
+  , descends isDecOf (ff2 xx yy) (ff2 yy (yy `mod'` yy)) == True -- other
+
+  -- interleave descent
+  , descends isDecOf (xxs -\/- yys) (yys -\/- tail' xxs) == True
+  , descends isDecOf (xxs -\/- yys) (tail' yys -\/- xxs) == True
+  , descends isDecOf (xxs -\/- yys) (tail' yys -\/- tail' xxs) == True
+  , descends isDecOf ((xx -:- xxs) -\/- yys) (yys -\/- xxs) == True
+  , descends isDecOf (xxs -\/- (yy -:- yys)) (yys -\/- xxs) == True
+  , descends isDecOf ((xx -:- xxs) -\/- (yy -:- yys)) (yys -\/- xxs) == True
+
+  -- disallowed descents
+  , descends isDecOf ((xx -:- xxs) -?- (yy -:- yys)) (yys -?- (xx -:- yys)) == False
+  , descends isDecOf ((xx -:- xxs) -?- (yy -:- yys)) (yys -?- (yy -:- yys)) == False
+  ]
+
+isDecOf :: Expr -> Expr -> Bool
+e1 `isDecOf` e2  =  any ((e1 -|- e2) `isInstanceOf`)
+  [ tail' xxs -|- xxs
+  , dec xx -|- xx
+  , yy `mod'` xx -|- xx
+  ]
+
+(-\/-) :: Expr -> Expr -> Expr
+exs -\/- eys  =  interleaveE :$ exs :$ eys
+  where
+  interleaveE  =  value "\\/" ((\/) :: [Int] -> [Int] -> [Int])
+  [] \/ ys  =  ys
+  (x:xs) \/ ys  =  x : (ys \/ xs)
+
+isDecon :: Expr -> Bool
+isDecon =  conjureIsDeconstruction (undefined :: [Int] -> [Char] -> [Bool]) 60
+
+dec :: Expr -> Expr
+dec ex  =  minus :$ ex :$ one
diff --git a/test/utils.hs b/test/utils.hs
--- a/test/utils.hs
+++ b/test/utils.hs
@@ -1,4 +1,4 @@
--- Copyright (C) 2021 Rudy Matela
+-- Copyright (C) 2021-2024 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 
 import Test
