diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -32,15 +32,19 @@
 eg/arith
 eg/bools
 eg/count
+eg/dupos
 eg/factorial
 eg/fibonacci
+eg/fib01
 eg/ints
 eg/gcd
 eg/list
+eg/pow
 eg/tapps
 eg/tree
 eg/replicate
 eg/setelem
+eg/sort
 eg/subset
 eg/spec
 bench/self
@@ -51,6 +55,8 @@
 bench/p12
 bench/p30
 bench/candidates
+bench/gps
+bench/lowtests
 proto/u-conjure
 test/expr
 test/conjurable
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -8,14 +8,18 @@
 EG = \
   eg/arith \
   eg/count \
+  eg/dupos \
   eg/factorial \
   eg/fibonacci \
+  eg/fib01 \
   eg/ints \
   eg/bools \
   eg/gcd \
   eg/list \
+  eg/pow \
   eg/replicate \
   eg/setelem \
+  eg/sort \
   eg/subset \
   eg/spec \
   eg/tapps \
@@ -23,10 +27,12 @@
   bench/candidates \
   bench/ill-hit \
   bench/longshot \
+  bench/lowtests \
   bench/self \
   bench/take-drop \
   bench/p12 \
   bench/p30 \
+  bench/gps \
   proto/u-conjure
 
 TESTS = \
@@ -39,10 +45,10 @@
 
 all-all: all $(EG) $(TESTS)
 
-test: $(patsubst %,%.run,$(TESTS)) diff-test test-sdist
+test: $(TESTS) $(patsubst %,%.run,$(TESTS)) diff-test test-sdist
 
 .PHONY: bench
-bench: $(patsubst %,%.bench,$(EG))
+bench: $(EG) $(patsubst %,%.bench,$(EG))
 	@mkdir -p bench/runtime/$$HOSTNAME
 	./bench/versions | tee bench/runtime/$$HOSTNAME/versions
 
@@ -55,9 +61,9 @@
 	python3 -c 'print("%.1f" % float(input()))' | \
 	tee bench/runtime/$$HOSTNAME/$<.runtime
 
-diff-test: $(patsubst %,%.diff-test,$(EG))
+diff-test: $(EG) $(patsubst %,%.diff-test,$(EG))
 
-out: $(patsubst %,%.out,$(EG))
+out: $(EG) $(patsubst %,%.out,$(EG))
 
 test-sdist:
 	./test/sdist
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -37,8 +37,12 @@
 Conjuring functions
 -------------------
 
-Given
+You first need to import the library with:
 
+	import Conjure
+
+Then, given
+
 	square :: Int -> Int
 	square 0  =  0
 	square 1  =  1
@@ -61,9 +65,10 @@
 
 	square :: Int -> Int
 	-- testing 3 combinations of argument values
+	-- pruning with 14/25 rules
 	-- looking through 3 candidates of size 1
-	-- looking through 3 candidates of size 2
-	-- looking through 5 candidates of size 3
+	-- looking through 4 candidates of size 2
+	-- looking through 9 candidates of size 3
 	square x  =  x * x
 
 in less than a second.
@@ -77,12 +82,10 @@
 Given
 
 	factorial :: Int -> Int
-	factorial 0  =  1
 	factorial 1  =  1
 	factorial 2  =  2
 	factorial 3  =  6
 	factorial 4  =  24
-	factorial 5  =  120
 
 and
 
@@ -92,7 +95,6 @@
 	               , prim "+" ((+) :: Int -> Int -> Int)
 	               , prim "*" ((*) :: Int -> Int -> Int)
 	               , prim "dec" (subtract 1 :: Int -> Int)
-	               , prim "==" ((==) :: Int -> Int -> Bool)
 	               ]
 
 running
@@ -102,28 +104,26 @@
 yields
 
 	factorial :: Int -> Int
-	-- testing 6 combinations of argument values
+	-- testing 4 combinations of argument values
+	-- pruning with 22/42 rules
 	-- looking through 3 candidates of size 1
-	-- looking through 5 candidates of size 2
-	-- looking through 8 candidates of size 3
-	-- looking through 26 candidates of size 4
-	-- looking through 59 candidates of size 5
-	-- looking through 167 candidates of size 6
-	-- looking through 581 candidates of size 7
-	-- looking through 1654 candidates of size 8
-	-- looking through 5754 candidates of size 9
-	-- looking through 17797 candidates of size 10
-	factorial n  =  if n == 0 then 1 else n * factorial (dec n)
+	-- looking through 6 candidates of size 2
+	-- looking through 16 candidates of size 3
+	-- looking through 39 candidates of size 4
+	-- looking through 78 candidates of size 5
+	-- looking through 166 candidates of size 6
+	factorial 0  =  1
+	factorial x  =  x * factorial (dec x)
 
-in about 3 seconds.
+in less than a second.
 
-See the `eg/factorial.hs` example.
+It is also possible to generate
 
-It is also possible to generate:
+	factorial x  =  foldr (*) 1 [1..x]
 
-    factorial n  =  if n == 0 then 1 else n * factorial (n - 1)
+by including `enumFromTo` and `foldr` in the background.
 
-in about 90s by including `(-) :: Int -> Int -> Int` in the primitives.
+See the `eg/factorial.hs` example.
 
 
 Related work
diff --git a/TODO.md b/TODO.md
--- a/TODO.md
+++ b/TODO.md
@@ -3,14 +3,21 @@
 
 A non-exhaustive list of things TO DO for Conjure.
 
-* add switch for case candidates?
+* pretty-print top-level ifs?
 
-* improve pruning of generated case candidates
+* carry on implementing all GPS benches while taking notes on the paper
 
+* consider memoizing `recs ep` in `candidateDefnsC`
+  and a sub function with `vs` arguments.
 
-### for later
+* remove `requireDescent=False` requirement from `gcd`
+  (add and use `isDeconstruction`)
+  this would also eliminate the requirement of providing `dec`
 
-* add machinery to reify `Int -> Int` from the `(Expr,Expr)` definition
+* consider not breaking in some cases (increased crossproduct of patterns)
+
+
+### for later
 
 * allow specifying properties that need to be true
 
diff --git a/bench/candidates.hs b/bench/candidates.hs
--- a/bench/candidates.hs
+++ b/bench/candidates.hs
@@ -7,54 +7,60 @@
 import Conjure.Defn
 import Data.Express.Fixtures
 
-printCandidates :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()
-printCandidates n nm f ps  =  do
+printCandidates :: Conjurable f => Int -> Int -> String -> f -> [Prim] -> IO ()
+printCandidates m n nm f ps  =  do
   putStrLn $ "Candidates for: " ++ nm ++ " :: " ++ show (typeOf f)
   putStrLn $ "  pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"
-  putStrLn $ "  " ++ show (map length cs1) ++ " direct candidates"
-  putStrLn $ "  " ++ show (map length csC) ++ " pattern candidates"
+  putStrLn $ "  " ++ show (map length css1) ++ " direct candidates, " ++ show nd1 ++ " duplicates"
+  putStrLn $ "  " ++ show (map length cssC) ++ " pattern candidates, " ++ show ndC ++ " duplicates"
   putStrLn ""
   printThy thy
   putStrLn $ "direct candidates:\n"
-  putStrLn $ unlines $ map showDefn $ concat $ cs1
+  putStrLn $ unlines $ map showDefn $ concat $ take n $ css1
   putStrLn $ "pattern candidates:\n"
-  putStrLn $ unlines $ map showDefn $ concat $ csC
+  putStrLn $ unlines $ map showDefn $ concat $ take n $ cssC
   where
-  cs1  =  take n cs1'
-  csC  =  take n csC'
-  (cs1', thy)  =  candidateDefns1 args nm f ps
-  (csC', _)    =  candidateDefnsC args nm f ps
+  nd1  =  length cs1 - length (nubSort cs1)
+  ndC  =  length csC - length (nubSort csC)
+  cs1  =  concat css1
+  csC  =  concat cssC
+  css1  =  take m css1'
+  cssC  =  take m cssC'
+  (css1', thy)  =  candidateDefns1 args nm f ps
+  (cssC', _)    =  candidateDefnsC args nm f ps
   nRules  =  length (rules thy)
   nREs  =  length (equations thy) + nRules
 
 main :: IO ()
 main  =  do
-  printCandidates 6 "foo" (undefined :: Int -> Int)
+  printCandidates 9 6 "foo" (undefined :: Int -> Int)
     [ pr (0 :: Int)
     , pr (1 :: Int)
     , prim "+" ((+) :: Int -> Int -> Int)
     , prim "*" ((+) :: Int -> Int -> Int)
+    , prim "dec" (subtract 1 :: Int -> Int)
     ]
 
-  printCandidates 4 "?" (undefined :: Int -> Int -> Int)
+  printCandidates 9 6 "?" (undefined :: Int -> Int -> Int)
     [ pr (0 :: Int)
     , prim "+" ((+) :: Int -> Int -> Int)
     , prim "*" ((+) :: Int -> Int -> Int)
+    , prim "dec" (subtract 1 :: Int -> Int)
     ]
 
-  printCandidates 6 "goo" (undefined :: [Int] -> [Int])
+  printCandidates 9 6 "goo" (undefined :: [Int] -> [Int])
     [ pr ([] :: [Int])
     , prim ":" ((:) :: Int -> [Int] -> [Int])
     , prim "++" ((++) :: [Int] -> [Int] -> [Int])
     ]
 
-  printCandidates 4 "??" (undefined :: [Int] -> [Int] -> [Int])
+  printCandidates 9 6 "??" (undefined :: [Int] -> [Int] -> [Int])
     [ pr ([] :: [Int])
     , prim ":" ((:) :: Int -> [Int] -> [Int])
     , prim "++" ((++) :: [Int] -> [Int] -> [Int])
     ]
 
-  printCandidates 6 "ton" (undefined :: Bool -> Bool)
+  printCandidates 9 6 "ton" (undefined :: Bool -> Bool)
     [ pr False
     , pr True
     , prim "&&" (&&)
@@ -62,7 +68,7 @@
     , prim "not" not
     ]
 
-  printCandidates 6 "&|" (undefined :: Bool -> Bool -> Bool)
+  printCandidates 9 6 "&|" (undefined :: Bool -> Bool -> Bool)
     [ pr False
     , pr True
     , prim "&&" (&&)
diff --git a/bench/candidates.out b/bench/candidates.out
--- a/bench/candidates.out
+++ b/bench/candidates.out
@@ -1,1707 +1,7250 @@
 Candidates for: foo :: Int -> Int
-  pruning with 6/10 rules
-  [3,0,4,0,8,0] direct candidates
-  [3,4,8,21,39,70] pattern candidates
-
-rules:
-x * y == x + y
-x * y == y + x
-x + 0 == x
-0 + x == x
-(x + y) + z == x + (y + z)
-(x + y) + z == y + (x + z)
-equations:
-y + x == x + y
-y + (x + z) == x + (y + z)
-z + (x + y) == x + (y + z)
-z + (y + x) == x + (y + z)
-
-direct candidates:
-
-foo x  =  x
-
-foo x  =  0
-
-foo x  =  1
-
-foo x  =  x + x
-
-foo x  =  x + 1
-
-foo x  =  1 + x
-
-foo x  =  1 + 1
-
-foo x  =  x + (x + x)
-
-foo x  =  x + (x + 1)
-
-foo x  =  x + (1 + x)
-
-foo x  =  x + (1 + 1)
-
-foo x  =  1 + (x + x)
-
-foo x  =  1 + (x + 1)
-
-foo x  =  1 + (1 + x)
-
-foo x  =  1 + (1 + 1)
-
-
-pattern candidates:
-
-foo x  =  x
-
-foo x  =  0
-
-foo x  =  1
-
-foo 0  =  0
-foo x  =  x
-
-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  =  1 + x
-
-foo x  =  1 + 1
-
-foo 1  =  0
-foo x  =  x
-
-foo 1  =  0
-foo x  =  1
-
-foo 1  =  1
-foo x  =  x
-
-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  =  1 + x
-
-foo 0  =  0
-foo x  =  1 + 1
-
-foo 0  =  1
-foo x  =  x + x
-
-foo 0  =  1
-foo x  =  x + 1
-
-foo 0  =  1
-foo x  =  1 + x
-
-foo 0  =  1
-foo x  =  1 + 1
-
-foo 0  =  1 + 1
-foo x  =  x
-
-foo 0  =  1 + 1
-foo x  =  0
-
-foo 0  =  1 + 1
-foo x  =  1
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  x
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  1
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  x
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  0
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  1
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  x
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  0
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  1
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  x
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  0
-
-foo 0  =  0
-foo x  =  foo (x + x)
-
-foo 0  =  0
-foo x  =  foo (x + 1)
-
-foo 0  =  0
-foo x  =  foo (x + 1)
-
-foo 0  =  0
-foo x  =  foo (1 + x)
-
-foo 0  =  0
-foo x  =  foo (1 + x)
-
-foo 0  =  0
-foo x  =  foo (x + x)
-
-foo 0  =  0
-foo x  =  foo (x + 1)
-
-foo 0  =  0
-foo x  =  foo (x + 1)
-
-foo 0  =  0
-foo x  =  foo (1 + x)
-
-foo 0  =  0
-foo x  =  foo (1 + x)
-
-foo 0  =  1
-foo x  =  foo (x + x)
-
-foo 0  =  1
-foo x  =  foo (x + 1)
-
-foo 0  =  1
-foo x  =  foo (x + 1)
-
-foo 0  =  1
-foo x  =  foo (1 + x)
-
-foo 0  =  1
-foo x  =  foo (1 + x)
-
-foo 0  =  1
-foo x  =  foo (x + x)
-
-foo 0  =  1
-foo x  =  foo (x + 1)
-
-foo 0  =  1
-foo x  =  foo (x + 1)
-
-foo 0  =  1
-foo x  =  foo (1 + x)
-
-foo 0  =  1
-foo x  =  foo (1 + x)
-
-foo x  =  x + (x + x)
-
-foo x  =  x + (x + 1)
-
-foo x  =  x + (1 + x)
-
-foo x  =  x + (1 + 1)
-
-foo x  =  1 + (x + x)
-
-foo x  =  1 + (x + 1)
-
-foo x  =  1 + (1 + x)
-
-foo x  =  1 + (1 + 1)
-
-foo 1  =  0
-foo x  =  x + x
-
-foo 1  =  0
-foo x  =  x + 1
-
-foo 1  =  0
-foo x  =  1 + x
-
-foo 1  =  0
-foo x  =  1 + 1
-
-foo 1  =  1
-foo x  =  x + x
-
-foo 1  =  1
-foo x  =  x + 1
-
-foo 1  =  1
-foo x  =  1 + x
-
-foo 1  =  1
-foo x  =  1 + 1
-
-foo 1  =  1 + 1
-foo x  =  x
-
-foo 1  =  1 + 1
-foo x  =  0
-
-foo 1  =  1 + 1
-foo x  =  1
-
-foo 1  =  0
-foo x  =  foo (x + x)
-
-foo 1  =  0
-foo x  =  foo (x + 1)
-
-foo 1  =  0
-foo x  =  foo (x + 1)
-
-foo 1  =  0
-foo x  =  foo (1 + x)
-
-foo 1  =  0
-foo x  =  foo (1 + x)
-
-foo 1  =  0
-foo x  =  foo (x + x)
-
-foo 1  =  0
-foo x  =  foo (x + 1)
-
-foo 1  =  0
-foo x  =  foo (x + 1)
-
-foo 1  =  0
-foo x  =  foo (1 + x)
-
-foo 1  =  0
-foo x  =  foo (1 + x)
-
-foo 1  =  1
-foo x  =  foo (x + x)
-
-foo 1  =  1
-foo x  =  foo (x + 1)
-
-foo 1  =  1
-foo x  =  foo (x + 1)
-
-foo 1  =  1
-foo x  =  foo (1 + x)
-
-foo 1  =  1
-foo x  =  foo (1 + x)
-
-foo 1  =  1
-foo x  =  foo (x + x)
-
-foo 1  =  1
-foo x  =  foo (x + 1)
-
-foo 1  =  1
-foo x  =  foo (x + 1)
-
-foo 1  =  1
-foo x  =  foo (1 + 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 + (1 + x)
-
-foo 0  =  0
-foo x  =  x + (1 + 1)
-
-foo 0  =  0
-foo x  =  1 + (x + x)
-
-foo 0  =  0
-foo x  =  1 + (x + 1)
-
-foo 0  =  0
-foo x  =  1 + (1 + x)
-
-foo 0  =  0
-foo x  =  1 + (1 + 1)
-
-foo 0  =  1
-foo x  =  x + (x + x)
-
-foo 0  =  1
-foo x  =  x + (x + 1)
-
-foo 0  =  1
-foo x  =  x + (1 + x)
-
-foo 0  =  1
-foo x  =  x + (1 + 1)
-
-foo 0  =  1
-foo x  =  1 + (x + x)
-
-foo 0  =  1
-foo x  =  1 + (x + 1)
-
-foo 0  =  1
-foo x  =  1 + (1 + x)
-
-foo 0  =  1
-foo x  =  1 + (1 + 1)
-
-foo 0  =  1 + 1
-foo x  =  x + x
-
-foo 0  =  1 + 1
-foo x  =  x + 1
-
-foo 0  =  1 + 1
-foo x  =  1 + x
-
-foo 0  =  1 + (1 + 1)
-foo x  =  x
-
-foo 0  =  1 + (1 + 1)
-foo x  =  0
-
-foo 0  =  1 + (1 + 1)
-foo 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  =  1 + x
-
-foo 0  =  0
-foo 1  =  0
-foo x  =  1 + 1
-
-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  =  1 + x
-
-foo 0  =  0
-foo 1  =  1
-foo x  =  1 + 1
-
-foo 0  =  0
-foo 1  =  1 + 1
-foo x  =  x
-
-foo 0  =  0
-foo 1  =  1 + 1
-foo x  =  0
-
-foo 0  =  0
-foo 1  =  1 + 1
-foo x  =  1
-
-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  =  1 + x
-
-foo 0  =  1
-foo 1  =  0
-foo x  =  1 + 1
-
-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  =  1 + x
-
-foo 0  =  1
-foo 1  =  1
-foo x  =  1 + 1
-
-foo 0  =  1
-foo 1  =  1 + 1
-foo x  =  x
-
-foo 0  =  1
-foo 1  =  1 + 1
-foo x  =  0
-
-foo 0  =  1
-foo 1  =  1 + 1
-foo x  =  1
-
-foo 0  =  1 + 1
-foo 1  =  0
-foo x  =  x
-
-foo 0  =  1 + 1
-foo 1  =  0
-foo x  =  0
-
-foo 0  =  1 + 1
-foo 1  =  0
-foo x  =  1
-
-foo 0  =  1 + 1
-foo 1  =  1
-foo x  =  x
-
-foo 0  =  1 + 1
-foo 1  =  1
-foo x  =  0
-
-foo 0  =  1 + 1
-foo 1  =  1
-foo x  =  1
-
-
-Candidates for: ? :: Int -> Int -> Int
-  pruning with 6/10 rules
-  [3,0,4,0] direct candidates
-  [3,8,15,84] pattern candidates
-
-rules:
-x * y == x + y
-x * y == y + x
-x + 0 == x
-0 + x == x
-(x + y) + z == x + (y + z)
-(x + y) + z == y + (x + z)
-equations:
-y + x == x + y
-y + (x + z) == x + (y + z)
-z + (x + y) == x + (y + z)
-z + (y + x) == x + (y + z)
-
-direct candidates:
-
-x ? y  =  x
-
-x ? y  =  y
-
-x ? y  =  0
-
-x ? y  =  x + x
-
-x ? y  =  x + y
-
-x ? y  =  y + x
-
-x ? y  =  y + y
-
-
-pattern candidates:
-
-x ? y  =  x
-
-x ? y  =  y
-
-x ? y  =  0
-
-x ? 0  =  x
-x ? y  =  y
-
-x ? 0  =  x
-x ? y  =  0
-
-x ? 0  =  0
-x ? y  =  x
-
-x ? 0  =  0
-x ? y  =  y
-
-0 ? x  =  x
-x ? y  =  y
-
-0 ? x  =  x
-x ? y  =  0
-
-0 ? x  =  0
-x ? y  =  x
-
-0 ? x  =  0
-x ? y  =  y
-
-x ? y  =  x + x
-
-x ? y  =  x + y
-
-x ? y  =  y + x
-
-x ? y  =  y + y
-
-0 ? 0  =  0
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  x
-
-0 ? 0  =  0
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  y
-
-0 ? 0  =  0
-0 ? x  =  x
-x ? 0  =  x
-x ? y  =  0
-
-0 ? 0  =  0
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  x
-
-0 ? 0  =  0
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  y
-
-0 ? 0  =  0
-0 ? x  =  x
-x ? 0  =  0
-x ? y  =  0
-
-0 ? 0  =  0
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  x
-
-0 ? 0  =  0
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  y
-
-0 ? 0  =  0
-0 ? x  =  0
-x ? 0  =  x
-x ? y  =  0
-
-0 ? 0  =  0
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  x
-
-0 ? 0  =  0
-0 ? x  =  0
-x ? 0  =  0
-x ? y  =  y
-
-x ? 0  =  x
-x ? y  =  x ? x
-
-x ? 0  =  x
-x ? y  =  x ? 0
-
-x ? 0  =  x
-x ? y  =  x ? 0
-
-x ? 0  =  x
-x ? y  =  y ? x
-
-x ? 0  =  x
-x ? y  =  y ? y
-
-x ? 0  =  x
-x ? y  =  y ? 0
-
-x ? 0  =  x
-x ? y  =  y ? 0
-
-x ? 0  =  x
-x ? y  =  0 ? x
-
-x ? 0  =  x
-x ? y  =  0 ? y
-
-x ? 0  =  x
-x ? y  =  0 ? x
-
-x ? 0  =  x
-x ? y  =  0 ? y
-
-x ? 0  =  x ? x
-x ? y  =  x
-
-x ? 0  =  0 ? x
-x ? y  =  x
-
-x ? 0  =  0 ? x
-x ? y  =  x
-
-x ? 0  =  x ? x
-x ? y  =  y
-
-x ? 0  =  0 ? x
-x ? y  =  y
-
-x ? 0  =  0 ? x
-x ? y  =  y
-
-x ? 0  =  x ? x
-x ? y  =  0
-
-x ? 0  =  0 ? x
-x ? y  =  0
-
-x ? 0  =  0 ? x
-x ? y  =  0
-
-x ? 0  =  0
-x ? y  =  x ? x
-
-x ? 0  =  0
-x ? y  =  x ? 0
-
-x ? 0  =  0
-x ? y  =  x ? 0
-
-x ? 0  =  0
-x ? y  =  y ? x
-
-x ? 0  =  0
-x ? y  =  y ? y
-
-x ? 0  =  0
-x ? y  =  y ? 0
-
-x ? 0  =  0
-x ? y  =  y ? 0
-
-x ? 0  =  0
-x ? y  =  0 ? x
-
-x ? 0  =  0
-x ? y  =  0 ? y
-
-x ? 0  =  0
-x ? y  =  0 ? x
-
-x ? 0  =  0
-x ? y  =  0 ? y
-
-0 ? x  =  x
-x ? y  =  x ? x
-
-0 ? x  =  x
-x ? y  =  x ? 0
-
-0 ? x  =  x
-x ? y  =  x ? 0
-
-0 ? x  =  x
-x ? y  =  y ? x
-
-0 ? x  =  x
-x ? y  =  y ? y
-
-0 ? x  =  x
-x ? y  =  y ? 0
-
-0 ? x  =  x
-x ? y  =  y ? 0
-
-0 ? x  =  x
-x ? y  =  0 ? x
-
-0 ? x  =  x
-x ? y  =  0 ? y
-
-0 ? x  =  x
-x ? y  =  0 ? x
-
-0 ? x  =  x
-x ? y  =  0 ? y
-
-0 ? x  =  x ? x
-x ? y  =  x
-
-0 ? x  =  x ? 0
-x ? y  =  x
-
-0 ? x  =  x ? 0
-x ? y  =  x
-
-0 ? x  =  x ? x
-x ? y  =  y
-
-0 ? x  =  x ? 0
-x ? y  =  y
-
-0 ? x  =  x ? 0
-x ? y  =  y
-
-0 ? x  =  x ? x
-x ? y  =  0
-
-0 ? x  =  x ? 0
-x ? y  =  0
-
-0 ? x  =  x ? 0
-x ? y  =  0
-
-0 ? x  =  0
-x ? y  =  x ? x
-
-0 ? x  =  0
-x ? y  =  x ? 0
-
-0 ? x  =  0
-x ? y  =  x ? 0
-
-0 ? x  =  0
-x ? y  =  y ? x
-
-0 ? x  =  0
-x ? y  =  y ? y
-
-0 ? x  =  0
-x ? y  =  y ? 0
-
-0 ? x  =  0
-x ? y  =  y ? 0
-
-0 ? x  =  0
-x ? y  =  0 ? x
-
-0 ? x  =  0
-x ? y  =  0 ? y
-
-0 ? x  =  0
-x ? y  =  0 ? x
-
-0 ? x  =  0
-x ? y  =  0 ? y
-
-x ? 0  =  x
-x ? y  =  x + x
-
-x ? 0  =  x
-x ? y  =  x + y
-
-x ? 0  =  x
-x ? y  =  y + x
-
-x ? 0  =  x
-x ? y  =  y + y
-
-x ? 0  =  0
-x ? y  =  x + x
-
-x ? 0  =  0
-x ? y  =  x + y
-
-x ? 0  =  0
-x ? y  =  y + x
-
-x ? 0  =  0
-x ? y  =  y + y
-
-x ? 0  =  x + x
-x ? y  =  x
-
-x ? 0  =  x + x
-x ? y  =  y
-
-x ? 0  =  x + x
-x ? y  =  0
-
-0 ? x  =  x
-x ? y  =  x + x
-
-0 ? x  =  x
-x ? y  =  x + y
-
-0 ? x  =  x
-x ? y  =  y + x
-
-0 ? x  =  x
-x ? y  =  y + y
-
-0 ? x  =  0
-x ? y  =  x + x
-
-0 ? x  =  0
-x ? y  =  x + y
-
-0 ? x  =  0
-x ? y  =  y + x
-
-0 ? x  =  0
-x ? y  =  y + y
-
-0 ? x  =  x + x
-x ? y  =  x
-
-0 ? x  =  x + x
-x ? y  =  y
-
-0 ? x  =  x + x
-x ? y  =  0
-
-
-Candidates for: goo :: [Int] -> [Int]
-  pruning with 4/4 rules
-  [2,0,1,0,1,0] direct candidates
-  [2,1,2,3,10,7] pattern candidates
-
-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)  =  goo [x]
-
-goo []  =  []
-goo (x:xs)  =  goo [x]
-
-goo []  =  []
-goo (x:xs)  =  goo [x]
-
-goo []  =  []
-goo (x:xs)  =  goo [x]
-
-goo []  =  []
-goo (x:xs)  =  goo (xs ++ xs)
-
-goo []  =  []
-goo (x:xs)  =  goo (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] direct candidates
-  [3,8,15,82] pattern candidates
-
-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
-
-
-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  =  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
-
-[] ?? []  =  []
-[] ?? (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
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  xs
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  ys
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  []
-(x:xs) ?? []  =  xs
-(x:xs) ?? (y:ys)  =  []
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  xs
-
-[] ?? []  =  []
-[] ?? (x:xs)  =  []
-(x:xs) ?? []  =  []
-(x:xs) ?? (y:ys)  =  ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  xs ?? []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? xs
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? ys
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  ys ?? []
-
-xs ?? []  =  xs
-xs ?? (x:ys)  =  [] ?? xs
-
-xs ?? []  =  xs
-xs ?? (x: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)  =  xs ?? []
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  xs ?? []
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? xs
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? ys
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? []
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  ys ?? []
-
-xs ?? []  =  []
-xs ?? (x:ys)  =  [] ?? xs
-
-xs ?? []  =  []
-xs ?? (x: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  =  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  =  ys ?? []
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  [] ?? xs
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  [] ?? ys
-
-[] ?? xs  =  xs
-(x:xs) ?? ys  =  [] ?? xs
-
-[] ?? 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  =  xs ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  ys ?? []
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  [] ?? xs
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  [] ?? ys
-
-[] ?? xs  =  []
-(x:xs) ?? ys  =  [] ?? 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  =  []
-
-
-Candidates for: ton :: Bool -> Bool
-  pruning with 39/49 rules
-  [3,1,0,0,2,4] direct candidates
-  [3,3,0,0,0,0] pattern 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
-
-direct candidates:
-
-ton p  =  p
-
-ton p  =  False
-
-ton p  =  True
-
-ton p  =  not p
-
-ton p  =  p && ton (not p)
-
-ton p  =  p || ton (not 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)
-
-
-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,4,8,4,72] direct candidates
-  [4,14,30,8,4,32] pattern 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
-
-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  =  q && p
-
-p &| q  =  p || q
-
-p &| q  =  q || p
-
-p &| q  =  not p && q
-
-p &| q  =  not q && p
-
-p &| q  =  not p || q
-
-p &| q  =  not q || p
-
-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 q && not p
-
-p &| q  =  not p || not q
-
-p &| q  =  not q || not p
-
-p &| q  =  p && (not p && q)
-
-p &| q  =  p && (not p || q)
-
-p &| q  =  p && (q && not p)
-
-p &| q  =  p && (q || not p)
-
-p &| q  =  q && (not q && p)
-
-p &| q  =  q && (not q || p)
-
-p &| q  =  q && (p && not q)
-
-p &| q  =  q && (p || not q)
-
-p &| q  =  p || not p && q
-
-p &| q  =  p || (not p || q)
-
-p &| q  =  p || q && not p
-
-p &| q  =  p || (q || not p)
-
-p &| q  =  q || not q && p
-
-p &| q  =  q || (not q || p)
-
-p &| q  =  q || p && not q
-
-p &| q  =  q || (p || not q)
-
-p &| q  =  not p && (p || q)
-
-p &| q  =  not p && (q || p)
-
-p &| q  =  not q && (p || q)
-
-p &| q  =  not q && (q || p)
-
-p &| q  =  not p || p && q
-
-p &| q  =  not p || q && p
-
-p &| q  =  not q || p && q
-
-p &| q  =  not q || q && p
-
-p &| q  =  (p || q) && not p
-
-p &| q  =  (p || q) && not q
-
-p &| q  =  (q || p) && not p
-
-p &| q  =  (q || p) && not q
-
-p &| q  =  p && q || not p
-
-p &| q  =  p && q || not q
-
-p &| q  =  q && p || not p
-
-p &| q  =  q && p || not q
-
-p &| q  =  p && p &| not q
-
-p &| q  =  p && q &| not p
-
-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 &| p
-
-p &| q  =  q && p &| not q
-
-p &| q  =  q && q &| not p
-
-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 &| p
-
-p &| q  =  p || p &| not q
-
-p &| q  =  p || q &| not p
-
-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 &| p
-
-p &| q  =  q || p &| not q
-
-p &| q  =  q || q &| not p
-
-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 &| p
+  pruning with 13/26 rules
+  [3,2,4,3,12,7,27,25,58] direct candidates, 0 duplicates
+  [3,6,15,34,61,111,174,344,529] pattern candidates, 0 duplicates
+
+rules:
+dec 1 == 0
+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
+1 + dec x == x
+dec x + 1 == 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:
+
+foo x  =  x
+
+foo x  =  0
+
+foo x  =  1
+
+foo x  =  dec x
+
+foo x  =  dec 0
+
+foo x  =  x + x
+
+foo x  =  x + 1
+
+foo x  =  1 + x
+
+foo x  =  1 + 1
+
+foo x  =  dec 0 + x
+
+foo x  =  x + dec x
+
+foo x  =  x + dec 0
+
+foo x  =  x + (x + x)
+
+foo x  =  x + (x + 1)
+
+foo x  =  x + (1 + x)
+
+foo x  =  x + (1 + 1)
+
+foo x  =  1 + (x + x)
+
+foo x  =  1 + (x + 1)
+
+foo x  =  1 + (1 + x)
+
+foo x  =  1 + (1 + 1)
+
+foo x  =  dec x + dec x
+
+foo x  =  dec x + dec 0
+
+foo x  =  dec 0 + dec x
+
+foo x  =  dec 0 + dec 0
+
+foo x  =  x + (dec 0 + x)
+
+foo x  =  x + (x + dec x)
+
+foo x  =  x + (x + dec 0)
+
+foo x  =  1 + (dec 0 + x)
+
+foo x  =  1 + (x + dec x)
+
+foo x  =  1 + (x + dec 0)
+
+foo x  =  dec 0 + (x + x)
+
+
+pattern candidates:
+
+foo x  =  x
+
+foo x  =  0
+
+foo x  =  1
+
+foo x  =  dec x
+
+foo x  =  dec 0
+
+foo 0  =  0
+foo x  =  x
+
+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  =  1 + x
+
+foo x  =  1 + 1
+
+foo 0  =  0
+foo x  =  dec x
+
+foo 0  =  0
+foo x  =  dec 0
+
+foo 0  =  1
+foo x  =  dec x
+
+foo 0  =  1
+foo x  =  dec 0
+
+foo 0  =  dec 0
+foo x  =  x
+
+foo 0  =  dec 0
+foo x  =  0
+
+foo 0  =  dec 0
+foo x  =  1
+
+foo 1  =  0
+foo x  =  x
+
+foo 1  =  0
+foo x  =  1
+
+foo 1  =  1
+foo x  =  x
+
+foo 1  =  1
+foo x  =  0
+
+foo 0  =  0
+foo x  =  foo (dec x)
+
+foo 0  =  1
+foo x  =  foo (dec x)
+
+foo x  =  dec 0 + x
+
+foo x  =  x + dec x
+
+foo x  =  x + dec 0
+
+foo 0  =  0
+foo x  =  x + x
+
+foo 0  =  0
+foo x  =  x + 1
+
+foo 0  =  0
+foo x  =  1 + x
+
+foo 0  =  0
+foo x  =  1 + 1
+
+foo 0  =  1
+foo x  =  x + x
+
+foo 0  =  1
+foo x  =  x + 1
+
+foo 0  =  1
+foo x  =  1 + x
+
+foo 0  =  1
+foo x  =  1 + 1
+
+foo 0  =  dec 0
+foo x  =  dec x
+
+foo 0  =  1 + 1
+foo x  =  x
+
+foo 0  =  1 + 1
+foo x  =  0
+
+foo 0  =  1 + 1
+foo x  =  1
+
+foo 1  =  0
+foo x  =  dec x
+
+foo 1  =  0
+foo x  =  dec 0
+
+foo 1  =  1
+foo x  =  dec x
+
+foo 1  =  1
+foo x  =  dec 0
+
+foo 1  =  dec 0
+foo x  =  x
+
+foo 1  =  dec 0
+foo x  =  0
+
+foo 1  =  dec 0
+foo x  =  1
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  x
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  1
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  x
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  0
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  1
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  x
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  0
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  1
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  x
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  0
+
+foo 0  =  0
+foo x  =  dec (foo (dec x))
+
+foo 0  =  1
+foo x  =  dec (foo (dec x))
+
+foo 0  =  dec 0
+foo x  =  foo (dec x)
+
+foo 1  =  0
+foo x  =  foo (dec x)
+
+foo 1  =  1
+foo x  =  foo (dec x)
+
+foo x  =  x + (x + x)
+
+foo x  =  x + (x + 1)
+
+foo x  =  x + (1 + x)
+
+foo x  =  x + (1 + 1)
+
+foo x  =  1 + (x + x)
+
+foo x  =  1 + (x + 1)
+
+foo x  =  1 + (1 + x)
+
+foo x  =  1 + (1 + 1)
+
+foo x  =  dec x + dec x
+
+foo x  =  dec x + dec 0
+
+foo x  =  dec 0 + dec x
+
+foo x  =  dec 0 + dec 0
+
+foo 0  =  0
+foo x  =  dec 0 + x
+
+foo 0  =  0
+foo x  =  x + dec x
+
+foo 0  =  0
+foo x  =  x + dec 0
+
+foo 0  =  1
+foo x  =  dec 0 + x
+
+foo 0  =  1
+foo x  =  x + dec x
+
+foo 0  =  1
+foo x  =  x + dec 0
+
+foo 0  =  dec 0
+foo x  =  x + x
+
+foo 0  =  dec 0
+foo x  =  x + 1
+
+foo 0  =  dec 0
+foo x  =  1 + x
+
+foo 0  =  dec 0
+foo x  =  1 + 1
+
+foo 0  =  1 + 1
+foo x  =  dec x
+
+foo 0  =  1 + 1
+foo x  =  dec 0
+
+foo 1  =  0
+foo x  =  x + x
+
+foo 1  =  0
+foo x  =  x + 1
+
+foo 1  =  0
+foo x  =  1 + x
+
+foo 1  =  0
+foo x  =  1 + 1
+
+foo 1  =  1
+foo x  =  x + x
+
+foo 1  =  1
+foo x  =  x + 1
+
+foo 1  =  1
+foo x  =  1 + x
+
+foo 1  =  1
+foo x  =  1 + 1
+
+foo 1  =  dec 0
+foo x  =  dec x
+
+foo 1  =  1 + 1
+foo x  =  x
+
+foo 1  =  1 + 1
+foo x  =  0
+
+foo 1  =  1 + 1
+foo x  =  1
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  dec x
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  dec 0
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  dec x
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  dec 0
+
+foo 0  =  0
+foo 1  =  dec 0
+foo x  =  x
+
+foo 0  =  0
+foo 1  =  dec 0
+foo x  =  0
+
+foo 0  =  0
+foo 1  =  dec 0
+foo x  =  1
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  dec x
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  dec 0
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  dec x
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  dec 0
+
+foo 0  =  1
+foo 1  =  dec 0
+foo x  =  x
+
+foo 0  =  1
+foo 1  =  dec 0
+foo x  =  0
+
+foo 0  =  1
+foo 1  =  dec 0
+foo x  =  1
+
+foo 0  =  dec 0
+foo 1  =  0
+foo x  =  x
+
+foo 0  =  dec 0
+foo 1  =  0
+foo x  =  0
+
+foo 0  =  dec 0
+foo 1  =  0
+foo x  =  1
+
+foo 0  =  dec 0
+foo 1  =  1
+foo x  =  x
+
+foo 0  =  dec 0
+foo 1  =  1
+foo x  =  0
+
+foo 0  =  dec 0
+foo 1  =  1
+foo x  =  1
+
+foo 0  =  0
+foo x  =  x + foo (dec x)
+
+foo 0  =  0
+foo x  =  foo (dec x) + x
+
+foo 0  =  0
+foo x  =  foo (dec x) + 1
+
+foo 0  =  0
+foo x  =  1 + foo (dec x)
+
+foo 0  =  1
+foo x  =  x + foo (dec x)
+
+foo 0  =  1
+foo x  =  foo (dec x) + x
+
+foo 0  =  1
+foo x  =  foo (dec x) + 1
+
+foo 0  =  1
+foo x  =  1 + foo (dec x)
+
+foo 0  =  dec 0
+foo x  =  dec (foo (dec x))
+
+foo 0  =  1 + 1
+foo x  =  foo (dec x)
+
+foo 1  =  0
+foo x  =  dec (foo (dec x))
+
+foo 1  =  1
+foo x  =  dec (foo (dec x))
+
+foo 1  =  dec 0
+foo x  =  foo (dec x)
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  foo (dec x)
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  foo (dec x)
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  foo (dec x)
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  foo (dec x)
+
+foo x  =  x + (dec 0 + x)
+
+foo x  =  x + (x + dec x)
+
+foo x  =  x + (x + dec 0)
+
+foo x  =  1 + (dec 0 + x)
+
+foo x  =  1 + (x + dec x)
+
+foo x  =  1 + (x + dec 0)
+
+foo x  =  dec 0 + (x + x)
+
+foo 0  =  0
+foo x  =  x + (x + x)
+
+foo 0  =  0
+foo x  =  x + (x + 1)
+
+foo 0  =  0
+foo x  =  x + (1 + x)
+
+foo 0  =  0
+foo x  =  x + (1 + 1)
+
+foo 0  =  0
+foo x  =  1 + (x + x)
+
+foo 0  =  0
+foo x  =  1 + (x + 1)
+
+foo 0  =  0
+foo x  =  1 + (1 + x)
+
+foo 0  =  0
+foo x  =  1 + (1 + 1)
+
+foo 0  =  0
+foo x  =  dec x + dec x
+
+foo 0  =  0
+foo x  =  dec x + dec 0
+
+foo 0  =  0
+foo x  =  dec 0 + dec x
+
+foo 0  =  0
+foo x  =  dec 0 + dec 0
+
+foo 0  =  1
+foo x  =  x + (x + x)
+
+foo 0  =  1
+foo x  =  x + (x + 1)
+
+foo 0  =  1
+foo x  =  x + (1 + x)
+
+foo 0  =  1
+foo x  =  x + (1 + 1)
+
+foo 0  =  1
+foo x  =  1 + (x + x)
+
+foo 0  =  1
+foo x  =  1 + (x + 1)
+
+foo 0  =  1
+foo x  =  1 + (1 + x)
+
+foo 0  =  1
+foo x  =  1 + (1 + 1)
+
+foo 0  =  1
+foo x  =  dec x + dec x
+
+foo 0  =  1
+foo x  =  dec x + dec 0
+
+foo 0  =  1
+foo x  =  dec 0 + dec x
+
+foo 0  =  1
+foo x  =  dec 0 + dec 0
+
+foo 0  =  dec 0
+foo x  =  dec 0 + x
+
+foo 0  =  dec 0
+foo x  =  x + dec x
+
+foo 0  =  dec 0
+foo x  =  x + dec 0
+
+foo 0  =  1 + 1
+foo x  =  x + x
+
+foo 0  =  1 + 1
+foo x  =  x + 1
+
+foo 0  =  1 + 1
+foo x  =  1 + x
+
+foo 0  =  1 + (1 + 1)
+foo x  =  x
+
+foo 0  =  1 + (1 + 1)
+foo x  =  0
+
+foo 0  =  1 + (1 + 1)
+foo x  =  1
+
+foo 0  =  dec 0 + dec 0
+foo x  =  x
+
+foo 0  =  dec 0 + dec 0
+foo x  =  0
+
+foo 0  =  dec 0 + dec 0
+foo x  =  1
+
+foo 1  =  0
+foo x  =  dec 0 + x
+
+foo 1  =  0
+foo x  =  x + dec x
+
+foo 1  =  0
+foo x  =  x + dec 0
+
+foo 1  =  1
+foo x  =  dec 0 + x
+
+foo 1  =  1
+foo x  =  x + dec x
+
+foo 1  =  1
+foo x  =  x + dec 0
+
+foo 1  =  dec 0
+foo x  =  x + x
+
+foo 1  =  dec 0
+foo x  =  x + 1
+
+foo 1  =  dec 0
+foo x  =  1 + x
+
+foo 1  =  dec 0
+foo x  =  1 + 1
+
+foo 1  =  1 + 1
+foo x  =  dec x
+
+foo 1  =  1 + 1
+foo x  =  dec 0
+
+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  =  1 + x
+
+foo 0  =  0
+foo 1  =  0
+foo x  =  1 + 1
+
+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  =  1 + x
+
+foo 0  =  0
+foo 1  =  1
+foo x  =  1 + 1
+
+foo 0  =  0
+foo 1  =  dec 0
+foo x  =  dec x
+
+foo 0  =  0
+foo 1  =  dec 0
+foo x  =  dec 0
+
+foo 0  =  0
+foo 1  =  1 + 1
+foo x  =  x
+
+foo 0  =  0
+foo 1  =  1 + 1
+foo x  =  0
+
+foo 0  =  0
+foo 1  =  1 + 1
+foo x  =  1
+
+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  =  1 + x
+
+foo 0  =  1
+foo 1  =  0
+foo x  =  1 + 1
+
+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  =  1 + x
+
+foo 0  =  1
+foo 1  =  1
+foo x  =  1 + 1
+
+foo 0  =  1
+foo 1  =  dec 0
+foo x  =  dec x
+
+foo 0  =  1
+foo 1  =  dec 0
+foo x  =  dec 0
+
+foo 0  =  1
+foo 1  =  1 + 1
+foo x  =  x
+
+foo 0  =  1
+foo 1  =  1 + 1
+foo x  =  0
+
+foo 0  =  1
+foo 1  =  1 + 1
+foo x  =  1
+
+foo 0  =  dec 0
+foo 1  =  0
+foo x  =  dec x
+
+foo 0  =  dec 0
+foo 1  =  0
+foo x  =  dec 0
+
+foo 0  =  dec 0
+foo 1  =  1
+foo x  =  dec x
+
+foo 0  =  dec 0
+foo 1  =  1
+foo x  =  dec 0
+
+foo 0  =  dec 0
+foo 1  =  dec 0
+foo x  =  x
+
+foo 0  =  dec 0
+foo 1  =  dec 0
+foo x  =  0
+
+foo 0  =  dec 0
+foo 1  =  dec 0
+foo x  =  1
+
+foo 0  =  1 + 1
+foo 1  =  0
+foo x  =  x
+
+foo 0  =  1 + 1
+foo 1  =  0
+foo x  =  0
+
+foo 0  =  1 + 1
+foo 1  =  0
+foo x  =  1
+
+foo 0  =  1 + 1
+foo 1  =  1
+foo x  =  x
+
+foo 0  =  1 + 1
+foo 1  =  1
+foo x  =  0
+
+foo 0  =  1 + 1
+foo 1  =  1
+foo x  =  1
+
+
+Candidates for: ? :: Int -> Int -> Int
+  pruning with 10/23 rules
+  [3,3,4,10,17,26,54,93,162] direct candidates, 0 duplicates
+  [3,11,39,88,245,596,1542,3881,9466] 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 + x
+
+x ? y  =  y + y
+
+x ? y  =  dec x + y
+
+x ? y  =  dec y + x
+
+x ? y  =  dec 0 + x
+
+x ? y  =  dec 0 + y
+
+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  =  x + (x + x)
+
+x ? y  =  x + (x + y)
+
+x ? y  =  x + (y + x)
+
+x ? y  =  x + (y + y)
+
+x ? y  =  y + (x + x)
+
+x ? y  =  y + (x + y)
+
+x ? y  =  y + (y + x)
+
+x ? y  =  y + (y + y)
+
+x ? y  =  dec x + dec x
+
+x ? y  =  dec x + dec y
+
+x ? y  =  dec x + dec 0
+
+x ? y  =  dec y + dec x
+
+x ? y  =  dec y + dec y
+
+x ? y  =  dec y + dec 0
+
+x ? y  =  dec 0 + dec x
+
+x ? y  =  dec 0 + dec y
+
+x ? y  =  dec 0 + dec 0
+
+x ? y  =  x + (dec x + y)
+
+x ? y  =  x + (dec y + x)
+
+x ? y  =  x + (dec 0 + x)
+
+x ? y  =  x + (dec 0 + y)
+
+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 x + y)
+
+x ? y  =  y + (dec y + x)
+
+x ? y  =  y + (dec 0 + x)
+
+x ? y  =  y + (dec 0 + y)
+
+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 + (y + y)
+
+x ? y  =  dec y + (x + x)
+
+x ? y  =  dec 0 + (x + x)
+
+x ? y  =  dec 0 + (x + y)
+
+x ? y  =  dec 0 + (y + x)
+
+x ? y  =  dec 0 + (y + y)
+
+
+pattern candidates:
+
+x ? y  =  x
+
+x ? y  =  y
+
+x ? y  =  0
+
+x ? y  =  dec x
+
+x ? y  =  dec y
+
+x ? y  =  dec 0
+
+x ? 0  =  x
+x ? y  =  y
+
+x ? 0  =  x
+x ? y  =  0
+
+x ? 0  =  0
+x ? y  =  x
+
+x ? 0  =  0
+x ? y  =  y
+
+0 ? x  =  x
+x ? y  =  y
+
+0 ? x  =  x
+x ? y  =  0
+
+0 ? x  =  0
+x ? y  =  x
+
+0 ? x  =  0
+x ? y  =  y
+
+x ? y  =  x + x
+
+x ? y  =  x + y
+
+x ? y  =  y + x
+
+x ? y  =  y + y
+
+x ? 0  =  x
+x ? y  =  dec x
+
+x ? 0  =  x
+x ? y  =  dec y
+
+x ? 0  =  x
+x ? y  =  dec 0
+
+x ? 0  =  0
+x ? y  =  dec x
+
+x ? 0  =  0
+x ? y  =  dec y
+
+x ? 0  =  0
+x ? y  =  dec 0
+
+x ? 0  =  dec x
+x ? y  =  x
+
+x ? 0  =  dec x
+x ? y  =  y
+
+x ? 0  =  dec x
+x ? y  =  0
+
+x ? 0  =  dec 0
+x ? y  =  x
+
+x ? 0  =  dec 0
+x ? y  =  y
+
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  dec x
+
+0 ? x  =  x
+x ? y  =  dec y
+
+0 ? x  =  x
+x ? y  =  dec 0
+
+0 ? x  =  0
+x ? y  =  dec x
+
+0 ? x  =  0
+x ? y  =  dec y
+
+0 ? x  =  0
+x ? y  =  dec 0
+
+0 ? x  =  dec x
+x ? y  =  x
+
+0 ? x  =  dec x
+x ? y  =  y
+
+0 ? x  =  dec x
+x ? y  =  0
+
+0 ? x  =  dec 0
+x ? y  =  x
+
+0 ? x  =  dec 0
+x ? y  =  y
+
+0 ? x  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y
+
+x ? y  =  dec x + y
+
+x ? y  =  dec y + x
+
+x ? y  =  dec 0 + x
+
+x ? y  =  dec 0 + y
+
+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 ? 0  =  x
+x ? y  =  x + x
+
+x ? 0  =  x
+x ? y  =  x + y
+
+x ? 0  =  x
+x ? y  =  y + x
+
+x ? 0  =  x
+x ? y  =  y + y
+
+x ? 0  =  0
+x ? y  =  x + x
+
+x ? 0  =  0
+x ? y  =  x + y
+
+x ? 0  =  0
+x ? y  =  y + x
+
+x ? 0  =  0
+x ? y  =  y + y
+
+x ? 0  =  dec x
+x ? y  =  dec y
+
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+x ? 0  =  dec 0
+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
+
+0 ? x  =  x
+x ? y  =  x + x
+
+0 ? x  =  x
+x ? y  =  x + y
+
+0 ? x  =  x
+x ? y  =  y + x
+
+0 ? x  =  x
+x ? y  =  y + y
+
+0 ? x  =  0
+x ? y  =  x + x
+
+0 ? x  =  0
+x ? y  =  x + y
+
+0 ? x  =  0
+x ? y  =  y + x
+
+0 ? x  =  0
+x ? y  =  y + y
+
+0 ? x  =  dec x
+x ? y  =  dec y
+
+0 ? x  =  dec x
+x ? y  =  dec 0
+
+0 ? x  =  dec 0
+x ? y  =  dec x
+
+0 ? x  =  dec 0
+x ? y  =  dec y
+
+0 ? x  =  x + x
+x ? y  =  x
+
+0 ? x  =  x + x
+x ? y  =  y
+
+0 ? x  =  x + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  0
+
+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  =  x
+x ? y  =  0 ? dec x
+
+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 x ? 0
+
+x ? 0  =  x
+x ? y  =  dec y ? x
+
+x ? 0  =  x
+x ? y  =  dec y ? y
+
+x ? 0  =  x
+x ? y  =  dec y ? 0
+
+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  =  0
+x ? y  =  0 ? dec x
+
+x ? 0  =  0
+x ? y  =  0 ? dec y
+
+x ? 0  =  0
+x ? y  =  dec x ? x
+
+x ? 0  =  0
+x ? y  =  dec x ? y
+
+x ? 0  =  0
+x ? y  =  dec x ? 0
+
+x ? 0  =  0
+x ? y  =  dec y ? x
+
+x ? 0  =  0
+x ? y  =  dec y ? y
+
+x ? 0  =  0
+x ? y  =  dec y ? 0
+
+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  =  x
+x ? y  =  0 ? dec x
+
+0 ? x  =  x
+x ? y  =  0 ? 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
+
+0 ? x  =  x
+x ? y  =  dec y ? y
+
+0 ? x  =  x
+x ? y  =  dec y ? 0
+
+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  =  0
+x ? y  =  0 ? dec x
+
+0 ? x  =  0
+x ? y  =  0 ? 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
+
+0 ? x  =  0
+x ? y  =  dec y ? x
+
+0 ? x  =  0
+x ? y  =  dec y ? y
+
+0 ? x  =  0
+x ? y  =  dec y ? 0
+
+x ? y  =  x + (x + x)
+
+x ? y  =  x + (x + y)
+
+x ? y  =  x + (y + x)
+
+x ? y  =  x + (y + y)
+
+x ? y  =  y + (x + x)
+
+x ? y  =  y + (x + y)
+
+x ? y  =  y + (y + x)
+
+x ? y  =  y + (y + y)
+
+x ? y  =  dec x + dec x
+
+x ? y  =  dec x + dec y
+
+x ? y  =  dec x + dec 0
+
+x ? y  =  dec y + dec x
+
+x ? y  =  dec y + dec y
+
+x ? y  =  dec y + dec 0
+
+x ? y  =  dec 0 + dec x
+
+x ? y  =  dec 0 + dec y
+
+x ? y  =  dec 0 + dec 0
+
+x ? 0  =  x
+x ? y  =  dec x + y
+
+x ? 0  =  x
+x ? y  =  dec y + x
+
+x ? 0  =  x
+x ? y  =  dec 0 + x
+
+x ? 0  =  x
+x ? y  =  dec 0 + y
+
+x ? 0  =  x
+x ? y  =  x + dec x
+
+x ? 0  =  x
+x ? y  =  x + dec y
+
+x ? 0  =  x
+x ? y  =  x + dec 0
+
+x ? 0  =  x
+x ? y  =  y + dec x
+
+x ? 0  =  x
+x ? y  =  y + dec y
+
+x ? 0  =  x
+x ? y  =  y + dec 0
+
+x ? 0  =  0
+x ? y  =  dec x + y
+
+x ? 0  =  0
+x ? y  =  dec y + x
+
+x ? 0  =  0
+x ? y  =  dec 0 + x
+
+x ? 0  =  0
+x ? y  =  dec 0 + y
+
+x ? 0  =  0
+x ? y  =  x + dec x
+
+x ? 0  =  0
+x ? y  =  x + dec y
+
+x ? 0  =  0
+x ? y  =  x + dec 0
+
+x ? 0  =  0
+x ? y  =  y + dec x
+
+x ? 0  =  0
+x ? y  =  y + dec y
+
+x ? 0  =  0
+x ? y  =  y + dec 0
+
+x ? 0  =  dec x
+x ? y  =  x + x
+
+x ? 0  =  dec x
+x ? y  =  x + y
+
+x ? 0  =  dec x
+x ? y  =  y + x
+
+x ? 0  =  dec x
+x ? y  =  y + y
+
+x ? 0  =  dec 0
+x ? y  =  x + x
+
+x ? 0  =  dec 0
+x ? y  =  x + y
+
+x ? 0  =  dec 0
+x ? y  =  y + x
+
+x ? 0  =  dec 0
+x ? y  =  y + y
+
+x ? 0  =  x + x
+x ? y  =  dec x
+
+x ? 0  =  x + x
+x ? y  =  dec y
+
+x ? 0  =  x + x
+x ? y  =  dec 0
+
+x ? 0  =  dec 0 + x
+x ? y  =  x
+
+x ? 0  =  dec 0 + x
+x ? y  =  y
+
+x ? 0  =  dec 0 + 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
+
+x ? 0  =  x + dec 0
+x ? y  =  x
+
+x ? 0  =  x + dec 0
+x ? y  =  y
+
+x ? 0  =  x + dec 0
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  dec x + y
+
+0 ? x  =  x
+x ? y  =  dec y + x
+
+0 ? x  =  x
+x ? y  =  dec 0 + x
+
+0 ? x  =  x
+x ? y  =  dec 0 + y
+
+0 ? x  =  x
+x ? y  =  x + dec x
+
+0 ? x  =  x
+x ? y  =  x + dec y
+
+0 ? x  =  x
+x ? y  =  x + dec 0
+
+0 ? x  =  x
+x ? y  =  y + dec x
+
+0 ? x  =  x
+x ? y  =  y + dec y
+
+0 ? x  =  x
+x ? y  =  y + dec 0
+
+0 ? x  =  0
+x ? y  =  dec x + y
+
+0 ? x  =  0
+x ? y  =  dec y + x
+
+0 ? x  =  0
+x ? y  =  dec 0 + x
+
+0 ? x  =  0
+x ? y  =  dec 0 + y
+
+0 ? x  =  0
+x ? y  =  x + dec x
+
+0 ? x  =  0
+x ? y  =  x + dec y
+
+0 ? x  =  0
+x ? y  =  x + dec 0
+
+0 ? x  =  0
+x ? y  =  y + dec x
+
+0 ? x  =  0
+x ? y  =  y + dec y
+
+0 ? x  =  0
+x ? y  =  y + dec 0
+
+0 ? x  =  dec x
+x ? y  =  x + x
+
+0 ? x  =  dec x
+x ? y  =  x + y
+
+0 ? x  =  dec x
+x ? y  =  y + x
+
+0 ? x  =  dec x
+x ? y  =  y + y
+
+0 ? x  =  dec 0
+x ? y  =  x + x
+
+0 ? x  =  dec 0
+x ? y  =  x + y
+
+0 ? x  =  dec 0
+x ? y  =  y + x
+
+0 ? x  =  dec 0
+x ? y  =  y + y
+
+0 ? x  =  x + x
+x ? y  =  dec x
+
+0 ? x  =  x + x
+x ? y  =  dec y
+
+0 ? x  =  x + x
+x ? y  =  dec 0
+
+0 ? x  =  dec 0 + x
+x ? y  =  x
+
+0 ? x  =  dec 0 + x
+x ? y  =  y
+
+0 ? x  =  dec 0 + 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 + dec 0
+x ? y  =  x
+
+0 ? x  =  x + dec 0
+x ? y  =  y
+
+0 ? x  =  x + dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  0
+
+x ? 0  =  x
+x ? y  =  dec x ? dec x
+
+x ? 0  =  x
+x ? y  =  dec x ? dec y
+
+x ? 0  =  x
+x ? y  =  dec x ? dec 0
+
+x ? 0  =  x
+x ? y  =  dec y ? dec x
+
+x ? 0  =  x
+x ? y  =  dec y ? dec y
+
+x ? 0  =  x
+x ? y  =  dec y ? dec 0
+
+x ? 0  =  x
+x ? y  =  dec 0 ? dec x
+
+x ? 0  =  x
+x ? y  =  dec 0 ? 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 x ? dec 0
+
+x ? 0  =  0
+x ? y  =  dec y ? dec x
+
+x ? 0  =  0
+x ? y  =  dec y ? dec y
+
+x ? 0  =  0
+x ? y  =  dec y ? dec 0
+
+x ? 0  =  0
+x ? y  =  dec 0 ? dec x
+
+x ? 0  =  0
+x ? y  =  dec 0 ? 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 x ? dec 0
+
+0 ? x  =  x
+x ? y  =  dec y ? dec x
+
+0 ? x  =  x
+x ? y  =  dec y ? dec y
+
+0 ? x  =  x
+x ? y  =  dec y ? dec 0
+
+0 ? x  =  x
+x ? y  =  dec 0 ? dec x
+
+0 ? x  =  x
+x ? y  =  dec 0 ? 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 x ? dec 0
+
+0 ? x  =  0
+x ? y  =  dec y ? dec x
+
+0 ? x  =  0
+x ? y  =  dec y ? dec y
+
+0 ? x  =  0
+x ? y  =  dec y ? dec 0
+
+0 ? x  =  0
+x ? y  =  dec 0 ? dec x
+
+0 ? x  =  0
+x ? y  =  dec 0 ? 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 (0 ? dec x)
+
+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 x ? 0)
+
+x ? 0  =  x
+x ? y  =  dec (dec y ? x)
+
+x ? 0  =  x
+x ? y  =  dec (dec y ? y)
+
+x ? 0  =  x
+x ? y  =  dec (dec y ? 0)
+
+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 x)
+
+x ? 0  =  0
+x ? y  =  dec (y ? dec y)
+
+x ? 0  =  0
+x ? y  =  dec (0 ? dec x)
+
+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 x ? 0)
+
+x ? 0  =  0
+x ? y  =  dec (dec y ? x)
+
+x ? 0  =  0
+x ? y  =  dec (dec y ? y)
+
+x ? 0  =  0
+x ? y  =  dec (dec y ? 0)
+
+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  =  dec x
+x ? y  =  0 ? dec x
+
+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 x ? 0
+
+x ? 0  =  dec x
+x ? y  =  dec y ? x
+
+x ? 0  =  dec x
+x ? y  =  dec y ? y
+
+x ? 0  =  dec x
+x ? y  =  dec y ? 0
+
+x ? 0  =  dec 0
+x ? y  =  x ? dec x
+
+x ? 0  =  dec 0
+x ? y  =  x ? dec y
+
+x ? 0  =  dec 0
+x ? y  =  y ? dec x
+
+x ? 0  =  dec 0
+x ? y  =  y ? dec y
+
+x ? 0  =  dec 0
+x ? y  =  0 ? dec x
+
+x ? 0  =  dec 0
+x ? y  =  0 ? dec y
+
+x ? 0  =  dec 0
+x ? y  =  dec x ? x
+
+x ? 0  =  dec 0
+x ? y  =  dec x ? y
+
+x ? 0  =  dec 0
+x ? y  =  dec x ? 0
+
+x ? 0  =  dec 0
+x ? y  =  dec y ? x
+
+x ? 0  =  dec 0
+x ? y  =  dec y ? y
+
+x ? 0  =  dec 0
+x ? y  =  dec y ? 0
+
+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 (0 ? dec x)
+
+0 ? x  =  x
+x ? y  =  dec (0 ? 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  =  x
+x ? y  =  dec (dec y ? y)
+
+0 ? x  =  x
+x ? y  =  dec (dec y ? 0)
+
+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 x)
+
+0 ? x  =  0
+x ? y  =  dec (y ? dec y)
+
+0 ? x  =  0
+x ? y  =  dec (0 ? dec x)
+
+0 ? x  =  0
+x ? y  =  dec (0 ? 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  =  0
+x ? y  =  dec (dec y ? y)
+
+0 ? x  =  0
+x ? y  =  dec (dec y ? 0)
+
+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  =  dec x
+x ? y  =  0 ? dec x
+
+0 ? x  =  dec x
+x ? y  =  0 ? 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  =  dec x
+x ? y  =  dec y ? y
+
+0 ? x  =  dec x
+x ? y  =  dec y ? 0
+
+0 ? x  =  dec 0
+x ? y  =  x ? dec x
+
+0 ? x  =  dec 0
+x ? y  =  x ? dec y
+
+0 ? x  =  dec 0
+x ? y  =  y ? dec x
+
+0 ? x  =  dec 0
+x ? y  =  y ? dec y
+
+0 ? x  =  dec 0
+x ? y  =  0 ? dec x
+
+0 ? x  =  dec 0
+x ? y  =  0 ? dec y
+
+0 ? x  =  dec 0
+x ? y  =  dec x ? x
+
+0 ? x  =  dec 0
+x ? y  =  dec x ? y
+
+0 ? x  =  dec 0
+x ? y  =  dec x ? 0
+
+0 ? x  =  dec 0
+x ? y  =  dec y ? x
+
+0 ? x  =  dec 0
+x ? y  =  dec y ? y
+
+0 ? x  =  dec 0
+x ? y  =  dec y ? 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x ? dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x ? dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y ? dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y ? dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  0 ? dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  0 ? dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x ? x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x ? y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x ? 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y ? x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y ? y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y ? 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x ? x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x ? 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x ? x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x ? 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x ? x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x ? 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x ? dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x ? dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y ? dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y ? dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  0 ? dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  0 ? dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x ? x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x ? y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x ? 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y ? x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y ? y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y ? 0
+
+0 ? 0  =  0
+0 ? x  =  x ? dec x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0 ? dec x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x ? dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0 ? dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x ? dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0 ? dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x ? dec x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0 ? dec x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x ? dec x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0 ? dec x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x ? dec x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0 ? dec x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x ? dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x ? dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y ? dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y ? dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  0 ? dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  0 ? dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x ? x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x ? y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x ? 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y ? x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y ? y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y ? 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x ? x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x ? 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x ? x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x ? 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x ? x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x ? 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x ? dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x ? dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y ? dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y ? dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  0 ? dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  0 ? dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x ? x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x ? y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x ? 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y ? x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y ? y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y ? 0
+
+x ? y  =  x + (dec x + y)
+
+x ? y  =  x + (dec y + x)
+
+x ? y  =  x + (dec 0 + x)
+
+x ? y  =  x + (dec 0 + y)
+
+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 x + y)
+
+x ? y  =  y + (dec y + x)
+
+x ? y  =  y + (dec 0 + x)
+
+x ? y  =  y + (dec 0 + y)
+
+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 + (y + y)
+
+x ? y  =  dec y + (x + x)
+
+x ? y  =  dec 0 + (x + x)
+
+x ? y  =  dec 0 + (x + y)
+
+x ? y  =  dec 0 + (y + x)
+
+x ? y  =  dec 0 + (y + y)
+
+x ? 0  =  x
+x ? y  =  x + (x + x)
+
+x ? 0  =  x
+x ? y  =  x + (x + y)
+
+x ? 0  =  x
+x ? y  =  x + (y + x)
+
+x ? 0  =  x
+x ? y  =  x + (y + y)
+
+x ? 0  =  x
+x ? y  =  y + (x + x)
+
+x ? 0  =  x
+x ? y  =  y + (x + y)
+
+x ? 0  =  x
+x ? y  =  y + (y + x)
+
+x ? 0  =  x
+x ? y  =  y + (y + 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 x + dec 0
+
+x ? 0  =  x
+x ? y  =  dec y + dec x
+
+x ? 0  =  x
+x ? y  =  dec y + dec y
+
+x ? 0  =  x
+x ? y  =  dec y + dec 0
+
+x ? 0  =  x
+x ? y  =  dec 0 + dec x
+
+x ? 0  =  x
+x ? y  =  dec 0 + dec y
+
+x ? 0  =  x
+x ? y  =  dec 0 + dec 0
+
+x ? 0  =  0
+x ? y  =  x + (x + x)
+
+x ? 0  =  0
+x ? y  =  x + (x + y)
+
+x ? 0  =  0
+x ? y  =  x + (y + x)
+
+x ? 0  =  0
+x ? y  =  x + (y + y)
+
+x ? 0  =  0
+x ? y  =  y + (x + x)
+
+x ? 0  =  0
+x ? y  =  y + (x + y)
+
+x ? 0  =  0
+x ? y  =  y + (y + x)
+
+x ? 0  =  0
+x ? y  =  y + (y + 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 x + dec 0
+
+x ? 0  =  0
+x ? y  =  dec y + dec x
+
+x ? 0  =  0
+x ? y  =  dec y + dec y
+
+x ? 0  =  0
+x ? y  =  dec y + dec 0
+
+x ? 0  =  0
+x ? y  =  dec 0 + dec x
+
+x ? 0  =  0
+x ? y  =  dec 0 + dec y
+
+x ? 0  =  0
+x ? y  =  dec 0 + dec 0
+
+x ? 0  =  dec x
+x ? y  =  dec x + y
+
+x ? 0  =  dec x
+x ? y  =  dec y + x
+
+x ? 0  =  dec x
+x ? y  =  dec 0 + x
+
+x ? 0  =  dec x
+x ? y  =  dec 0 + 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  =  x + dec 0
+
+x ? 0  =  dec x
+x ? y  =  y + dec x
+
+x ? 0  =  dec x
+x ? y  =  y + dec y
+
+x ? 0  =  dec x
+x ? y  =  y + dec 0
+
+x ? 0  =  dec 0
+x ? y  =  dec x + y
+
+x ? 0  =  dec 0
+x ? y  =  dec y + x
+
+x ? 0  =  dec 0
+x ? y  =  dec 0 + x
+
+x ? 0  =  dec 0
+x ? y  =  dec 0 + y
+
+x ? 0  =  dec 0
+x ? y  =  x + dec x
+
+x ? 0  =  dec 0
+x ? y  =  x + dec y
+
+x ? 0  =  dec 0
+x ? y  =  x + dec 0
+
+x ? 0  =  dec 0
+x ? y  =  y + dec x
+
+x ? 0  =  dec 0
+x ? y  =  y + dec y
+
+x ? 0  =  dec 0
+x ? y  =  y + dec 0
+
+x ? 0  =  x + x
+x ? y  =  x + y
+
+x ? 0  =  x + x
+x ? y  =  y + x
+
+x ? 0  =  x + x
+x ? y  =  y + y
+
+x ? 0  =  dec 0 + x
+x ? y  =  dec x
+
+x ? 0  =  dec 0 + x
+x ? y  =  dec y
+
+x ? 0  =  dec 0 + x
+x ? y  =  dec 0
+
+x ? 0  =  x + dec x
+x ? y  =  dec x
+
+x ? 0  =  x + dec x
+x ? y  =  dec y
+
+x ? 0  =  x + dec x
+x ? y  =  dec 0
+
+x ? 0  =  x + dec 0
+x ? y  =  dec x
+
+x ? 0  =  x + dec 0
+x ? y  =  dec y
+
+x ? 0  =  x + dec 0
+x ? y  =  dec 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  =  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
+
+x ? 0  =  dec x + dec 0
+x ? y  =  x
+
+x ? 0  =  dec x + dec 0
+x ? y  =  y
+
+x ? 0  =  dec x + dec 0
+x ? y  =  0
+
+x ? 0  =  dec 0 + dec x
+x ? y  =  x
+
+x ? 0  =  dec 0 + dec x
+x ? y  =  y
+
+x ? 0  =  dec 0 + dec x
+x ? y  =  0
+
+x ? 0  =  dec 0 + dec 0
+x ? y  =  x
+
+x ? 0  =  dec 0 + dec 0
+x ? y  =  y
+
+x ? 0  =  dec 0 + dec 0
+x ? y  =  0
+
+0 ? x  =  x
+x ? y  =  x + (x + x)
+
+0 ? x  =  x
+x ? y  =  x + (x + y)
+
+0 ? x  =  x
+x ? y  =  x + (y + x)
+
+0 ? x  =  x
+x ? y  =  x + (y + y)
+
+0 ? x  =  x
+x ? y  =  y + (x + x)
+
+0 ? x  =  x
+x ? y  =  y + (x + y)
+
+0 ? x  =  x
+x ? y  =  y + (y + x)
+
+0 ? x  =  x
+x ? y  =  y + (y + 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 x + dec 0
+
+0 ? x  =  x
+x ? y  =  dec y + dec x
+
+0 ? x  =  x
+x ? y  =  dec y + dec y
+
+0 ? x  =  x
+x ? y  =  dec y + dec 0
+
+0 ? x  =  x
+x ? y  =  dec 0 + dec x
+
+0 ? x  =  x
+x ? y  =  dec 0 + dec y
+
+0 ? x  =  x
+x ? y  =  dec 0 + dec 0
+
+0 ? x  =  0
+x ? y  =  x + (x + x)
+
+0 ? x  =  0
+x ? y  =  x + (x + y)
+
+0 ? x  =  0
+x ? y  =  x + (y + x)
+
+0 ? x  =  0
+x ? y  =  x + (y + y)
+
+0 ? x  =  0
+x ? y  =  y + (x + x)
+
+0 ? x  =  0
+x ? y  =  y + (x + y)
+
+0 ? x  =  0
+x ? y  =  y + (y + x)
+
+0 ? x  =  0
+x ? y  =  y + (y + 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 x + dec 0
+
+0 ? x  =  0
+x ? y  =  dec y + dec x
+
+0 ? x  =  0
+x ? y  =  dec y + dec y
+
+0 ? x  =  0
+x ? y  =  dec y + dec 0
+
+0 ? x  =  0
+x ? y  =  dec 0 + dec x
+
+0 ? x  =  0
+x ? y  =  dec 0 + dec y
+
+0 ? x  =  0
+x ? y  =  dec 0 + dec 0
+
+0 ? x  =  dec x
+x ? y  =  dec x + y
+
+0 ? x  =  dec x
+x ? y  =  dec y + x
+
+0 ? x  =  dec x
+x ? y  =  dec 0 + x
+
+0 ? x  =  dec x
+x ? y  =  dec 0 + 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  =  x + dec 0
+
+0 ? x  =  dec x
+x ? y  =  y + dec x
+
+0 ? x  =  dec x
+x ? y  =  y + dec y
+
+0 ? x  =  dec x
+x ? y  =  y + dec 0
+
+0 ? x  =  dec 0
+x ? y  =  dec x + y
+
+0 ? x  =  dec 0
+x ? y  =  dec y + x
+
+0 ? x  =  dec 0
+x ? y  =  dec 0 + x
+
+0 ? x  =  dec 0
+x ? y  =  dec 0 + y
+
+0 ? x  =  dec 0
+x ? y  =  x + dec x
+
+0 ? x  =  dec 0
+x ? y  =  x + dec y
+
+0 ? x  =  dec 0
+x ? y  =  x + dec 0
+
+0 ? x  =  dec 0
+x ? y  =  y + dec x
+
+0 ? x  =  dec 0
+x ? y  =  y + dec y
+
+0 ? x  =  dec 0
+x ? y  =  y + dec 0
+
+0 ? x  =  x + x
+x ? y  =  x + y
+
+0 ? x  =  x + x
+x ? y  =  y + x
+
+0 ? x  =  x + x
+x ? y  =  y + y
+
+0 ? x  =  dec 0 + x
+x ? y  =  dec x
+
+0 ? x  =  dec 0 + x
+x ? y  =  dec y
+
+0 ? x  =  dec 0 + x
+x ? y  =  dec 0
+
+0 ? x  =  x + dec x
+x ? y  =  dec x
+
+0 ? x  =  x + dec x
+x ? y  =  dec y
+
+0 ? x  =  x + dec x
+x ? y  =  dec 0
+
+0 ? x  =  x + dec 0
+x ? y  =  dec x
+
+0 ? x  =  x + dec 0
+x ? y  =  dec y
+
+0 ? x  =  x + dec 0
+x ? y  =  dec 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  =  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  =  dec x + dec 0
+x ? y  =  x
+
+0 ? x  =  dec x + dec 0
+x ? y  =  y
+
+0 ? x  =  dec x + dec 0
+x ? y  =  0
+
+0 ? x  =  dec 0 + dec x
+x ? y  =  x
+
+0 ? x  =  dec 0 + dec x
+x ? y  =  y
+
+0 ? x  =  dec 0 + dec x
+x ? y  =  0
+
+0 ? x  =  dec 0 + dec 0
+x ? y  =  x
+
+0 ? x  =  dec 0 + dec 0
+x ? y  =  y
+
+0 ? x  =  dec 0 + dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec x + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec y + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec 0 + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  dec 0 + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec x + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec y + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec 0 + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  dec 0 + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0 + x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0 + x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  dec 0 + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x
+x ? 0  =  x + dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec x + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec y + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec 0 + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  dec 0 + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec x + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec y + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec 0 + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  dec 0 + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0 + x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0 + x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  dec 0 + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  0
+x ? 0  =  x + dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec x
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  y + x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  y + y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + x
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0 + x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0 + x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0 + x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  dec 0 + x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  dec 0 + x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  dec 0 + x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + dec x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + dec x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + dec x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + dec x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + dec x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + dec x
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + dec 0
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + dec 0
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + dec 0
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  0
+0 ? x  =  x + dec 0
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  0
+0 ? x  =  x + dec 0
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  0
+0 ? x  =  x + dec 0
+x ? 0  =  0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  x + y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  0
+x ? y  =  y + y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  dec 0
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  x + y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x
+x ? y  =  y + y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  x + y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  0
+x ? y  =  y + y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec x
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  dec 0
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  0
+x ? 0  =  x + x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec x
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  x
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  dec x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  dec y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  0
+x ? y  =  dec 0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  dec x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  dec 0
+x ? 0  =  dec 0
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x + x
+x ? 0  =  x
+x ? y  =  0
+
+0 ? 0  =  dec 0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  x
+
+0 ? 0  =  dec 0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  y
+
+0 ? 0  =  dec 0
+0 ? x  =  x + x
+x ? 0  =  0
+x ? y  =  0
+
+
+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,8,15,66,152,362,1400,2084,11820] 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  =  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
+
+[] ?? []  =  []
+[] ?? (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
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x: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)  =  xs ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x: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  =  xs
+(x:xs) ?? ys  =  [] ?? xs
+
+[] ?? 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  =  []
+(x:xs) ?? ys  =  [] ?? 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) ?? []  =  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)  =  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
+(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
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [] ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [] ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  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
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (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)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ?? []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [] ?? xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [] ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [] ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  [] ?? xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  [] ?? xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ?? xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ?? []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  [] ?? xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ?? []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [] ?? xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y: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)
+
+[] ?? []  =  []
+[] ?? (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) ?? (y:ys)  =  x:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x: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)  =  ys
+
+[] ?? []  =  []
+[] ?? (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)  =  ys
+
+[] ?? []  =  []
+[] ?? (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)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  x:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [x]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  y:ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  [y]
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys ++ ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  x:xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  [x]
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  []
+(x:xs) ?? []  =  xs ++ xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (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:xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  x:xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  [x]
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  xs
+(x:xs) ?? (y:ys)  =  []
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  xs
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  ys
+
+[] ?? []  =  []
+[] ?? (x:xs)  =  xs ++ xs
+(x:xs) ?? []  =  []
+(x:xs) ?? (y:ys)  =  []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:xs) ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:xs) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:xs) ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:ys) ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x:ys) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (x: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
+xs ?? (x:ys)  =  (xs ++ xs) ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (xs ++ xs) ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (xs ++ ys) ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (xs ++ ys) ?? ys
+
+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 ++ xs) ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (ys ++ ys) ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  (ys ++ ys) ?? 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:xs) ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (x:ys) ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (x:ys) ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (x: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 ?? []  =  []
+xs ?? (x:ys)  =  (xs ++ xs) ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (xs ++ xs) ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (xs ++ ys) ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (xs ++ ys) ?? ys
+
+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 ++ xs) ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (ys ++ ys) ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  (ys ++ ys) ?? ys
+
+xs ?? []  =  []
+xs ?? (x: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  =  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  =  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  =  []
+(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:ys)  =  x:xs ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:xs ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x:ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  x: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 ++ xs ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  xs ++ ys ?? ys
+
+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)  =  ys ++ xs ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ xs ?? ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ xs ?? []
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ ys ?? xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ++ ys ?? ys
+
+xs ?? []  =  xs
+xs ?? (x: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)  =  xs ?? [] ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? xs ++ xs
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? ys ++ xs
+
+xs ?? []  =  xs
+xs ?? (x: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)  =  xs ?? [] ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? xs ++ ys
+
+xs ?? []  =  xs
+xs ?? (x:ys)  =  ys ?? ys ++ ys
+
+xs ?? []  =  xs
+xs ?? (x: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:xs ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x:ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  x: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 ++ xs ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  xs ++ 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 ++ xs ?? []
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ ys ?? xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ++ ys ?? ys
+
+xs ?? []  =  []
+xs ?? (x: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)  =  xs ?? [] ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? xs ++ xs
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? ys ++ xs
+
+xs ?? []  =  []
+xs ?? (x: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)  =  xs ?? [] ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? xs ++ ys
+
+xs ?? []  =  []
+xs ?? (x:ys)  =  ys ?? ys ++ ys
+
+xs ?? []  =  []
+xs ?? (x: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)  =  xs ?? []
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys ?? xs
+
+xs ?? []  =  xs ++ xs
+xs ?? (x:ys)  =  ys ?? ys
+
+xs ?? []  =  xs ++ xs
+xs ?? (x: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  =  [x,] ?? 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 ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ ys ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  xs ++ [] ?? 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 ?? ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ++ ys ?? []
+
+[] ?? xs  =  xs
+(x:xs) ?? 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 ?? ys ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? [] ++ xs
+
+[] ?? xs  =  xs
+(x:xs) ?? 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 ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? ys  =  ys ?? [] ++ ys
+
+[] ?? xs  =  xs
+(x:xs) ?? 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 ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  x:ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  [x,] ?? 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 ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  xs ++ [] ?? 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 ?? ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ++ ys ?? []
+
+[] ?? xs  =  []
+(x:xs) ?? 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 ?? ys ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ?? [] ++ xs
+
+[] ?? xs  =  []
+(x:xs) ?? 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 ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? ys  =  ys ?? [] ++ ys
+
+[] ?? xs  =  []
+(x:xs) ?? 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 ?? ys
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  ys ?? []
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  [] ?? xs
+
+[] ?? xs  =  xs ++ xs
+(x:xs) ?? ys  =  [] ?? 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
+(x:xs) ?? ys  =  ys ++ ys
+
+[] ?? xs  =  xs ++ (xs ++ xs)
+(x:xs) ?? ys  =  xs
+
+[] ?? xs  =  xs ++ (xs ++ xs)
+(x:xs) ?? ys  =  ys
+
+[] ?? xs  =  xs ++ (xs ++ xs)
+(x:xs) ?? 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,4,8,4,32,36,112,264] direct candidates, 0 duplicates
+  [4,14,30,8,4,32,36,112,264] 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  =  q && p
+
+p &| q  =  p || q
+
+p &| q  =  q || p
+
+p &| q  =  not p && q
+
+p &| q  =  not q && p
+
+p &| q  =  not p || q
+
+p &| q  =  not q || p
+
+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 q && not p
+
+p &| q  =  not p || not q
+
+p &| q  =  not q || not p
+
+p &| q  =  p && (not p && q)
+
+p &| q  =  p && (not p || q)
+
+p &| q  =  p && (q && not p)
+
+p &| q  =  p && (q || not p)
+
+p &| q  =  q && (not q && p)
+
+p &| q  =  q && (not q || p)
+
+p &| q  =  q && (p && not q)
+
+p &| q  =  q && (p || not q)
+
+p &| q  =  p || not p && q
+
+p &| q  =  p || (not p || q)
+
+p &| q  =  p || q && not p
+
+p &| q  =  p || (q || not p)
+
+p &| q  =  q || not q && p
+
+p &| q  =  q || (not q || p)
+
+p &| q  =  q || p && not q
+
+p &| q  =  q || (p || not q)
+
+p &| q  =  not p && (p || q)
+
+p &| q  =  not p && (q || p)
+
+p &| q  =  not q && (p || q)
+
+p &| q  =  not q && (q || p)
+
+p &| q  =  not p || p && q
+
+p &| q  =  not p || q && p
+
+p &| q  =  not q || p && q
+
+p &| q  =  not q || q && p
+
+p &| q  =  (p || q) && not p
+
+p &| q  =  (p || q) && not q
+
+p &| q  =  (q || p) && not p
+
+p &| q  =  (q || p) && not q
+
+p &| q  =  p && q || not p
+
+p &| q  =  p && q || not q
+
+p &| q  =  q && p || not p
+
+p &| q  =  q && p || not q
 
 
 pattern candidates:
diff --git a/bench/gps.hs b/bench/gps.hs
new file mode 100644
--- /dev/null
+++ b/bench/gps.hs
@@ -0,0 +1,337 @@
+-- gps.hs: General Program Synthesis Benchmark Suite
+--
+-- Copyright (C) 2021 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+import System.Environment (getArgs)
+
+import Data.Char (isLetter)                      -- GPS bench  #5
+import Data.Char (isSpace)                       -- GPS bench  #7
+import Data.Ratio ((%), numerator, denominator)  -- GPS bench #10
+
+
+gps1p :: Int -> Float -> Float
+gps1p 0 1.0  =  1.0
+gps1p 1 0.0  =  1.0
+gps1p 1 1.0  =  2.0
+gps1p 1 1.5  =  2.5
+
+gps1g :: Int -> Float -> Float
+gps1g x f  =  fromIntegral x + f
+
+gps1c :: IO ()
+gps1c  =  conjure "gps1" gps1p
+  [ prim "+" ((+) :: Float -> Float -> Float)
+  , prim "fromIntegral" (fromIntegral :: Int -> Float)
+  ]
+
+
+gps2p :: Int -> Maybe String
+gps2p    0  =  Just "small"
+gps2p  500  =  Just "small"
+gps2p 1000  =  Nothing
+gps2p 1500  =  Nothing
+gps2p 2000  =  Just "large"
+gps2p 2500  =  Just "large"
+
+gps2g :: Int -> Maybe String
+gps2g n
+  | n <  1000  =  Just "small"
+  | 2000 <= n  =  Just "large"
+  | otherwise  =  Nothing
+
+gps2c :: IO ()
+gps2c  =  conjureWith args{maxTests=5040, maxSize=30} "gps2" gps2p
+  [ pr "small"
+  , pr "large"
+  , pr (1000 :: Int)
+  , pr (2000 :: Int)
+  , prim "Just" (Just :: String -> Maybe String)
+  , prim "Nothing" (Nothing :: Maybe String)
+  , prim "<=" ((<=) :: Int -> Int -> Bool)
+  , prim "<" ((<) :: Int -> Int -> Bool)
+  , prif (undefined :: Maybe String)
+  ]
+
+
+gps3p :: Int -> Int -> Int -> [Int]
+gps3p 0 9 1  =  [0,1,2,3,4,5,6,7,8]
+gps3p 2 9 2  =  [2,4,6,8]
+
+gps3g1 :: Int -> Int -> Int -> [Int]
+gps3g1 start end step  =  enumFromThenTo start (step+start) (end-1)
+
+gps3g2 :: Int -> Int -> Int -> [Int]
+gps3g2 start end step  =  if start < end
+                          then start : gps3g2 (start+step) end step
+                          else []
+
+gps3c :: IO ()
+gps3c  =  do
+  conjure "gps3" gps3p
+    [ pr (1 :: Int)
+    , prim "enumFromThenTo" ((\x y z -> take 720 $ enumFromThenTo x y z) :: Int -> Int -> Int -> [Int])
+    , prim "+" ((+) :: Int -> Int -> Int)
+    , prim "-" ((-) :: Int -> Int -> Int)
+    ]
+
+  -- not possible, no recursive descent
+  conjureWith args{maxSize=8} "gps3" gps3p
+    [ pr ([] :: [Int])
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "+" ((+) :: Int -> Int -> Int)
+    , prim "<" ((<) :: Int -> Int -> Bool)
+    , prif (undefined :: [Int])
+    ]
+
+
+gps4p :: String -> String -> String -> Bool
+gps4p "" "a" "aa"  =  True
+gps4p "aa" "a" ""  =  False
+gps4p "a" "aa" ""  =  False
+gps4p "a" "aa" "aaa"  =  True
+gps4p "a" "aaa" "aa"  =  False
+gps4p "aa" "a" "aaa"  =  False
+gps4p "aa" "aaa" "a"  =  False
+gps4p "aaa" "a" "aa"  =  False
+gps4p "aaa" "aa" "a"  =  False
+
+gps4g :: String -> String -> String -> Bool
+gps4g s1 s2 s3  =  length s1 < length s2 && length s2 < length s3
+
+gps4c :: IO ()
+gps4c  =  do
+  conjure "gps4" gps4p
+    [ prim "length" (length :: String -> Int)
+    , prim "<" ((<) :: Int -> Int -> Bool)
+    , prim "&&" (&&)
+    ]
+
+
+gps5p :: String -> String
+gps5p "a"  =  "aa"
+gps5p "b"  =  "bb"
+gps5p " "  =  " "
+gps5p "!"  =  "!!!"
+gps5p "aa"  =  "aaaa"
+
+gps5g :: String -> String
+gps5g []  =  []
+gps5g (c:cs)
+  | isLetter c  =  c:c:gps5g cs
+  | c == '!'    =  c:c:c:gps5g cs
+  | otherwise   =  c:gps5g cs
+
+gps5c :: IO ()
+gps5c  =  conjureWith args{maxSize=6} "gps5" gps5p -- can't find
+  [ pr ""
+  , prim ":" ((:) :: Char -> String -> String)
+  , pr '!'
+  , prim "==" ((==) :: Char -> Char -> Bool)
+  , prim "isLetter" (isLetter :: Char -> Bool)
+  , prif (undefined :: String -> String)
+  ]
+
+
+-- GPS Benchmark #6 -- Collatz/Hailstone numbers --
+
+gps6p :: Int -> Int
+gps6p 1  =  1
+gps6p 2  =  2
+gps6p 3  =  8
+gps6p 4  =  3
+gps6p 5  =  6
+gps6p 6  =  9
+gps6p 12  =  10
+gps6p 60  =  20
+gps6p 360  =  20
+
+gps6g :: Int -> Int
+gps6g  =  tnp1
+  where
+  tnp1 n | n <= 0  =  undefined
+  tnp1 1  =  1                          --  1
+  tnp1 n  =  1 + gps6g (if even n       --  7
+                        then n `div` 2  -- 10
+                        else 3*n + 1)   -- 15
+
+-- This one is out of reach performance wise:
+-- Speculate hangs with this background.
+-- Removing three or setting maxEqSize to 4 makes it unhang.
+-- But a size of 15 or 17 is simplyl out of our reach.
+gps6c :: IO ()
+gps6c  =  conjureWith args{maxSize=6,maxEquationSize=3} "gps6" gps6p
+  [ pr (1 :: Int)
+  , pr (2 :: Int)
+  , pr (3 :: Int)
+  , prim "+" ((+) :: Int -> Int -> Int)
+  , prim "*" ((*) :: Int -> Int -> Int)
+  , prim "`div`" (div :: Int -> Int -> Int)
+  , prim "even" (even :: Int -> Bool)
+  , prif (undefined :: Int)
+  ]
+
+
+-- GPS Benchmark #7 -- Replace Space with Newline (P 4.3)
+
+gps7p :: String -> (String, Int)
+gps7p "a"  =  ("a", 1)
+gps7p "aa"  =  ("aa", 2)
+gps7p "a a"  =  ("a\na", 2)
+gps7p "a\na"  =  ("a\na", 2)
+
+gps7g :: String -> (String, Int)
+gps7g s  =  (init $ unlines $ words s, length (filter (not . isSpace) s))
+
+gps7c :: IO ()
+gps7c  =  conjure "gps7" gps7p
+  [ prim "," ((,) :: String -> Int -> (String, Int))
+  , prim "init" (init :: String -> String)
+  , prim "unlines" unlines
+  , prim "words" words
+  , prim "length" (length :: String -> Int)
+  , prim "filter" (filter :: (Char -> Bool) -> String -> String)
+  , prim "not" not
+  , prim "." ((.) :: (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool) -- cheat?
+  , prim "isSpace" (isSpace :: Char -> Bool)
+  ]
+
+
+-- GPS Benchmark #8 -- String Differences
+
+gps8p :: String -> String -> [(Int, Char, Char)]
+gps8p "a" "a"  =  []
+gps8p "a" "b"  =  [(0,'a','b')]
+gps8p "aa" "ab"  =  [(1,'a','b')]
+gps8p "dealer" "dollar"  =  [(1,'e','o'), (2,'a','l'),(4,'e','a')]
+
+gps8g :: String -> String -> [(Int, Char, Char)]
+gps8g  =  diffs 0
+  where
+  diffs _ [] _  =  []
+  diffs _ _ []  =  []
+  diffs n (c:cs) (d:ds)  =  if c == d
+                            then diffs (n+1) cs ds
+                            else (n,c,d) : diffs (n+1) cs ds
+
+-- out of reach as Conjure cannot invent helper functions
+-- even if that would be solved,
+-- I conjecture it would be out-of-reach performance-wise.
+gps8c :: IO ()
+gps8c  =  conjure "gps8" gps8p
+  [
+  ]
+
+
+-- GPS Benchmark #9 -- Even Squares
+-- given an integer _n_, print all of the positive even perfect squares less
+-- than _n_ on separate lines.
+
+gps9p :: Int -> [Int]
+gps9p 10  =  [4]
+gps9p 100  =  [4,16,36,64]
+gps9p 1000  =  [4,16,36,64,100,144,196,256,324,400,484,576,676,784,900]
+
+-- non-optimal performance, but does the job
+-- gps9g :: Int -> [Int]
+-- gps9g n  =  [x*x | x <- [1..n], x*x < n, even (x*x)]
+gps9g :: Int -> [Int]
+gps9g n  =  filter (n >) (filter even (map sq [1..n]))
+  where
+  sq  =  (^2)
+
+gps9c :: IO ()
+gps9c  =  conjureWith args{maxTests=60} "gps9" gps9p
+  [ pr (1 :: Int)
+  , prim "map" (map :: (Int -> Int) -> [Int] -> [Int])
+  , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])
+  , prim ".." (enumFromTo :: Int -> Int -> [Int])
+  , prim ">" ((>) :: Int -> Int -> Bool)
+  , prim "even" (even :: Int -> Bool)
+  , prim "sq" ((^2) :: Int -> Int)  -- invented separately
+  ]
+
+
+-- GPS Benchmark #10 -- Wallis Pi
+-- (quarter pi approximation)
+-- 2   4   4   6   6   8   8
+-- - x - x - x - x - x - x - x ...
+-- 3   3   5   5   7   7   9
+
+gps10p :: Int -> Rational
+gps10p 1  =     2/3
+gps10p 2  =     8/9
+gps10p 3  =    32/45
+gps10p 4  =    64/75
+gps10p 5  =   128/175
+gps10p 6  =  1024/1225
+
+gps10g :: Int -> Rational
+gps10g n  =  product $ take n $ iterate wallisNext (2/3)
+
+wallisNextP :: Rational -> Rational
+wallisNextP q
+  | q == 2/3  =  4/3
+  | q == 4/3  =  4/5
+  | q == 4/5  =  6/5
+  | q == 6/5  =  6/7
+  | q == 6/7  =  8/7
+  | q == 8/7  =  8/9
+
+wallisNext :: Rational -> Rational
+wallisNext q  =  if n < d
+                 then (n+2) % d
+                 else n % (d+2)
+  where
+  n  =  numerator q
+  d  =  denominator q
+-- wallisNext (x % y)  =  (y + (y + 2)) % (x + (x + 2)) -- which simplifies to...
+-- wallisNext (x % y)  =  (x + x * y) % (x + x * x)     -- which simplifies to...
+-- wallisNext (x % y)  =  (y + 1) % (x + 1)             -- this correct version
+
+
+gps10c :: IO ()
+gps10c  =  do
+  conjureWith args{maxSize=14} "wallisNext" wallisNextP
+    [ pr (1 :: Integer)
+    , pr (2 :: Integer)
+    , prim "+" ((+) :: Integer -> Integer -> Integer)
+    , prim "*" ((*) :: Integer -> Integer -> Integer)
+    , prim "%" ((%) :: Integer -> Integer -> Rational)
+    , prim "<" ((<) :: Integer -> Integer -> Bool)
+--  , prim "numerator" (numerator :: Rational -> Integer)
+--  , prim "denominator" (denominator :: Rational -> Integer)
+    , prif (undefined :: Rational)
+    ]
+
+  conjure "gps10" gps10p
+    [ pr (2 :: Integer)
+    , pr (3 :: Integer)
+    , prim "%" ((%) :: Integer -> Integer -> Rational)
+--  , pr (2/3 :: Rational)
+    , prim "product"    (product :: [Rational] -> Rational)
+    , prim "take"       (take :: Int -> [Rational] -> [Rational])
+    , prim "iterate"    ((\f -> take 720 . iterate f) :: (Rational -> Rational) -> Rational -> [Rational])
+    , prim "wallisNext" wallisNext
+    ]
+
+main :: IO ()
+main  =  do
+  as <- getArgs
+  case as of
+    [] -> sequence_ gpss
+    (n:_) -> gpss !! (read n - 1)
+
+
+gpss :: [IO ()]
+gpss  =  [ gps1c
+         , gps2c
+         , gps3c
+         , gps4c
+         , gps5c
+         , gps6c
+         , gps7c
+         , gps8c
+         , gps9c
+         , gps10c
+         ]
diff --git a/bench/gps.out b/bench/gps.out
new file mode 100644
--- /dev/null
+++ b/bench/gps.out
@@ -0,0 +1,156 @@
+gps1 :: Int -> Float -> Float
+-- testing 4 combinations of argument values
+-- pruning with 1/2 rules
+-- looking through 1 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
+gps1 x y  =  fromIntegral x + y
+
+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 4 candidates of size 3
+-- looking through 6 candidates of size 4
+-- looking through 8 candidates of size 5
+-- looking through 12 candidates of size 6
+-- looking through 38 candidates of size 7
+-- looking through 48 candidates of size 8
+-- looking through 112 candidates of size 9
+-- looking through 144 candidates of size 10
+-- looking through 176 candidates of size 11
+-- looking through 704 candidates of size 12
+-- looking through 1856 candidates of size 13
+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 1536 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 26127 candidates of size 8
+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 18 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 108 candidates of size 7
+-- looking through 36 candidates of size 8
+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 30 candidates of size 10
+-- looking through 30 candidates of size 11
+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
+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 9 candidates of size 2
+-- looking through 30 candidates of size 3
+-- looking through 125 candidates of size 4
+-- looking through 415 candidates of size 5
+-- looking through 1602 candidates of size 6
+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 86 candidates of size 9
+-- looking through 193 candidates of size 10
+-- looking through 414 candidates of size 11
+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
+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 25 candidates of size 6
+-- looking through 35 candidates of size 7
+-- looking through 87 candidates of size 8
+-- looking through 150 candidates of size 9
+-- looking through 272 candidates of size 10
+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 118 candidates of size 6
+-- looking through 5 candidates of size 7
+-- looking through 825 candidates of size 8
+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
+gps10 x  =  product (take x (iterate wallisNext (2 % 3)))
+
diff --git a/bench/ill-hit.out b/bench/ill-hit.out
--- a/bench/ill-hit.out
+++ b/bench/ill-hit.out
@@ -2,44 +2,32 @@
 -- testing 4 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 15 candidates of size 7
--- looking through 27 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 119 candidates of size 10
-sum xs  =  if null xs then 0 else head xs + sum (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 31 candidates of size 5
+sum []  =  0
+sum (x:xs)  =  x + sum xs
 
 sum :: [Int] -> Int
 -- testing 6 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 15 candidates of size 7
--- looking through 27 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 119 candidates of size 10
-sum xs  =  if null xs then 0 else head xs + sum (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 31 candidates of size 5
+sum []  =  0
+sum (x:xs)  =  x + sum xs
 
 sum :: [Int] -> Int
 -- testing 6 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 15 candidates of size 7
--- looking through 27 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 119 candidates of size 10
-sum xs  =  if null xs then 0 else head xs + sum (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 31 candidates of size 5
+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
@@ -4,119 +4,6 @@
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
 
-sort' :: [Int] -> [Int]
-sort' []       =  []
-sort' [x]      =  [x]
-sort' [x,y]
-  | x <= y     =  [x,y]
-  | otherwise  =  [y,x]
-sort' [x,y,z]
-  | x <= y && y <= z  =  [x,y,z]
-  | z <= y && y <= x  =  [z,y,x]
-
-pow :: Int -> Int -> Int
-pow 2 0  =  1
-pow 2 1  =  2
-pow 2 2  =  4
-pow 2 3  =  8
-pow 3 2  =  9
-
-duplicates :: [Int] -> [Int] -- Eq a => [a] -> [a]
-duplicates []  =  []
-duplicates (x:xs)  =
-  if x `elem` xs && not (x `elem` d)
-  then x : d
-  else d
-  where
-  d  =  duplicates xs
-
-positionsFrom :: Int -> Int -> [Int] -> [Int]
-positionsFrom n x  =  from n
-  where
-  from _ []  =  []
-  from n (y:ys)  =  if y == x
-                    then n : f
-                    else f
-    where
-    f  =  from (n+1) ys
-
 main :: IO ()
 main = do
-  -- qsort
-  -- qsort xs  =  if null xs                                 -- 3
-  --              then []                                    -- 4
-  --              else qsort (filter (< head xs) (tail xs))  -- 11
-  --                ++ (head xs:[])                          -- 16
-  --                ++ qsort (filter (>= head xs) (tail xs)) -- 24
-  -- not only this is out of reach performance wise,
-  -- but the needed recursive calls will not be enumerated
-  conjure "qsort" sort'
-    [ pr ([] :: [Int])
-    , prim ":" ((:) :: Int -> [Int] -> [Int])
-    , prim "head" (head :: [Int] -> Int)
-    , prim "tail" (tail :: [Int] -> [Int])
-    , prim "null" (null :: [Int] -> Bool)
-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])
-    , prim "<" ((<) :: Int -> Int -> Bool)
-    , prim ">=" ((>=) :: Int -> Int -> Bool)
-    , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])
-    ]
-
-  -- pow b e  =  if e == 0 then 1 else b * pow b (dec e)
-  --             1  2  3 4      5      6 7 8   9  10 11
-  -- somehow this takes 30s to run, the two arguments
-  -- of the same type introduce the difficulty here.
-  conjureWithMaxSize 8 "pow" pow
-    [ pr (0::Int)
-    , pr (1::Int)
-    , prim "+" ((+) :: Int -> Int -> Int)
-    , prim "*" ((*) :: Int -> Int -> Int)
-    , prim "dec" (subtract 1 :: Int -> Int)
-    , prim "==" ((==) :: Int -> Int -> Bool)
-    ]
-
-  -- pow b e  =  if e == 0 then 1 else pow b (halve e) * pow b (halve e) * if odd e then b else 1
-  --             1  2  3 4      5      6   7  8     9 10 11 12  13   14 15 16 17  18    19     20
-  -- out of reach performance wise
-  conjureWithMaxSize 8 "pow" pow
-    [ pr (0::Int)
-    , pr (1::Int)
-    , prim "+" ((+) :: Int -> Int -> Int)
-    , prim "*" ((*) :: Int -> Int -> Int)
-    , prim "halve" ((`div` 2) :: Int -> Int)
-    , prim "==" ((==) :: Int -> Int -> Bool)
-    ]
-
-  -- duplicates xs  =
-  --   if null xs                                                                   --  3
-  --   then []                                                                      --  4
-  --   else if head xs `elem` tail xs && not (head xs `elem` duplicates (tail xs))  -- 18
-  --        then head xs : duplicates (tail xs)                                     -- 24
-  --        else duplicates (tail xs)                                               -- 27
-  conjure "duplicates" duplicates
-    [ pr ([] :: [Int])
-    , pr True
-    , pr False
-    , prim "not" not
-    , prim "||" (||)
-    , prim "&&" (&&)
-    , prim ":" ((:) :: Int -> [Int] -> [Int])
-    , prim "head" (head :: [Int] -> Int)
-    , prim "tail" (tail :: [Int] -> [Int])
-    , prim "null" (null :: [Int] -> Bool)
-    , prim "elem" (elem :: Int -> [Int] -> Bool)
-    ]
-
-  conjure "positionsFrom" positionsFrom
-    [ pr ([] :: [Int])
-    , pr True
-    , pr False
-    , prim "not" not
-    , prim "||" (||)
-    , prim "&&" (&&)
-    , prim ":" ((:) :: Int -> [Int] -> [Int])
-    , prim "head" (head :: [Int] -> Int)
-    , prim "tail" (tail :: [Int] -> [Int])
-    , prim "null" (null :: [Int] -> Bool)
-    , prim "==" ((==) :: Int -> Int -> Bool)
-    ]
+  return ()  -- \o/ no misc longshots ATM (formerly: eg/sort & bench/dupos)
diff --git a/bench/longshot.out b/bench/longshot.out
--- a/bench/longshot.out
+++ b/bench/longshot.out
@@ -1,77 +0,0 @@
-qsort :: [Int] -> [Int]
--- testing 60 combinations of argument values
--- pruning with 13/14 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 11 candidates of size 4
--- looking through 28 candidates of size 5
--- looking through 72 candidates of size 6
--- looking through 207 candidates of size 7
--- looking through 611 candidates of size 8
--- looking through 1779 candidates of size 9
--- looking through 5301 candidates of size 10
--- looking through 16107 candidates of size 11
--- looking through 49149 candidates of size 12
-cannot conjure
-
-pow :: Int -> Int -> Int
--- testing 5 combinations of argument values
--- pruning with 40/73 rules
--- looking through 4 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 13 candidates of size 3
--- looking through 20 candidates of size 4
--- looking through 80 candidates of size 5
--- looking through 172 candidates of size 6
--- looking through 614 candidates of size 7
--- looking through 1623 candidates of size 8
-cannot conjure
-
-pow :: Int -> Int -> Int
--- testing 5 combinations of argument values
--- pruning with 31/55 rules
--- looking through 4 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 15 candidates of size 3
--- looking through 26 candidates of size 4
--- looking through 111 candidates of size 5
--- looking through 307 candidates of size 6
--- looking through 1122 candidates of size 7
--- looking through 3675 candidates of size 8
-cannot conjure
-
-duplicates :: [Int] -> [Int]
--- testing 60 combinations of argument values
--- pruning with 44/55 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 14 candidates of size 6
--- looking through 30 candidates of size 7
--- looking through 70 candidates of size 8
--- looking through 154 candidates of size 9
--- looking through 366 candidates of size 10
--- looking through 914 candidates of size 11
--- looking through 2238 candidates of size 12
-cannot conjure
-
-positionsFrom :: Int -> Int -> [Int] -> [Int]
--- testing 60 combinations of argument values
--- pruning with 42/55 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 10 candidates of size 4
--- looking through 22 candidates of size 5
--- looking through 42 candidates of size 6
--- looking through 86 candidates of size 7
--- looking through 170 candidates of size 8
--- looking through 358 candidates of size 9
--- looking through 810 candidates of size 10
--- looking through 2070 candidates of size 11
--- looking through 5706 candidates of size 12
-cannot conjure
-
diff --git a/bench/lowtests.hs b/bench/lowtests.hs
new file mode 100644
--- /dev/null
+++ b/bench/lowtests.hs
@@ -0,0 +1,86 @@
+-- lowtests.hs: conjuring with a low number of tests
+--
+-- Copyright (C) 2021 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
+-- function due to Speculate finding incorrect properties from later properties
+-- using reasoning.
+{-# LANGUAGE CPP #-}
+import Conjure
+import Data.List (sort, transpose)
+
+#if __GLASGOW_HASKELL__ >= 710
+import Data.List (isSubsequenceOf)
+#else
+isSubsequenceOf :: Eq a => [a] -> [a] -> Bool
+isSubsequenceOf []    _  = True
+isSubsequenceOf (_:_) [] = False
+isSubsequenceOf (x:xs) (y:ys)
+  | x == y    =    xs  `isSubsequenceOf` ys
+  | otherwise = (x:xs) `isSubsequenceOf` ys
+#endif
+
+subset' :: [Int] -> [Int] -> Bool
+subset' [] [x]  =  True
+subset' [x] []  =  False
+subset' [0] [0]  =  True
+subset' [1] [1]  =  True
+subset' [0] [1]  =  False
+subset' [1] [0]  =  False
+subset' [0] [0,1]  =  True
+subset' [1] [0,1]  =  True
+subset' [0] [1,0]  =  True
+subset' [1] [1,0]  =  True
+subset' [2] [0,1]  =  False
+subset' [2] [1,0]  =  False
+subset' [0,1] [0]  =  False
+subset' [0,1] [1]  =  False
+subset' [0,1] [0,1]  =  True
+subset' [0,1] [1,0]  =  True
+subset' [1,0] [0,1]  =  True
+subset' [1,0] [1,0]  =  True
+subset' [0,1,2] [0,1,2]  =  True
+subset' [0,1,2,3] [0,1,2,3]  =  True
+
+-- this function is one of the examples of MagicHaskeller
+replicates' :: String -> Int -> String
+replicates' [a]     1  =  [a]
+replicates' [a,b]   1  =  [a,b]
+replicates' [a]     2  =  [a,a]
+replicates' [a,b]   2  =  [a,a,b,b]
+replicates' [a,b,c] 2  =  [a,a,b,b,c,c]
+replicates' [a]     3  =  [a,a,a]
+replicates' [a,b]   3  =  [a,a,a,b,b,b]
+replicates' [a,b,c] 3  =  [a,a,a,b,b,b,c,c,c]
+
+as :: Args
+as  =  args{showTheory = True}
+
+main :: IO ()
+main = do
+  -- low number of tests, cannot conjure due to incorrect property
+  conjureWith as{maxTests=60} "subset" (subset')
+    [ prim "sort" (sort :: [Int] -> [Int])
+    , prim "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)
+    ]
+
+  -- subset xs ys  =  sort xs `isSubsequenceOf` sort ys
+  conjureWith as{maxTests=360} "subset" (subset')
+    [ prim "sort" (sort :: [Int] -> [Int])
+    , prim "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)
+    ]
+
+  -- low number of tests, cannot conjure due to incorrect property
+  conjureWith as{maxTests=60} "replicates" replicates'
+    [ prim "replicate" (replicate :: Int -> String -> [String])
+    , prim "transpose" (transpose :: [[Char]] -> [[Char]])
+    , prim "concat"    (concat :: [String] -> String)
+    ]
+
+  -- emulates how MagicHaskeller generates "replicates"
+  conjureWith as{maxTests=360} "replicates" replicates'
+    [ prim "replicate" (replicate :: Int -> String -> [String])
+    , prim "transpose" (transpose :: [[Char]] -> [[Char]])
+    , prim "concat"    (concat :: [String] -> String)
+    ]
diff --git a/bench/lowtests.out b/bench/lowtests.out
new file mode 100644
--- /dev/null
+++ b/bench/lowtests.out
@@ -0,0 +1,81 @@
+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 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 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 22 candidates of size 8
+-- looking through 8 candidates of size 9
+-- looking through 0 candidates of size 10
+-- looking through 0 candidates of size 11
+-- looking through 0 candidates of size 12
+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
+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
+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
+replicates cs x  =  concat (transpose (replicate x cs))
+
diff --git a/bench/p12.out b/bench/p12.out
--- a/bench/p12.out
+++ b/bench/p12.out
@@ -3,10 +3,11 @@
 -- 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 16 candidates of size 4
--- looking through 55 candidates of size 5
--- looking through 175 candidates of size 6
-factorial n  =  foldr (*) 1 [1..n]
+-- looking through 7 candidates of size 2
+-- looking through 22 candidates of size 3
+-- looking through 62 candidates of size 4
+-- looking through 175 candidates of size 5
+-- looking through 542 candidates of size 6
+factorial 0  =  1
+factorial x  =  x * factorial (dec x)
 
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 @@
-2.1
+10.0
diff --git a/bench/runtime/zero/bench/gps.runtime b/bench/runtime/zero/bench/gps.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/bench/gps.runtime
@@ -0,0 +1,1 @@
+15.2
diff --git a/bench/runtime/zero/bench/ill-hit.runtime b/bench/runtime/zero/bench/ill-hit.runtime
--- a/bench/runtime/zero/bench/ill-hit.runtime
+++ b/bench/runtime/zero/bench/ill-hit.runtime
@@ -1,1 +1,1 @@
-1.4
+1.3
diff --git a/bench/runtime/zero/bench/longshot.runtime b/bench/runtime/zero/bench/longshot.runtime
--- a/bench/runtime/zero/bench/longshot.runtime
+++ b/bench/runtime/zero/bench/longshot.runtime
@@ -1,1 +1,1 @@
-10.0
+0.0
diff --git a/bench/runtime/zero/bench/lowtests.runtime b/bench/runtime/zero/bench/lowtests.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/bench/lowtests.runtime
@@ -0,0 +1,1 @@
+0.4
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 @@
-2.9
+3.5
diff --git a/bench/runtime/zero/bench/take-drop.runtime b/bench/runtime/zero/bench/take-drop.runtime
--- a/bench/runtime/zero/bench/take-drop.runtime
+++ b/bench/runtime/zero/bench/take-drop.runtime
@@ -1,1 +1,1 @@
-10.6
+0.6
diff --git a/bench/runtime/zero/eg/arith.runtime b/bench/runtime/zero/eg/arith.runtime
--- a/bench/runtime/zero/eg/arith.runtime
+++ b/bench/runtime/zero/eg/arith.runtime
@@ -1,1 +1,1 @@
-0.9
+1.2
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.9
+3.5
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 @@
-4.4
+0.7
diff --git a/bench/runtime/zero/eg/dupos.runtime b/bench/runtime/zero/eg/dupos.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/dupos.runtime
@@ -0,0 +1,1 @@
+5.4
diff --git a/bench/runtime/zero/eg/factorial.runtime b/bench/runtime/zero/eg/factorial.runtime
--- a/bench/runtime/zero/eg/factorial.runtime
+++ b/bench/runtime/zero/eg/factorial.runtime
@@ -1,1 +1,1 @@
-2.8
+0.8
diff --git a/bench/runtime/zero/eg/fib01.runtime b/bench/runtime/zero/eg/fib01.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/fib01.runtime
@@ -0,0 +1,1 @@
+5.8
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 @@
-29.9
+1.4
diff --git a/bench/runtime/zero/eg/ints.runtime b/bench/runtime/zero/eg/ints.runtime
--- a/bench/runtime/zero/eg/ints.runtime
+++ b/bench/runtime/zero/eg/ints.runtime
@@ -1,1 +1,1 @@
-1.3
+1.6
diff --git a/bench/runtime/zero/eg/list.runtime b/bench/runtime/zero/eg/list.runtime
--- a/bench/runtime/zero/eg/list.runtime
+++ b/bench/runtime/zero/eg/list.runtime
@@ -1,1 +1,1 @@
-1.1
+0.5
diff --git a/bench/runtime/zero/eg/pow.runtime b/bench/runtime/zero/eg/pow.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/pow.runtime
@@ -0,0 +1,1 @@
+2.3
diff --git a/bench/runtime/zero/eg/replicate.runtime b/bench/runtime/zero/eg/replicate.runtime
--- a/bench/runtime/zero/eg/replicate.runtime
+++ b/bench/runtime/zero/eg/replicate.runtime
@@ -1,1 +1,1 @@
-7.0
+0.4
diff --git a/bench/runtime/zero/eg/setelem.runtime b/bench/runtime/zero/eg/setelem.runtime
--- a/bench/runtime/zero/eg/setelem.runtime
+++ b/bench/runtime/zero/eg/setelem.runtime
@@ -1,1 +1,1 @@
-41.7
+2.5
diff --git a/bench/runtime/zero/eg/sort.runtime b/bench/runtime/zero/eg/sort.runtime
new file mode 100644
--- /dev/null
+++ b/bench/runtime/zero/eg/sort.runtime
@@ -0,0 +1,1 @@
+1.3
diff --git a/bench/runtime/zero/eg/subset.runtime b/bench/runtime/zero/eg/subset.runtime
--- a/bench/runtime/zero/eg/subset.runtime
+++ b/bench/runtime/zero/eg/subset.runtime
@@ -1,1 +1,1 @@
-7.1
+0.8
diff --git a/bench/runtime/zero/eg/tapps.runtime b/bench/runtime/zero/eg/tapps.runtime
--- a/bench/runtime/zero/eg/tapps.runtime
+++ b/bench/runtime/zero/eg/tapps.runtime
@@ -1,1 +1,1 @@
-0.7
+0.8
diff --git a/bench/runtime/zero/eg/tree.runtime b/bench/runtime/zero/eg/tree.runtime
--- a/bench/runtime/zero/eg/tree.runtime
+++ b/bench/runtime/zero/eg/tree.runtime
@@ -1,1 +1,1 @@
-8.1
+2.2
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 8.10.4
 leancheck-0.9.10
-express-1.0.2
-speculate-0.4.10
+express-1.0.4
+speculate-0.4.12
diff --git a/bench/self.out b/bench/self.out
--- a/bench/self.out
+++ b/bench/self.out
@@ -1,32 +1,32 @@
 (?) :: Int -> Int -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 0/0 rules
 -- looking through 4 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 32 candidates of size 3
+-- looking through 18 candidates of size 2
+-- looking through 120 candidates of size 3
 x ? y  =  x + y
 
 (?) :: Int -> Int -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 0/0 rules
 -- looking through 4 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 32 candidates of size 3
+-- looking through 18 candidates of size 2
+-- looking through 120 candidates of size 3
 x ? y  =  x * y
 
 i :: Int -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 0/0 rules
 -- looking through 3 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 18 candidates of size 3
+-- looking through 4 candidates of size 2
+-- looking through 22 candidates of size 3
 i x  =  x + 1
 
 d :: Int -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 0/0 rules
 -- looking through 3 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 18 candidates of size 3
+-- looking through 4 candidates of size 2
+-- looking through 22 candidates of size 3
 cannot conjure
 
diff --git a/bench/take-drop.hs b/bench/take-drop.hs
--- a/bench/take-drop.hs
+++ b/bench/take-drop.hs
@@ -21,13 +21,15 @@
 main = do
   -- drop n xs = if n==0 || null xs then xs else drop (dec n) (tail xs)
   -- needs size 13
-  conjureWithMaxSize 13 "drop" (drop' :: Int -> [A] -> [A])
+  -- drop 0 []      =  []               -- 1
+  -- drop 0 (x:xs)  =  x : xs           -- 4
+  -- drop n []      =  []               -- 5
+  -- drop n (x:xs)  =  drop (dec n) xs  -- 9
+  conjure "drop" (drop' :: Int -> [A] -> [A])
     [ pr (0 :: Int)
-    , prim "null" (null :: [A] -> Bool)
-    , prim "==" ((==) :: Int -> Int -> Bool)
-    , prim "||" (||)
+    , pr ([] :: [A])
+    , prim ":" ((:) :: A -> [A] -> [A])
     , prim "dec" (subtract 1 :: Int -> Int)
-    , prim "tail" (tail :: [A] -> [A])
     ]
 
   -- take n xs = if n==0 || null xs then [] else head xs : take (dec n) (tail xs)
@@ -36,7 +38,6 @@
     [ pr (0 :: Int)
     , pr ([] :: [A])
     , prim "null" (null :: [A] -> Bool)
-    , prim "==" ((==) :: Int -> Int -> Bool)
     , prim "||" ((||) :: Bool -> Bool -> Bool)
     , prim "dec" ((\n -> n-1) :: Int -> Int)
     , prim ":" ((:) :: A -> [A] -> [A])
diff --git a/bench/take-drop.out b/bench/take-drop.out
--- a/bench/take-drop.out
+++ b/bench/take-drop.out
@@ -1,39 +1,32 @@
 drop :: Int -> [A] -> [A]
--- testing 60 combinations of argument values
--- pruning with 16/22 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 1 candidates of size 5
--- looking through 1 candidates of size 6
--- looking through 1 candidates of size 7
--- looking through 7 candidates of size 8
--- looking through 35 candidates of size 9
--- looking through 109 candidates of size 10
--- looking through 261 candidates of size 11
--- looking through 567 candidates of size 12
--- looking through 1183 candidates of size 13
-drop x xs  =  if null xs || x == 0 then xs else drop (dec x) (tail xs)
+-- testing 143 combinations of argument values
+-- pruning with 0/0 rules
+-- looking through 2 candidates of size 1
+-- looking through 3 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 5 candidates of size 4
+-- looking through 23 candidates of size 5
+-- looking through 24 candidates of size 6
+-- looking through 55 candidates of size 7
+-- looking through 71 candidates of size 8
+drop 0 []  =  []
+drop 0 (x:xs)  =  x:xs
+drop x []  =  []
+drop x (y:xs)  =  drop (dec x) xs
 
 take :: Int -> [A] -> [A]
--- testing 60 combinations of argument values
--- pruning with 20/26 rules
+-- testing 143 combinations of argument values
+-- pruning with 14/18 rules
 -- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 14 candidates of size 6
--- looking through 26 candidates of size 7
--- looking through 62 candidates of size 8
--- looking through 182 candidates of size 9
--- looking through 498 candidates of size 10
--- looking through 1270 candidates of size 11
--- looking through 3346 candidates of size 12
--- looking through 8650 candidates of size 13
--- looking through 21270 candidates of size 14
--- looking through 51166 candidates of size 15
--- looking through 121430 candidates of size 16
-take x xs  =  if null xs || x == 0 then [] else head xs:take (dec x) (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 17 candidates of size 3
+-- looking through 42 candidates of size 4
+-- looking through 136 candidates of size 5
+-- looking through 363 candidates of size 6
+-- looking through 921 candidates of size 7
+-- looking through 2354 candidates of size 8
+take 0 []  =  []
+take 0 (x:xs)  =  []
+take x []  =  []
+take x (y:xs)  =  y:take (dec x) xs
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,19 @@
 ============================
 
 
+v0.4.2
+------
+
+* default to using top-level patterns on generated functions;
+* memoize function evaluation;
+* double-check theory at the end and report warning on incorrect properties;
+* add `prif` to `Conjure`;
+* simplify deconstructor discovery and add `conjureSize` to `Conjurable`;
+* add `cevaluate`, `ceval` and `cvl` to `Conjure.Conjurable`;
+* add `bench/gps` and `bench/lowtests`;
+* improve tests and benchmarks.
+
+
 v0.4.0
 ------
 
diff --git a/code-conjure.cabal b/code-conjure.cabal
--- a/code-conjure.cabal
+++ b/code-conjure.cabal
@@ -3,7 +3,7 @@
 -- Copyright (C) 2021 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 name:                code-conjure
-version:             0.4.0
+version:             0.4.2
 synopsis:            conjure Haskell functions out of partial definitions
 description:
   Conjure is a tool that produces Haskell functions out of partial definitions.
@@ -66,7 +66,7 @@
 source-repository this
   type:            git
   location:        https://github.com/rudymatela/conjure
-  tag:             v0.4.0
+  tag:             v0.4.2
 
 library
   exposed-modules: Conjure
diff --git a/eg/arith.out b/eg/arith.out
--- a/eg/arith.out
+++ b/eg/arith.out
@@ -2,35 +2,35 @@
 -- testing 4 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 3 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 5 candidates of size 3
+-- looking through 4 candidates of size 2
+-- looking through 9 candidates of size 3
 double 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 0 candidates of size 2
--- looking through 13 candidates of size 3
+-- looking through 18 candidates of size 2
+-- looking through 101 candidates of size 3
 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 0 candidates of size 2
--- looking through 5 candidates of size 3
+-- looking through 4 candidates of size 2
+-- looking through 9 candidates of size 3
 square 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 0 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 13 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 42 candidates of size 7
+-- looking through 4 candidates of size 2
+-- looking through 9 candidates of size 3
+-- looking through 23 candidates of size 4
+-- looking through 26 candidates of size 5
+-- looking through 65 candidates of size 6
+-- looking through 75 candidates of size 7
 tnpo x  =  x + (x + (x + 1))
 
diff --git a/eg/bools.out b/eg/bools.out
--- a/eg/bools.out
+++ b/eg/bools.out
@@ -2,46 +2,39 @@
 -- testing 14 combinations of argument values
 -- pruning with 37/47 rules
 -- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 6 candidates of size 5
--- looking through 19 candidates of size 6
--- looking through 45 candidates of size 7
--- looking through 80 candidates of size 8
--- looking through 172 candidates of size 9
-and ps  =  null ps || head ps && and (tail ps)
+-- looking through 6 candidates of size 2
+-- looking through 12 candidates of size 3
+-- looking through 16 candidates of size 4
+-- looking through 40 candidates of size 5
+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 2 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 4 candidates of size 4
--- looking through 6 candidates of size 5
--- looking through 19 candidates of size 6
--- looking through 45 candidates of size 7
--- looking through 80 candidates of size 8
--- looking through 172 candidates of size 9
--- looking through 462 candidates of size 10
-or ps  =  not (null ps) && (head ps || or (tail ps))
+-- looking through 6 candidates of size 2
+-- looking through 12 candidates of size 3
+-- looking through 16 candidates of size 4
+-- looking through 40 candidates of size 5
+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 2 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 6 candidates of size 4
+-- looking through 6 candidates of size 2
+-- looking through 12 candidates of size 3
+-- looking through 18 candidates of size 4
 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 2 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 6 candidates of size 4
+-- looking through 6 candidates of size 2
+-- looking through 12 candidates of size 3
+-- looking through 18 candidates of size 4
 or ps  =  foldr (||) False ps
 
diff --git a/eg/count.out b/eg/count.out
--- a/eg/count.out
+++ b/eg/count.out
@@ -12,20 +12,16 @@
 -- testing 13 combinations of argument values
 -- pruning with 8/13 rules
 -- looking through 2 candidates of size 1
--- looking through 0 candidates of size 2
+-- looking through 2 candidates of size 2
 -- looking through 1 candidates of size 3
--- looking through 0 candidates of size 4
--- looking through 3 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 13 candidates of size 7
--- looking through 16 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 90 candidates of size 10
--- looking through 258 candidates of size 11
--- looking through 448 candidates of size 12
--- looking through 1145 candidates of size 13
--- looking through 2144 candidates of size 14
--- looking through 5216 candidates of size 15
--- looking through 10320 candidates of size 16
-count x xs  =  if null xs then 0 else (if head xs == x then 1 else 0) + count x (tail xs)
+-- looking through 8 candidates of size 4
+-- looking through 9 candidates of size 5
+-- looking through 24 candidates of size 6
+-- looking through 44 candidates of size 7
+-- looking through 108 candidates of size 8
+-- looking through 244 candidates of size 9
+-- looking through 574 candidates of size 10
+-- looking through 1320 candidates of size 11
+count x []  =  0
+count x (y:xs)  =  (if x == y then 1 else 0) + count x xs
 
diff --git a/eg/dupos.hs b/eg/dupos.hs
new file mode 100644
--- /dev/null
+++ b/eg/dupos.hs
@@ -0,0 +1,77 @@
+-- dupos.hs: duplicates and positions
+--
+-- Copyright (C) 2021 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+
+duplicates :: [Int] -> [Int] -- Eq a => [a] -> [a]
+duplicates []  =  []
+duplicates (x:xs)  =
+  if x `elem` xs && not (x `elem` d)
+  then x : d
+  else d
+  where
+  d  =  duplicates xs
+
+duplicates' :: [Int] -> [Int]
+duplicates' [0,0]  =  [0]
+duplicates' [0,1]  =  []
+duplicates' [1,0,1]  =  [1]
+duplicates' [0,1,0,1]  =  [0,1]
+duplicates' [1,0,1,0,1]  =  [0,1]
+duplicates' [0,1,2,1]  =  [1]
+
+positionsFrom :: Int -> Int -> [Int] -> [Int]
+positionsFrom n x  =  from n
+  where
+  from _ []  =  []
+  from n (y:ys)  =  if y == x
+                    then n : f
+                    else f
+    where
+    f  =  from (n+1) ys
+
+-- this is what conjure _can_ generate
+positionsFrom' :: Int -> A -> [A] -> [Int]
+positionsFrom' _ _ []      =  []                                  --  1
+positionsFrom' n x (y:ys)  =  if y == x                           --  4
+                              then n : positionsFrom' (n+1) x ys  -- 12
+                              else     positionsFrom' (n+1) x ys  -- 18
+
+main :: IO ()
+main = do
+  -- duplicates xs  =
+  --   if null xs                                                                   --  3
+  --   then []                                                                      --  4
+  --   else if head xs `elem` tail xs && not (head xs `elem` duplicates (tail xs))  -- 18
+  --        then head xs : duplicates (tail xs)                                     -- 24
+  --        else duplicates (tail xs)                                               -- 27
+  -- out of reach memory and performance wise
+  -- -- OR --
+  -- duplicates []  =  []                                                  --  1
+  -- duplicates (x:xs)  =  if x `elem` xs && not (x `elem` duplicates xs)  -- 11
+  --                       then x : duplicates xs                          -- 15
+  --                       else duplicates xs                              -- 17
+  -- within reach performance wise.
+  conjureWith args{maxSize=18} "duplicates" duplicates'
+    [ pr ([] :: [Int])
+    , prim "not" not
+    , prim "&&" (&&)
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "elem" (elem :: Int -> [Int] -> Bool)
+    , prif (undefined :: [Int])
+    ]
+
+  -- found!
+  conjureWithMaxSize 14 "positionsFrom" positionsFrom'
+    [ pr ([] :: [Int])
+    , pr (1 :: Int)
+    , prim "+" ((+) :: Int -> Int -> Int)
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "==" ((==) :: A -> A -> Bool)
+
+--  , prif (undefined :: [Int])
+    -- cheat codes:
+    , prim "id" (id :: [Int] -> [Int])
+    , prif (undefined :: [Int] -> [Int])
+    ]
diff --git a/eg/dupos.out b/eg/dupos.out
new file mode 100644
--- /dev/null
+++ b/eg/dupos.out
@@ -0,0 +1,43 @@
+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 65 candidates of size 12
+-- looking through 141 candidates of size 13
+-- looking through 322 candidates of size 14
+-- looking through 644 candidates of size 15
+-- looking through 1185 candidates of size 16
+-- looking through 2153 candidates of size 17
+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 7 candidates of size 4
+-- looking through 18 candidates of size 5
+-- looking through 35 candidates of size 6
+-- looking through 89 candidates of size 7
+-- looking through 190 candidates of size 8
+-- looking through 440 candidates of size 9
+-- looking through 926 candidates of size 10
+-- looking through 2113 candidates of size 11
+-- looking through 4520 candidates of size 12
+-- looking through 10066 candidates of size 13
+-- looking through 21492 candidates of size 14
+positionsFrom x y []  =  []
+positionsFrom x y (z:xs)  =  (if y == z then (x :) else id) (positionsFrom (x + 1) y xs)
+
diff --git a/eg/factorial.hs b/eg/factorial.hs
--- a/eg/factorial.hs
+++ b/eg/factorial.hs
@@ -5,12 +5,10 @@
 import Conjure
 
 factorial :: Int -> Int
-factorial 0  =  1
 factorial 1  =  1
 factorial 2  =  2
 factorial 3  =  6
 factorial 4  =  24
-factorial 5  =  120
 
 
 main :: IO ()
@@ -30,7 +28,6 @@
     , prim "+" ((+) :: Int -> Int -> Int)
     , prim "*" ((*) :: Int -> Int -> Int)
     , prim "dec" (subtract 1 :: Int -> Int)
-    , prim "==" ((==) :: Int -> Int -> Bool)
     ]
 
 -- the actual factorial function:
diff --git a/eg/factorial.out b/eg/factorial.out
--- a/eg/factorial.out
+++ b/eg/factorial.out
@@ -1,26 +1,23 @@
 factorial :: Int -> Int
--- testing 6 combinations of argument values
+-- testing 4 combinations of argument values
 -- pruning with 4/8 rules
 -- looking through 2 candidates of size 1
--- looking through 0 candidates of size 2
+-- looking through 1 candidates of size 2
 -- looking through 1 candidates of size 3
--- looking through 0 candidates of size 4
+-- looking through 1 candidates of size 4
 -- looking through 1 candidates of size 5
--- looking through 8 candidates of size 6
-factorial n  =  foldr (*) 1 [1..n]
+-- looking through 9 candidates of size 6
+factorial x  =  foldr (*) 1 [1..x]
 
 factorial :: Int -> Int
--- testing 6 combinations of argument values
--- pruning with 40/73 rules
+-- testing 4 combinations of argument values
+-- pruning with 22/42 rules
 -- looking through 3 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 20 candidates of size 5
--- looking through 27 candidates of size 6
--- looking through 87 candidates of size 7
--- looking through 173 candidates of size 8
--- looking through 434 candidates of size 9
--- looking through 1016 candidates of size 10
-factorial n  =  if n == 0 then 1 else n * factorial (dec n)
+-- looking through 6 candidates of size 2
+-- looking through 16 candidates of size 3
+-- looking through 39 candidates of size 4
+-- looking through 78 candidates of size 5
+-- looking through 166 candidates of size 6
+factorial 0  =  1
+factorial x  =  x * factorial (dec x)
 
diff --git a/eg/fib01.hs b/eg/fib01.hs
new file mode 100644
--- /dev/null
+++ b/eg/fib01.hs
@@ -0,0 +1,31 @@
+-- fib01.hs: conjuring an efficient fibonacci function
+import Conjure
+
+fib01 :: Int -> Int -> Int -> Int
+fib01 0 1 0  =  1
+fib01 0 1 1  =  1
+fib01 0 1 2  =  2
+fib01 0 1 3  =  3
+fib01 0 1 4  =  5
+fib01 0 1 5  =  8
+fib01 0 1 6  =  13
+fib01 0 1 7  =  21
+
+main :: IO ()
+main  =  do
+  conjureWithMaxSize 5 "fib01" fib01
+    [ pr (0::Int)
+    , prim "dec" (subtract 1 :: Int -> Int)
+    , prim "+" ((+) :: Int -> Int -> Int)
+    ]
+
+  -- takes about 22 seconds to run with maxSize=12
+  conjureWith args{usePatterns = False, maxSize = 10} "fib01" fib01
+    [ pr (0::Int)
+    , prim "+" ((+) :: Int -> Int -> Int)
+    , prim "dec" (subtract 1 :: Int -> Int)
+    , prim "<=" ((<=) :: Int -> Int -> Bool)
+    ]
+-- expected function:
+-- fib01 x y z  =  if z <= 0 then y else fib01 y (x + y) (dec z)
+--                 1  2 3  4      5      6     7  8 9 10  11 12
diff --git a/eg/fib01.out b/eg/fib01.out
new file mode 100644
--- /dev/null
+++ b/eg/fib01.out
@@ -0,0 +1,25 @@
+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 31 candidates of size 2
+-- looking through 295 candidates of size 3
+-- looking through 1968 candidates of size 4
+-- looking through 10684 candidates of size 5
+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 9 candidates of size 3
+-- looking through 21 candidates of size 4
+-- looking through 43 candidates of size 5
+-- looking through 84 candidates of size 6
+-- looking through 192 candidates of size 7
+-- looking through 391 candidates of size 8
+-- looking through 840 candidates of size 9
+-- looking through 15630 candidates of size 10
+cannot conjure
+
diff --git a/eg/fibonacci.hs b/eg/fibonacci.hs
--- a/eg/fibonacci.hs
+++ b/eg/fibonacci.hs
@@ -11,37 +11,26 @@
 fibonacci 6  =  13
 fibonacci 7  =  21
 
-fib01 :: Int -> Int -> Int -> Int
-fib01 0 1 0  =  1
-fib01 0 1 1  =  1
-fib01 0 1 2  =  2
-fib01 0 1 3  =  3
-fib01 0 1 4  =  5
-fib01 0 1 5  =  8
-fib01 0 1 6  =  13
-fib01 0 1 7  =  21
-
-as :: Args
-as  =  args{maxSize=13}
-
 main :: IO ()
 main  =  do
-  conjureWithMaxSize 13 "fibonacci n" fibonacci
-    [ pr (1::Int)
-    , prim "+" ((+) :: Int -> Int -> Int)
+  conjure "fibonacci n" fibonacci
+    [ pr (0::Int)
+    , pr (1::Int)
     , prim "dec" (subtract 1 :: Int -> Int)
-    , prim "<=" ((<=) :: Int -> Int -> Bool)
+    , prim "+" ((+) :: Int -> Int -> Int)
     ]
 -- expected function:
 -- fibonacci n  =  if n <= 1 then 1 else fibonacci (dec n) + fibonacci (dec (dec n))
 --                 1  2 3  4      5      6          7   8  9        10  11   12  13
 
-  conjure "fib01" fib01
-    [ pr (0::Int)
-    , prim "+" ((+) :: Int -> Int -> Int)
-    , prim "dec" (subtract 1 :: Int -> Int)
-    , prim "<=" ((<=) :: Int -> Int -> Bool)
-    ]
--- expected function:
--- fib01 x y z  =  if z <= 0 then y else fib01 y (x + y) (dec z)
---                 1  2 3  4      5      6     7  8 9 10  11 12
+
+{- to note, if dec appears later than + in the primitives list:
+
+conjureWith ...  =
+
+> print $ canReduceTo thy (xx -+- dec xx) (dec (dec xx))
+False
+> print $ canReduceTo thy (dec (dec xx)) (xx -+- dec xx)
+True
+
+-}
diff --git a/eg/fibonacci.out b/eg/fibonacci.out
--- a/eg/fibonacci.out
+++ b/eg/fibonacci.out
@@ -1,35 +1,18 @@
 fibonacci :: Int -> Int
 -- testing 8 combinations of argument values
--- pruning with 20/38 rules
--- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 6 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 11 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 27 candidates of size 7
--- looking through 20 candidates of size 8
--- looking through 95 candidates of size 9
--- looking through 172 candidates of size 10
--- looking through 519 candidates of size 11
--- looking through 1281 candidates of size 12
--- looking through 3289 candidates of size 13
-fibonacci n  =  if n <= 1 then 1 else fibonacci (dec n) + fibonacci (dec (dec n))
-
-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 9 candidates of size 3
--- looking through 21 candidates of size 4
--- looking through 43 candidates of size 5
--- looking through 84 candidates of size 6
--- looking through 192 candidates of size 7
--- looking through 391 candidates of size 8
--- looking through 840 candidates of size 9
--- looking through 9294 candidates of size 10
--- looking through 45295 candidates of size 11
--- looking through 215844 candidates of size 12
-fib01 x y z  =  if z <= 0 then y else fib01 y (x + y) (dec z)
+-- pruning with 9/13 rules
+-- looking through 3 candidates of size 1
+-- looking through 6 candidates of size 2
+-- looking through 17 candidates of size 3
+-- looking through 41 candidates of size 4
+-- looking through 76 candidates of size 5
+-- looking through 155 candidates of size 6
+-- looking through 249 candidates of size 7
+-- looking through 481 candidates of size 8
+-- looking through 762 candidates of size 9
+-- looking through 1413 candidates of size 10
+-- looking through 2257 candidates of size 11
+fibonacci 0  =  1
+fibonacci 1  =  1
+fibonacci x  =  fibonacci (dec x) + fibonacci (dec (dec x))
 
diff --git a/eg/gcd.hs b/eg/gcd.hs
--- a/eg/gcd.hs
+++ b/eg/gcd.hs
@@ -21,7 +21,6 @@
 main = conjureWith args{requireDescent=False} "gcd a b" gcd'
   [ pr (0::Int)
   , prim "`mod`" (mod :: Int -> Int -> Int)
-  , prim "==" ((==) :: Int -> Int -> Bool)
   ]
   -- desired function:
   -- gcd a b  =  if b == 0 then a else gcd b (a `mod` b)
diff --git a/eg/gcd.out b/eg/gcd.out
--- a/eg/gcd.out
+++ b/eg/gcd.out
@@ -1,15 +1,12 @@
 gcd :: Int -> Int -> Int
 -- testing 11 combinations of argument values
--- pruning with 1/2 rules
+-- pruning with 0/0 rules
 -- looking through 3 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 54 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 405 candidates of size 7
--- looking through 90 candidates of size 8
--- looking through 3402 candidates of size 9
--- looking through 2016 candidates of size 10
-gcd a b  =  if a == 0 then b else gcd (b `mod` a) a
+-- looking through 8 candidates of size 2
+-- looking through 20 candidates of size 3
+-- looking through 88 candidates of size 4
+-- looking through 202 candidates of size 5
+-- looking through 808 candidates of size 6
+gcd x 0  =  x
+gcd x y  =  gcd y (x `mod` y)
 
diff --git a/eg/ints.out b/eg/ints.out
--- a/eg/ints.out
+++ b/eg/ints.out
@@ -1,65 +1,57 @@
 second :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
 second xs  =  head (tail xs)
 
 third :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
 third xs  =  head (tail (tail xs))
 
 sum :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 15 candidates of size 7
--- looking through 27 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 119 candidates of size 10
-sum xs  =  if null xs then 0 else head xs + sum (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 31 candidates of size 5
+sum []  =  0
+sum (x:xs)  =  x + sum xs
 
 product :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 15 candidates of size 7
--- looking through 27 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 119 candidates of size 10
-product xs  =  if null xs then 1 else head xs * product (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 31 candidates of size 5
+product []  =  1
+product (x:xs)  =  x * product xs
 
 sum :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 15/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 5 candidates of size 4
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 22 candidates of size 4
 sum xs  =  foldr (+) 0 xs
 
 product :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 15/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 5 candidates of size 4
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 22 candidates of size 4
 product xs  =  foldr (*) 1 xs
 
diff --git a/eg/list.hs b/eg/list.hs
--- a/eg/list.hs
+++ b/eg/list.hs
@@ -3,7 +3,6 @@
 -- Copyright (C) 2021 Rudy Matela
 -- Distributed under the 3-Clause BSD licence (see the file LICENSE).
 import Conjure
-import Data.List (insert)
 
 length' :: [Int] -> Int
 length' []       =  0
@@ -61,16 +60,6 @@
     , prim "null" (null :: [Int] -> Bool)
     ]
 
-  -- sort xs  =  if null xs then [] else insert (head xs) (sort (tail xs))
-  --             1  2    3       4       5       6    7    8     9    10
-  conjure "sort" sort'
-    [ pr ([] :: [Int])
-    , prim "insert" (insert :: Int -> [Int] -> [Int])
-    , prim "head" (head :: [Int] -> Int)
-    , prim "tail" (tail :: [Int] -> [Int])
-    , prim "null" (null :: [Int] -> Bool)
-    ]
-
   -- xs ++ ys  =  if null xs then ys else head xs:(tail xs ++ ys)
   --              1  2    3       4       5    6 7  8   9  10 11
   conjure "++" (+++)
@@ -102,14 +91,6 @@
     -- these last two are cheats:
     , prim "flip" (flip :: ([Int]->[Int]->[Int]) -> [Int] -> [Int] -> [Int])
     , prim "." ((.) :: ([Int]->[Int]->[Int]) -> (Int->[Int]) -> Int -> [Int] -> [Int])
-    ]
-
-  -- now through fold
-  -- sort xs  =  foldr insert [] xs
-  conjure "sort" sort'
-    [ pr ([] :: [Int])
-    , prim "insert" (insert :: Int -> [Int] -> [Int])
-    , prim "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])
     ]
 
   -- now through fold
diff --git a/eg/list.out b/eg/list.out
--- a/eg/list.out
+++ b/eg/list.out
@@ -1,118 +1,79 @@
 length :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 4/8 rules
 -- looking through 2 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 0 candidates of size 6
--- looking through 5 candidates of size 7
--- looking through 8 candidates of size 8
--- looking through 23 candidates of size 9
-length xs  =  if null xs then 0 else 1 + length (tail xs)
+-- looking through 4 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 13 candidates of size 4
+-- looking through 10 candidates of size 5
+length []  =  0
+length (x:xs)  =  length xs + 1
 
 reverse :: [Int] -> [Int]
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 12/13 rules
 -- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 5 candidates of size 3
--- looking through 9 candidates of size 4
--- looking through 23 candidates of size 5
--- looking through 57 candidates of size 6
--- looking through 147 candidates of size 7
--- looking through 381 candidates of size 8
--- looking through 1014 candidates of size 9
--- looking through 2736 candidates of size 10
--- looking through 7451 candidates of size 11
-reverse xs  =  if null xs then xs else reverse (tail xs) ++ unit (head xs)
-
-sort :: [Int] -> [Int]
--- testing 60 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 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 11 candidates of size 5
--- looking through 21 candidates of size 6
--- looking through 49 candidates of size 7
--- looking through 119 candidates of size 8
--- looking through 272 candidates of size 9
--- looking through 625 candidates of size 10
-sort xs  =  if null xs then xs else insert (head xs) (sort (tail xs))
+-- looking through 3 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 24 candidates of size 4
+-- looking through 60 candidates of size 5
+-- looking through 152 candidates of size 6
+reverse []  =  []
+reverse (x:xs)  =  reverse xs ++ unit x
 
 (++) :: [Int] -> [Int] -> [Int]
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 4/4 rules
 -- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 30 candidates of size 6
--- looking through 66 candidates of size 7
--- looking through 225 candidates of size 8
--- looking through 723 candidates of size 9
--- looking through 1965 candidates of size 10
--- looking through 5544 candidates of size 11
-xs ++ ys  =  if null xs then ys else head xs:(tail xs ++ ys)
+-- looking through 11 candidates of size 2
+-- looking through 38 candidates of size 3
+-- looking through 136 candidates of size 4
+-- looking through 517 candidates of size 5
+-- looking through 1606 candidates of size 6
+[] ++ xs  =  xs
+(x:xs) ++ ys  =  x:(xs ++ ys)
 
 length :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 6/10 rules
 -- looking through 2 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 1 candidates of size 5
--- looking through 7 candidates of size 6
-length xs  =  foldr (const (1 +)) 0 xs
+-- looking through 4 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 13 candidates of size 4
+-- looking through 16 candidates of size 5
+length []  =  0
+length (x:xs)  =  length xs + 1
 
 reverse :: [Int] -> [Int]
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 6/6 rules
 -- looking through 2 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 8 candidates of size 6
--- looking through 13 candidates of size 7
-reverse xs  =  foldr (flip (++) . unit) [] xs
-
-sort :: [Int] -> [Int]
--- testing 60 combinations of argument values
--- pruning with 1/2 rules
--- looking through 2 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
+-- looking through 1 candidates of size 2
+-- looking through 3 candidates of size 3
 -- looking through 2 candidates of size 4
-sort xs  =  foldr insert [] xs
+-- looking through 5 candidates of size 5
+-- looking through 15 candidates of size 6
+reverse []  =  []
+reverse (x:xs)  =  reverse xs ++ unit x
 
 (++) :: [Int] -> [Int] -> [Int]
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 2/2 rules
 -- looking through 3 candidates of size 1
--- looking through 0 candidates of size 2
--- looking through 0 candidates of size 3
--- looking through 4 candidates of size 4
+-- looking through 8 candidates of size 2
+-- looking through 11 candidates of size 3
+-- looking through 48 candidates of size 4
 xs ++ ys  =  foldr (:) ys xs
 
 (\/) :: [Int] -> [Int] -> [Int]
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 4/4 rules
 -- looking through 3 candidates of size 1
--- looking through 3 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 12 candidates of size 4
--- looking through 21 candidates of size 5
--- looking through 30 candidates of size 6
--- looking through 66 candidates of size 7
--- looking through 225 candidates of size 8
--- looking through 723 candidates of size 9
--- looking through 1965 candidates of size 10
--- looking through 5544 candidates of size 11
-xs \/ ys  =  if null xs then xs else head xs:ys \/ tail xs
+-- looking through 11 candidates of size 2
+-- looking through 38 candidates of size 3
+-- looking through 136 candidates of size 4
+-- looking through 517 candidates of size 5
+-- looking through 1606 candidates of size 6
+[] \/ xs  =  xs
+(x:xs) \/ ys  =  x:ys \/ xs
 
diff --git a/eg/pow.hs b/eg/pow.hs
new file mode 100644
--- /dev/null
+++ b/eg/pow.hs
@@ -0,0 +1,42 @@
+-- pow.hs: conjuring exponentiation
+--
+-- Copyright (C) 2021 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+
+pow :: Int -> Int -> Int
+pow 2 0  =  1
+pow 2 1  =  2
+pow 2 2  =  4
+pow 2 3  =  8
+pow 3 2  =  9
+
+main :: IO ()
+main  =  do
+  -- pow b e  =  if e == 0 then 1 else b * pow b (dec e)
+  --             1  2  3 4      5      6 7 8   9  10 11
+  -- somehow the above takes 30s to run, the two arguments
+  -- of the same type introduce the difficulty here.
+  -- with cases below, runtime is ok:
+  conjureWithMaxSize 8 "pow" pow
+    [ pr (0::Int)
+    , pr (1::Int)
+    , prim "*" ((*) :: Int -> Int -> Int)
+    , prim "dec" (subtract 1 :: Int -> Int)
+    ]
+
+  -- pow b e  =  if e == 0 then 1 else pow b (halve e) * pow b (halve e) * if odd e then b else 1
+  --             1  2  3 4      5      6   7  8     9 10 11 12  13   14 15 16 17  18    19     20
+  -- -- OR --
+  -- pow b 0  =  1
+  -- pow b e  =  pow b (halve e) * pow b (halve e) * if odd e then b else 1
+  --             2   3  4     5  6 7   8  9    10 11 12 13 14     15     16
+  -- out of reach performance wise, OOM at size 9
+  conjureWithMaxSize 6 "pow" pow
+    [ pr (0::Int)
+    , pr (1::Int)
+--  , prim "sq" ((\x -> x*x) :: Int -> Int) -- cheat! OOM still
+    , prim "*" ((*) :: Int -> Int -> Int)
+    , prim "halve" ((`div` 2) :: Int -> Int)
+    , prif (undefined :: Int)
+    ]
diff --git a/eg/pow.out b/eg/pow.out
new file mode 100644
--- /dev/null
+++ b/eg/pow.out
@@ -0,0 +1,24 @@
+pow :: Int -> Int -> Int
+-- testing 5 combinations of argument values
+-- pruning with 8/12 rules
+-- looking through 4 candidates of size 1
+-- looking through 21 candidates of size 2
+-- looking through 129 candidates of size 3
+-- looking through 517 candidates of size 4
+-- looking through 2346 candidates of size 5
+-- looking through 8550 candidates of size 6
+-- looking through 32487 candidates of size 7
+pow x 0  =  1
+pow x y  =  x * pow x (dec y)
+
+pow :: Int -> Int -> Int
+-- testing 5 combinations of argument values
+-- pruning with 15/19 rules
+-- looking through 4 candidates of size 1
+-- looking through 20 candidates of size 2
+-- looking through 114 candidates of size 3
+-- looking through 376 candidates of size 4
+-- looking through 1714 candidates of size 5
+-- looking through 4706 candidates of size 6
+cannot conjure
+
diff --git a/eg/replicate.hs b/eg/replicate.hs
--- a/eg/replicate.hs
+++ b/eg/replicate.hs
@@ -28,27 +28,26 @@
   conjure "replicate" replicate'
     [ pr (0 :: Int)
     , prim "dec" (subtract 1 :: Int -> Int)
-    , prim "==" ((==) :: Int -> Int -> Bool)
     , pr ""
     , prim ":" ((:) :: Char -> String -> String)
     ]
 
   -- emulates how MagicHaskeller generates "replicates"
-  conjureWith args{maxTests=360} "replicates" replicates'
+  conjure "replicates" replicates'
     [ prim "replicate" (replicate :: Int -> String -> [String])
     , prim "transpose" (transpose :: [[Char]] -> [[Char]])
     , prim "concat"    (concat :: [String] -> String)
     ]
 
   -- emulates an alternative generation that works on MagicHaskeller
-  conjureWith args{maxTests=360} "replicates" replicates'
+  conjure "replicates" replicates'
     [ prim "replicate" (replicate :: Int -> Char -> String)
     , prim "map"       (map :: (Char -> String) -> String -> [String])
     , prim "concat"    (concat :: [String] -> String)
     ]
 
   -- alternative generation using recursion
-  conjureWith args{maxTests=360, maxSize=13} "replicates" replicates'
+  conjureWith args{maxSize=13} "replicates" replicates'
     [ pr ""
     , prim "null" (null :: String -> Bool)
     , prim "head" (head :: String -> Char)
diff --git a/eg/replicate.out b/eg/replicate.out
--- a/eg/replicate.out
+++ b/eg/replicate.out
@@ -1,18 +1,15 @@
 replicate :: Int -> Char -> [Char]
--- testing 60 combinations of argument values
--- pruning with 6/7 rules
+-- 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 1 candidates of size 3
--- looking through 0 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 0 candidates of size 8
--- looking through 3 candidates of size 9
--- looking through 4 candidates of size 10
--- looking through 11 candidates of size 11
-replicate x c  =  if x == 0 then "" else c:replicate (dec x) c
+-- 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
+replicate 0 c  =  ""
+replicate x c  =  c:replicate (dec x) c
 
 replicates :: [Char] -> Int -> [Char]
 -- testing 360 combinations of argument values
@@ -38,17 +35,13 @@
 -- testing 360 combinations of argument values
 -- pruning with 9/14 rules
 -- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 13 candidates of size 4
--- looking through 28 candidates of size 5
--- looking through 67 candidates of size 6
--- looking through 197 candidates of size 7
--- looking through 523 candidates of size 8
--- looking through 1430 candidates of size 9
--- looking through 4072 candidates of size 10
--- looking through 11488 candidates of size 11
--- looking through 32782 candidates of size 12
--- looking through 94734 candidates of size 13
-replicates cs x  =  if null cs then cs else replicate x (head cs) ++ replicates (tail cs) x
+-- looking through 3 candidates of size 2
+-- looking through 7 candidates of size 3
+-- looking through 24 candidates of size 4
+-- looking through 64 candidates of size 5
+-- looking through 161 candidates of size 6
+-- looking through 469 candidates of size 7
+-- looking through 1303 candidates of size 8
+replicates "" x  =  ""
+replicates (c:cs) x  =  replicate x c ++ replicates cs x
 
diff --git a/eg/setelem.out b/eg/setelem.out
--- a/eg/setelem.out
+++ b/eg/setelem.out
@@ -1,36 +1,28 @@
 elem :: Int -> [Int] -> Bool
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 44/57 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
--- looking through 14 candidates of size 5
--- looking through 25 candidates of size 6
--- looking through 60 candidates of size 7
--- looking through 145 candidates of size 8
--- looking through 332 candidates of size 9
--- looking through 747 candidates of size 10
--- looking through 1826 candidates of size 11
--- looking through 4411 candidates of size 12
--- looking through 10932 candidates of size 13
-elem x xs  =  not (null xs) && (head xs == x || elem x (tail xs))
+-- looking through 3 candidates of size 2
+-- looking through 5 candidates of size 3
+-- looking through 28 candidates of size 4
+-- looking through 73 candidates of size 5
+-- looking through 119 candidates of size 6
+-- looking through 277 candidates of size 7
+-- looking through 895 candidates of size 8
+elem x []  =  False
+elem x (y:xs)  =  x == y || elem x xs
 
 set :: [Int] -> Bool
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 46/57 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 5 candidates of size 4
--- looking through 11 candidates of size 5
--- looking through 26 candidates of size 6
--- looking through 64 candidates of size 7
--- looking through 145 candidates of size 8
--- looking through 310 candidates of size 9
--- looking through 721 candidates of size 10
--- looking through 1762 candidates of size 11
--- looking through 4235 candidates of size 12
--- looking through 10038 candidates of size 13
-set xs  =  null xs || not (elem (head xs) (tail xs)) && set (tail xs)
+-- looking through 3 candidates of size 2
+-- looking through 7 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 35 candidates of size 5
+-- looking through 81 candidates of size 6
+-- looking through 229 candidates of size 7
+-- looking through 546 candidates of size 8
+set []  =  True
+set (x:xs)  =  not (elem x xs) && set xs
 
diff --git a/eg/sort.hs b/eg/sort.hs
new file mode 100644
--- /dev/null
+++ b/eg/sort.hs
@@ -0,0 +1,82 @@
+-- sort.hs: conjuring a sort function
+--
+-- Copyright (C) 2021 Rudy Matela
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+import Conjure
+import Data.List (insert, sort)
+
+sort' :: [Int] -> [Int]
+sort' []       =  []
+sort' [x]      =  [x]
+sort' [x,y]
+  | x <= y     =  [x,y]
+  | otherwise  =  [y,x]
+sort' [x,y,z]
+  | x <= y && y <= z  =  [x,y,z]
+  | x <= z && z <= y  =  [x,z,y]
+  | y <= x && x <= z  =  [y,x,z]
+  | y <= z && z <= x  =  [y,z,x]
+  | z <= x && x <= y  =  [z,x,y]
+  | z <= y && y <= x  =  [z,y,x]
+
+merge' :: [Int] -> [Int] -> [Int]
+merge' xs ys  =  sort (xs ++ ys)
+
+main :: IO ()
+main = do
+  -- recursive insertion sort
+  -- sort xs  =  if null xs then [] else insert (head xs) (sort (tail xs))
+  --             1  2    3       4       5       6    7    8     9    10
+  -- -- OR --
+  -- sort []  =  []
+  -- sort (x:xs)  =  insert x (sort xs)
+  conjure "sort" sort'
+    [ pr ([] :: [Int])
+    , prim "insert" (insert :: Int -> [Int] -> [Int])
+    , prim "head" (head :: [Int] -> Int)
+    , prim "tail" (tail :: [Int] -> [Int])
+    , prim "null" (null :: [Int] -> Bool)
+    ]
+
+  -- now through fold
+  -- sort xs  =  foldr insert [] xs
+  conjure "sort" sort'
+    [ pr ([] :: [Int])
+    , prim "insert" (insert :: Int -> [Int] -> [Int])
+    , prim "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])
+    ]
+
+  -- qsort
+  -- qsort xs  =  if null xs                                 --  3
+  --              then []                                    --  4
+  --              else qsort (filter (< head xs) (tail xs))  -- 11
+  --                ++ (head xs:[])                          -- 16
+  --                ++ qsort (filter (>= head xs) (tail xs)) -- 24
+  -- not only this is out of reach performance wise,
+  -- but the needed recursive calls will not be enumerated
+  -- -- OR --
+  -- qsort []  =  []                           -- 1
+  -- qsort (x:xs)  =  qsort (filter (x >) xs)  -- 6
+  --            ++ (x:qsort (filter (x <=) xs) -- 14
+  -- this one is not out of reach performance wise,
+  -- but is not generated because of the deconstruction restriction.
+  -- The following does generate a correct but inneficient version of qsort.
+  conjureWith args{maxSize=14} "qsort" sort'
+    [ pr ([] :: [Int])
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "++" ((++) :: [Int] -> [Int] -> [Int])
+    , prim "<=" ((<=) :: Int -> Int -> Bool)
+    , prim ">"  ((>)  :: Int -> Int -> Bool)
+    , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])
+    ]
+
+  -- merge [] []  =  []
+  -- merge (x:xs) (y:ys)  =  if x <= y then x:merge xs (y:ys) else y:merge (x:xs) ys
+  --                         2  3 4  5      678     9 10 11 12  13 14 15  16 17 18 19
+  -- OOM after size 17, out of reach performance wise
+  conjureWith args{maxSize=12} "merge" merge'
+    [ pr ([] :: [Int])
+    , prim ":" ((:) :: Int -> [Int] -> [Int])
+    , prim "<=" ((<=) :: Int -> Int -> Bool)
+    , prif (undefined :: [Int])
+    ]
diff --git a/eg/sort.out b/eg/sort.out
new file mode 100644
--- /dev/null
+++ b/eg/sort.out
@@ -0,0 +1,57 @@
+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 7 candidates of size 3
+-- looking through 16 candidates of size 4
+-- looking through 36 candidates of size 5
+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
+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
+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 44 candidates of size 4
+-- looking through 116 candidates of size 5
+-- looking through 80 candidates of size 6
+-- looking through 719 candidates of size 7
+-- looking through 164 candidates of size 8
+-- looking through 3360 candidates of size 9
+-- looking through 1448 candidates of size 10
+-- looking through 12905 candidates of size 11
+-- looking through 15208 candidates of size 12
+cannot conjure
+
diff --git a/eg/spec.out b/eg/spec.out
--- a/eg/spec.out
+++ b/eg/spec.out
@@ -2,30 +2,22 @@
 -- 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 1 candidates of size 3
--- looking through 1 candidates of size 4
--- looking through 2 candidates of size 5
--- looking through 2 candidates of size 6
--- looking through 5 candidates of size 7
--- looking through 10 candidates of size 8
--- looking through 17 candidates of size 9
--- looking through 30 candidates of size 10
-sum xs  =  if null xs then 0 else head xs + sum (tail xs)
+-- looking through 2 candidates of size 2
+-- looking through 3 candidates of size 3
+-- looking through 4 candidates of size 4
+-- looking through 7 candidates of size 5
+sum []  =  0
+sum (x:xs)  =  x + sum xs
 
 (++) :: [Int] -> [Int] -> [Int]
 -- testing 3 combinations of argument values
 -- pruning with 3/3 rules
 -- looking through 2 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 6 candidates of size 4
--- looking through 10 candidates of size 5
--- looking through 14 candidates of size 6
--- looking through 26 candidates of size 7
--- looking through 94 candidates of size 8
--- looking through 298 candidates of size 9
--- looking through 766 candidates of size 10
--- looking through 2010 candidates of size 11
-xs ++ ys  =  if null xs then ys else head xs:(tail xs ++ ys)
+-- looking through 4 candidates of size 2
+-- looking through 10 candidates of size 3
+-- looking through 28 candidates of size 4
+-- looking through 78 candidates of size 5
+-- looking through 172 candidates of size 6
+[] ++ 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
@@ -43,18 +43,20 @@
 main = do
   -- subset xs ys  =  null xs || elem (head xs) ys && subset (tail xs) ys
   --                  1    2  3  4     5    6   7  8  9       10   11  12
+  -- -- OR --
+  -- subset [] ys  =  True
+  -- subset (x:xs) ys  =  elem x ys && subset xs ys
   conjure "subset" (subset')
     [ pr ([] :: [Int])
+    , pr True
+    , pr False
     , prim "&&" (&&)
     , prim "||" (||)
-    , prim "head" (head :: [Int] -> Int)
-    , prim "tail" (tail :: [Int] -> [Int])
-    , prim "null" (null :: [Int] -> Bool)
     , prim "elem" (elem :: Int -> [Int] -> Bool)
     ]
 
   -- subset xs ys  =  sort xs `isSubsequenceOf` sort ys
-  conjureWith args{maxTests=360} "subset" (subset')
+  conjure "subset" (subset')
     [ prim "sort" (sort :: [Int] -> [Int])
     , prim "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)
     ]
diff --git a/eg/subset.out b/eg/subset.out
--- a/eg/subset.out
+++ b/eg/subset.out
@@ -1,19 +1,16 @@
 subset :: [Int] -> [Int] -> Bool
 -- testing 44 combinations of argument values
--- pruning with 30/40 rules
--- looking through 0 candidates of size 1
--- looking through 2 candidates of size 2
--- looking through 3 candidates of size 3
--- looking through 9 candidates of size 4
--- looking through 22 candidates of size 5
--- looking through 47 candidates of size 6
--- looking through 132 candidates of size 7
--- looking through 323 candidates of size 8
--- looking through 854 candidates of size 9
--- looking through 2421 candidates of size 10
--- looking through 6452 candidates of size 11
--- looking through 17815 candidates of size 12
-subset xs ys  =  null xs || elem (head xs) ys && subset (tail xs) ys
+-- pruning with 29/39 rules
+-- looking through 2 candidates of size 1
+-- looking through 4 candidates of size 2
+-- looking through 14 candidates of size 3
+-- looking through 40 candidates of size 4
+-- looking through 160 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 448 candidates of size 7
+-- looking through 784 candidates of size 8
+subset [] xs  =  True
+subset (x:xs) ys  =  elem x ys && subset xs ys
 
 subset :: [Int] -> [Int] -> Bool
 -- testing 44 combinations of argument values
diff --git a/eg/tapps.out b/eg/tapps.out
--- a/eg/tapps.out
+++ b/eg/tapps.out
@@ -1,33 +1,29 @@
 third :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
 third xs  =  head (tail (tail xs))
 
 product :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 14/25 rules
 -- looking through 2 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 2 candidates of size 3
--- looking through 2 candidates of size 4
--- looking through 5 candidates of size 5
--- looking through 5 candidates of size 6
--- looking through 15 candidates of size 7
--- looking through 27 candidates of size 8
--- looking through 57 candidates of size 9
--- looking through 119 candidates of size 10
-product xs  =  if null xs then 1 else head xs * product (tail xs)
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 31 candidates of size 5
+product []  =  1
+product (x:xs)  =  x * product xs
 
 product :: [Int] -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 15/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 5 candidates of size 4
+-- looking through 5 candidates of size 2
+-- looking through 6 candidates of size 3
+-- looking through 22 candidates of size 4
 product xs  =  foldr (*) 1 xs
 
diff --git a/eg/tree.hs b/eg/tree.hs
--- a/eg/tree.hs
+++ b/eg/tree.hs
@@ -77,6 +77,9 @@
   tiers  =  cons0 Leaf
         \/  cons3 Node
 
+instance Name Tree where
+  name _  =  "t1"
+
 instance Conjurable Tree where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
@@ -92,17 +95,15 @@
 main :: IO ()
 main = do
   conjure "leftmost" leftmost
-    [ prim "valu" valu
+    [ prim "undefined" (undefined :: Int)
+    , prim "if" (\p x y -> if p then x else y :: Int)
     , prim "nil" nil
-    , prim "left" left
-    , prim "right" right
     ]
 
   conjure "rightmost" rightmost
-    [ prim "valu" valu
+    [ prim "undefined" (undefined :: Int)
+    , prim "if" (\p x y -> if p then x else y :: Int)
     , prim "nil" nil
-    , prim "left" left
-    , prim "right" right
     ]
 
   conjureWithMaxSize 13 "size" size
@@ -130,24 +131,16 @@
     [ pr False
     , prim "||" (||)
     , prim "==" ((==) :: Int -> Int -> Bool)
-    , prim "nil" nil
-    , prim "left" left
-    , prim "right" right
-    , prim "valu" valu
     ]
 
   -- simply out of reach performance-wise (size 34)
-  conjureWithMaxSize 9 "insert" mem
+  conjureWithMaxSize 12 "insert" insert
     [ pr Leaf
     , prim "Node" Node
-    , prim "left" left
-    , prim "right" right
-    , prim "valu" valu
-    , prim "nil" nil
-    , prim "unit" unit
     , prim "==" ((==) :: Int -> Int -> Bool)
     , prim "<" ((<) :: Int -> Int -> Bool)
     , prim ">" ((>) :: Int -> Int -> Bool)
+    , prim "if" (\p t1 t2 -> if p then t1 else t2 :: Tree)
     ]
 
 
diff --git a/eg/tree.out b/eg/tree.out
--- a/eg/tree.out
+++ b/eg/tree.out
@@ -1,95 +1,89 @@
 leftmost :: Tree -> Int
--- testing 60 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
+-- 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 4 candidates of size 4
--- looking through 8 candidates of size 5
--- looking through 16 candidates of size 6
--- looking through 32 candidates of size 7
--- looking through 68 candidates of size 8
--- looking through 152 candidates of size 9
-leftmost x  =  if nil (left x) then valu x else leftmost (left x)
+-- 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
+leftmost Leaf  =  undefined
+leftmost (Node t1 x t2)  =  if nil t1 then x else leftmost t1
 
 rightmost :: Tree -> Int
--- testing 60 combinations of argument values
--- pruning with 0/0 rules
--- looking through 0 candidates of size 1
+-- 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 4 candidates of size 4
--- looking through 8 candidates of size 5
--- looking through 16 candidates of size 6
--- looking through 32 candidates of size 7
--- looking through 68 candidates of size 8
--- looking through 152 candidates of size 9
-rightmost x  =  if nil (right x) then valu x else rightmost (right x)
+-- 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
+rightmost Leaf  =  undefined
+rightmost (Node t1 x t2)  =  if nil t2 then x else rightmost t2
 
 size :: Tree -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 4/8 rules
 -- looking through 2 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 0 candidates of size 6
--- looking through 9 candidates of size 7
--- looking through 32 candidates of size 8
--- looking through 117 candidates of size 9
--- looking through 336 candidates of size 10
--- looking through 933 candidates of size 11
--- looking through 2416 candidates of size 12
--- looking through 6113 candidates of size 13
-size x  =  if nil x then 0 else 1 + (size (left x) + size (right x))
+-- looking through 4 candidates of size 2
+-- looking through 5 candidates of size 3
+-- looking through 19 candidates of size 4
+-- looking through 35 candidates of size 5
+-- looking through 66 candidates of size 6
+-- looking through 163 candidates of size 7
+-- looking through 311 candidates of size 8
+size Leaf  =  0
+size (Node t1 x t2)  =  size t1 + (size t2 + 1)
 
 height :: Tree -> Int
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 49/65 rules
 -- looking through 3 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 2 candidates of size 5
--- looking through 0 candidates of size 6
--- looking through 21 candidates of size 7
--- looking through 48 candidates of size 8
--- looking through 299 candidates of size 9
--- looking through 896 candidates of size 10
--- looking through 3137 candidates of size 11
--- looking through 8672 candidates of size 12
--- looking through 26088 candidates of size 13
-height x  =  if nil x then -1 else 1 + max (height (left x)) (height (right x))
+-- looking through 9 candidates of size 2
+-- looking through 8 candidates of size 3
+-- looking through 59 candidates of size 4
+-- looking through 114 candidates of size 5
+-- looking through 388 candidates of size 6
+-- looking through 1255 candidates of size 7
+-- looking through 3833 candidates of size 8
+height Leaf  =  -1
+height (Node t1 x t2)  =  1 + max (height t1) (height t2)
 
 mem :: Int -> Tree -> Bool
--- testing 60 combinations of argument values
+-- testing 360 combinations of argument values
 -- pruning with 11/17 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 2
+-- looking through 0 candidates of size 3
 -- looking through 6 candidates of size 4
--- looking through 12 candidates of size 5
--- looking through 28 candidates of size 6
--- looking through 64 candidates of size 7
--- looking through 156 candidates of size 8
--- looking through 376 candidates of size 9
--- looking through 930 candidates of size 10
--- looking through 2302 candidates of size 11
--- looking through 5760 candidates of size 12
-cannot conjure
+-- looking through 0 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 0 candidates of size 7
+-- looking through 34 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 184 candidates of size 12
+mem x Leaf  =  False
+mem x (Node t1 y t2)  =  mem x t1 || (x == y || mem x t2)
 
-insert :: Int -> Tree -> Bool
--- testing 60 combinations of argument values
--- pruning with 9/10 rules
--- looking through 0 candidates of size 1
--- looking through 1 candidates of size 2
--- looking through 4 candidates of size 3
--- looking through 16 candidates of size 4
--- looking through 36 candidates of size 5
--- looking through 90 candidates of size 6
--- looking through 205 candidates of size 7
--- looking through 497 candidates of size 8
--- looking through 1199 candidates of size 9
+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 10 candidates of size 4
+-- looking through 21 candidates of size 5
+-- looking through 0 candidates of size 6
+-- looking through 118 candidates of size 7
+-- looking through 239 candidates of size 8
+-- looking through 216 candidates of size 9
+-- looking through 2204 candidates of size 10
+-- looking through 3651 candidates of size 11
+-- looking through 8280 candidates of size 12
 cannot conjure
 
diff --git a/mk/depend.mk b/mk/depend.mk
--- a/mk/depend.mk
+++ b/mk/depend.mk
@@ -16,6 +16,19 @@
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   bench/candidates.hs
+bench/gps: \
+  bench/gps.hs \
+  mk/toplibs
+bench/gps.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Spec.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  bench/gps.hs
 bench/ill-hit: \
   bench/ill-hit.hs \
   mk/toplibs
@@ -42,6 +55,19 @@
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   bench/longshot.hs
+bench/lowtests: \
+  bench/lowtests.hs \
+  mk/toplibs
+bench/lowtests.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Spec.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  bench/lowtests.hs
 bench/p12: \
   bench/p12.hs \
   mk/toplibs
@@ -133,6 +159,19 @@
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   eg/count.hs
+eg/dupos: \
+  eg/dupos.hs \
+  mk/toplibs
+eg/dupos.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Spec.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  eg/dupos.hs
 eg/factorial: \
   eg/factorial.hs \
   mk/toplibs
@@ -146,6 +185,19 @@
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   eg/factorial.hs
+eg/fib01: \
+  eg/fib01.hs \
+  mk/toplibs
+eg/fib01.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Spec.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  eg/fib01.hs
 eg/fibonacci: \
   eg/fibonacci.hs \
   mk/toplibs
@@ -198,6 +250,19 @@
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   eg/list.hs
+eg/pow: \
+  eg/pow.hs \
+  mk/toplibs
+eg/pow.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Spec.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  eg/pow.hs
 eg/replicate: \
   eg/replicate.hs \
   mk/toplibs
@@ -224,6 +289,19 @@
   src/Conjure/Defn.hs \
   src/Conjure/Conjurable.hs \
   eg/setelem.hs
+eg/sort: \
+  eg/sort.hs \
+  mk/toplibs
+eg/sort.o: \
+  src/Conjure/Utils.hs \
+  src/Conjure/Spec.hs \
+  src/Conjure/Prim.hs \
+  src/Conjure.hs \
+  src/Conjure/Expr.hs \
+  src/Conjure/Engine.hs \
+  src/Conjure/Defn.hs \
+  src/Conjure/Conjurable.hs \
+  eg/sort.hs
 eg/spec: \
   eg/spec.hs \
   mk/toplibs
diff --git a/src/Conjure.hs b/src/Conjure.hs
--- a/src/Conjure.hs
+++ b/src/Conjure.hs
@@ -34,9 +34,10 @@
 -- > > conjure "square" square primitives
 -- > square :: Int -> Int
 -- > -- testing 3 combinations of argument values
+-- > -- pruning with 14/25 rules
 -- > -- looking through 3 candidates of size 1
--- > -- looking through 3 candidates of size 2
--- > -- looking through 5 candidates of size 3
+-- > -- looking through 4 candidates of size 2
+-- > -- looking through 9 candidates of size 3
 -- > square x  =  x * x
 {-# LANGUAGE CPP #-}
 module Conjure
@@ -46,6 +47,7 @@
   , Prim
   , pr
   , prim
+  , prif
 
 -- * Advanced use
   , conjureWithMaxSize
diff --git a/src/Conjure/Conjurable.hs b/src/Conjure/Conjurable.hs
--- a/src/Conjure/Conjurable.hs
+++ b/src/Conjure/Conjurable.hs
@@ -30,6 +30,9 @@
   , conjureIsUnbreakable
   , conjureReification
   , conjureReification1
+  , cevaluate
+  , ceval
+  , cevl
   )
 where
 
@@ -51,7 +54,7 @@
 -- | Single reification of some functions over a type as 'Expr's.
 --
 -- A hole, an equality function and tiers.
-type Reification1  =  (Expr, Maybe Expr, Maybe [[Expr]], Bool)
+type Reification1  =  (Expr, Maybe Expr, Maybe [[Expr]], [String], Bool, Expr)
 
 -- | A reification over a collection of types.
 --
@@ -113,7 +116,7 @@
 -- Please see the source code of "Conjure.Conjurable" for more examples.
 --
 -- (cf. 'reifyTiers', 'reifyEquality', 'conjureType')
-class Typeable a => Conjurable a where
+class (Typeable a, Name a) => Conjurable a where
   conjureArgumentHoles :: a -> [Expr]
   conjureArgumentHoles _  =  []
 
@@ -139,23 +142,29 @@
   conjureArgumentCases :: a -> [[Expr]]
   conjureArgumentCases _  =  []
 
+  conjureSize :: a -> Int
+  conjureSize _  =  0
+
   conjureExpress :: a -> Expr -> Expr
 
+  conjureEvaluate :: (Expr->Expr) -> Int -> Defn -> Expr -> Maybe a
+  conjureEvaluate  =  devaluate
 
+
 conjureType :: Conjurable a => a -> Reification
 conjureType x ms  =
-  if hole x `elem` [h | (h,_,_,_) <- ms]
+  if hole x `elem` [h | (h,_,_,_,_,_) <- ms]
   then ms
   else conjureSubTypes x $ conjureReification1 x : ms
 
 -- | like 'conjureType' but without type repetitions
 nubConjureType :: Conjurable a => a -> Reification
-nubConjureType x  =  nubOn (\(eh,_,_,_) -> eh) . conjureType x
+nubConjureType x  =  nubOn (\(eh,_,_,_,_,_) -> eh) . conjureType x
 -- The use of nubOn above is O(n^2).
 -- So long as there is not a huge number of subtypes of a, so we're fine.
 
 conjureReification1 :: Conjurable a => a -> Reification1
-conjureReification1 x  =  (hole x, conjureEquality x, conjureTiers x, null $ conjureCases x)
+conjureReification1 x  =  (hole x, conjureEquality x, conjureTiers x, names x, null $ conjureCases x, value "conjureSize" (conjureSize -:> x))
 
 conjureReification :: Conjurable a => a -> [Reification1]
 conjureReification x  =  nubConjureType x [conjureReification1 bool]
@@ -198,10 +207,10 @@
 mkExprTiers a  =  mapT val (tiers -: [[a]])
 
 conjureHoles :: Conjurable f => f -> [Expr]
-conjureHoles f  =  [eh | (eh,_,Just _,_) <- conjureReification f]
+conjureHoles f  =  [eh | (eh,_,Just _,_,_,_) <- conjureReification f]
 
 conjureMkEquation :: Conjurable f => f -> Expr -> Expr -> Expr
-conjureMkEquation f  =  mkEquation [eq | (_,Just eq,_,_) <- conjureReification f]
+conjureMkEquation f  =  mkEquation [eq | (_,Just eq,_,_,_,_) <- conjureReification f]
 
 conjureAreEqual :: Conjurable f => f -> Int -> Expr -> Expr -> Bool
 conjureAreEqual f maxTests  =  (===)
@@ -215,20 +224,39 @@
 conjureTiersFor f e  =  tf allTiers
   where
   allTiers :: [ [[Expr]] ]
-  allTiers  =  [etiers | (_,_,Just etiers,_) <- conjureReification f]
+  allTiers  =  [etiers | (_,_,Just etiers,_,_,_) <- conjureReification f]
   tf []  =  [[e]] -- no tiers found, keep variable
   tf (etiers:etc)  =  case etiers of
                       ((e':_):_) | typ e' == typ e -> etiers
                       _                            -> tf etc
 
-conjureIsDeconstructor :: Conjurable f => f -> Int -> Expr -> Expr -> Expr -> Bool
-conjureIsDeconstructor f maxTests  =  isDeconstructionE
-                                   .  take maxTests
-                                   .  grounds (conjureTiersFor f)
+conjureNamesFor :: Conjurable f => f -> Expr -> [String]
+conjureNamesFor f e  =  head
+                     $  [ns | (eh, _, _, ns, _, _) <- conjureReification f, typ e == typ eh]
+                     ++ [names (undefined :: Int)] -- use [Int] on lists
 
+conjureMostGeneralCanonicalVariation :: Conjurable f => f -> Expr -> Expr
+conjureMostGeneralCanonicalVariation f  =  canonicalizeWith (conjureNamesFor f)
+                                        .  fastMostGeneralVariation
+
+conjureIsDeconstructor :: Conjurable f => f -> Int -> Expr -> Bool
+conjureIsDeconstructor f maxTests e  =  case as of
+  [] -> False
+  (h:_) -> isDec h
+  where
+  as  =  [h | h <- hs, isWellTyped (e:$h), typ (e:$h) == typ h]
+  hs  =  conjureArgumentHoles f
+  isDec h  =  count is gs >= length gs `div` 2
+    where
+    gs  =  take maxTests $ grounds (conjureTiersFor f) h
+    sz  =  head [sz | (_, _, _, _, _, sz) <- conjureReification f
+                    , isWellTyped (sz :$ h)]
+    esz e  =  eval (0::Int) (sz :$ e)
+    is e  =  esz (h :$ e) < esz e
+
 conjureIsUnbreakable :: Conjurable f => f -> Expr -> Bool
 conjureIsUnbreakable f e  =  head
-  [is | (h,_,_,is) <- conjureReification f, typ h == typ e]
+  [is | (h,_,_,_,is,_) <- conjureReification f, typ h == typ e]
 
 instance Conjurable () where
   conjureExpress   =  reifyExpress
@@ -246,11 +274,13 @@
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  abs
 
 instance Conjurable Integer where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Char where
   conjureExpress   =  reifyExpress
@@ -265,6 +295,7 @@
   conjureExpress   =  reifyExpress
   conjureSubTypes xs  =  conjureType (head xs)
   conjureTiers     =  reifyTiers
+  conjureSize      =  length
   conjureCases xs  =  [ val ([] -: xs)
                       , value ":" ((:) ->>: xs) :$ hole x :$ hole xs
                       ]  where  x  =  head xs
@@ -384,6 +415,15 @@
   conjureExpress f e
     | typ e == typeOf (argTy f)  =  conjureExpress (argTy f) e
     | otherwise                  =  conjureExpress (f undefined) e
+  conjureEvaluate exprExpr mx defn ef  =  mf
+    where
+    ce  =  conjureEvaluate exprExpr mx defn
+    mf  =  case ce (holeAsTypeOf ef :$ hole x) -: Just (f x) of
+           Nothing -> Nothing
+           Just _  -> Just $ \x -> fromMaybe err . ce $ ef :$ exprExpr (value "" x)
+    f  =  undefined -: fromJust mf
+    x  =  argTy f
+    err  =  error "conjureEvaluate (a->b): BUG!  This should never be evaluated as it is protected by the outer case."
 
 argTy :: (a -> b) -> a
 argTy _  =  undefined
@@ -391,6 +431,21 @@
 resTy :: (a -> b) -> b
 resTy _  =  undefined
 
+cevaluate :: Conjurable f => Int -> Defn -> Maybe f
+cevaluate mx defn  =  mr
+  where
+  mr  =  conjureEvaluate exprExpr mx defn ef'
+  exprExpr  =  conjureExpress $ fromJust mr
+  (ef':_)  =  unfoldApp . fst $ head defn
+
+ceval :: Conjurable f => Int -> f -> Defn -> f
+ceval mx z  =  fromMaybe z . cevaluate mx
+
+cevl :: Conjurable f => Int -> Defn -> f
+cevl mx  =  ceval mx err
+  where
+  err  =  error "cevl: type mismatch"
+
 conjureApplication :: Conjurable f => String -> f -> Expr
 conjureApplication  =  conjureWhatApplication value
 
@@ -404,8 +459,12 @@
   (nf:nas)  =  words nm ++ repeat ""
 
 conjurePats :: Conjurable f => [Expr] -> String -> f -> [[[Expr]]]
-conjurePats es nm f  =  mapT (map (foldApp . (ef:) . unfold . mostGeneralCanonicalVariation . fold) . prods) $ cs
+conjurePats es nm f  =  mapT (map mkApp . prods) $ cs
   where
+  mkApp  =  foldApp . (ef:)
+         .  unfold
+         .  conjureMostGeneralCanonicalVariation f
+         .  fold
   ef  =  var (head $ words nm) f  -- TODO: take the tail into account
   cs  =  products $ zipWith mk (conjureArgumentHoles f) (conjureArgumentCases f)
   mk h []  =  mapT (++ [h]) $ setsOf [[e] | e <- es, typ e == typ h]
@@ -429,67 +488,84 @@
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  round
 
 instance Conjurable Double where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  round
 
 instance Conjurable Int8 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Int16 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Int32 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Int64 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Word where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Word8 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Word16 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Word32 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable Word64 where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance (Integral a, Conjurable a, Listable a, Show a, Eq a, Express a) => Conjurable (Ratio a) where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize q    =  conjureSize (numerator q) + conjureSize (denominator q)
   conjureSubTypes q  =  conjureType (numerator q)
+  conjureCases q  =  [value "%" ((%) ->>: q) :$ hole n :$ hole d]
+    where
+    n  =  numerator q
+    d  =  denominator q
 
 instance (RealFloat a, Conjurable a, Listable a, Show a, Eq a, Express a) => Conjurable (Complex a) where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize x    =  conjureSize (realPart x) + conjureSize (imagPart x)
   conjureSubTypes x  =  conjureType (realPart x)
 
 
@@ -498,31 +574,37 @@
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable B where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable C where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable D where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable E where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 instance Conjurable F where
   conjureExpress   =  reifyExpress
   conjureEquality  =  reifyEquality
   conjureTiers     =  reifyTiers
+  conjureSize      =  fromIntegral . abs
 
 
 -- Conjurable tuples --
@@ -678,3 +760,10 @@
                                                         && t1 ......== t2
 
 -- TODO: go up to 12-tuples
+
+instance Name A
+instance Name B
+instance Name C
+instance Name D
+instance Name E
+instance Name F
diff --git a/src/Conjure/Defn.hs b/src/Conjure/Defn.hs
--- a/src/Conjure/Defn.hs
+++ b/src/Conjure/Defn.hs
@@ -41,50 +41,61 @@
   where
   show1 (lhs,rhs)  =  showExpr lhs ++ "  =  " ++ showExpr rhs
 
+type Memo  =  [(Expr, Maybe Dynamic)]
 
 -- | Evaluates an 'Expr' using the given 'Defn' as definition
 --   when a recursive call is found.
 toDynamicWithDefn :: (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe Dynamic
-toDynamicWithDefn exprExpr n cx  =  fmap (\(_,_,d) -> d) . re (n * sum (map (size . snd) cx)) n
+toDynamicWithDefn exprExpr mx cx  =  fmap (\(_,_,d) -> d) . re (mx * sum (map (size . snd) cx)) []
   where
   (ef':_)  =  unfoldApp . fst $ head cx
 
-  rev :: Typeable a => Int -> Int -> Expr -> Maybe (Int, Int, a)
-  rev m n e  =  case re m n e of
-                Nothing    -> Nothing
-                Just (m,n,d) -> case fromDynamic d of
-                                Nothing -> Nothing
-                                Just x  -> Just (m, n, x)
-
-  re :: Int -> Int -> Expr -> Maybe (Int, Int, Dynamic)
-  re m n _  | n <= 0  =  error "toDynamicWithDefn: recursion limit reached"
-  re m n _  | m <= 0  =  error "toDynamicWithDefn: evaluation limit reached"
-  re m n (Value "if" _ :$ ec :$ ex :$ ey)  =  case rev m n ec of
+  -- recursively evaluate an expression, the entry point
+  re :: Int -> Memo -> Expr -> Maybe (Int, Memo, Dynamic)
+  re n m _  | length m > mx  =  error "toDynamicWithDefn: recursion limit reached"
+  re n m _  | n <= 0  =  error "toDynamicWithDefn: evaluation limit reached"
+  re n m (Value "if" _ :$ ec :$ ex :$ ey)  =  case rev n m ec of
     Nothing    -> Nothing
-    Just (m,n,True)  -> re m n ex
-    Just (m,n,False) -> re m n ey
-  re m n (Value "||" _ :$ ep :$ eq)  =  case rev m n ep of
+    Just (n,m,True)  -> re n m ex
+    Just (n,m,False) -> re n m ey
+  re n m (Value "||" _ :$ ep :$ eq)  =  case rev n m ep of
     Nothing        -> Nothing
-    Just (m,n,True)  -> (m,n,) <$> toDynamic (val True)
-    Just (m,n,False) -> re m n eq
-  re m n (Value "&&" _ :$ ep :$ eq)  =  case rev m n ep of
+    Just (n,m,True)  -> (n,m,) <$> toDynamic (val True)
+    Just (n,m,False) -> re n m eq
+  re n m (Value "&&" _ :$ ep :$ eq)  =  case rev n m ep of
     Nothing    -> Nothing
-    Just (m,n,True)  -> re m n eq
-    Just (m,n,False) -> (m,n,) <$> toDynamic (val False)
-  re m n e  =  case unfoldApp e of
+    Just (n,m,True)  -> re n m eq
+    Just (n,m,False) -> (n,m,) <$> toDynamic (val False)
+  re n m e  =  case unfoldApp e of
     [] -> error "toDynamicWithDefn: empty application unfold"  -- should never happen
-    [e] -> (m-1,n,) <$> toDynamic e
-    (ef:exs) | ef == ef' -> headOr (error $ "toDynamicWithDefn: unhandled pattern " ++ show e)
-                          [ re m (n-1) $ e' //- bs
-                          | let e  =  foldApp (ef:map exprExpr exs)
-                          , (a',e') <- cx
-                          , Just bs <- [e `match` a']
-                          ]
-             | otherwise -> foldl ($$) (re m n ef) exs
+    [e] -> (n-1,m,) <$> toDynamic e
+    (ef:exs) | ef == ef' -> red n m (foldApp (ef:map exprExpr exs))
+             | otherwise -> foldl ($$) (re n m ef) exs
 
-  Just (m,n,d1) $$ e2  =  case re m n e2 of
+  -- like 're' but is bound to an actual Haskell value instead of a Dynamic
+  rev :: Typeable a => Int -> Memo -> Expr -> Maybe (Int, Memo, a)
+  rev n m e  =  case re n m e of
+                Nothing    -> Nothing
+                Just (n,m,d) -> case fromDynamic d of
+                                Nothing -> Nothing
+                                Just x  -> Just (n, m, x)
+
+  -- evaluates by matching on one of cases of the actual definition
+  -- should only be used to evaluate an expr of the form:
+  -- ef' :$ exprExpr ex :$ exprExpr ey :$ ...
+  red :: Int -> Memo -> Expr -> Maybe (Int, Memo, Dynamic)
+  red n m e  =  case lookup e m of
+    Just Nothing -> error $ "toDynamicWithDefn: loop detected " ++ show e
+    Just (Just d) -> Just (n,m,d)
+    Nothing -> case [re n ((e,Nothing):m) $ e' //- bs | (a',e') <- cx, Just bs <- [e `match` a']] of
+               [] -> error $ "toDynamicWithDefn: unhandled pattern " ++ show e
+               (Nothing:_) -> Nothing
+               (Just (n,m,d):_) -> Just (n,[(e',if e == e' then Just d else md) | (e',md) <- m],d)
+
+  ($$) :: Maybe (Int,Memo,Dynamic) -> Expr -> Maybe (Int, Memo, Dynamic)
+  Just (n,m,d1) $$ e2  =  case re n m e2 of
                           Nothing -> Nothing
-                          Just (m', n', d2) -> (m',n',) <$> dynApply d1 d2
+                          Just (n', m', d2) -> (n',m',) <$> dynApply d1 d2
   _ $$ _               =  Nothing
 
 devaluate :: Typeable a => (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe a
diff --git a/src/Conjure/Engine.hs b/src/Conjure/Engine.hs
--- a/src/Conjure/Engine.hs
+++ b/src/Conjure/Engine.hs
@@ -40,7 +40,7 @@
 import Test.LeanCheck.Tiers
 import Test.LeanCheck.Error (errorToTrue, errorToFalse, errorToNothing)
 
-import Test.Speculate.Reason (Thy, rules, equations, canReduceTo, printThy)
+import Test.Speculate.Reason (Thy, rules, equations, canReduceTo, printThy, closureLimit)
 import Test.Speculate.Engine (theoryFromAtoms, groundBinds, boolTy)
 
 import Conjure.Expr
@@ -105,6 +105,8 @@
   , maxEquationSize   :: Int  -- ^ maximum size of equation operands
   , maxSearchTests    :: Int  -- ^ maximum number of tests to search for defined values
   , requireDescent    :: Bool -- ^ require recursive calls to deconstruct arguments
+  , usePatterns       :: Bool -- ^ use pattern matching to create (recursive) candidates
+  , showTheory        :: Bool -- ^ show theory discovered by Speculate used in pruning
   , forceTests :: [[Expr]]  -- ^ force tests
   }
 
@@ -118,14 +120,17 @@
 -- * pruning with equations up to size 5
 -- * search for defined applications for up to 100000 combinations
 -- * require recursive calls to deconstruct arguments
+-- * don't show the theory used in pruning
 args :: Args
 args = Args
-  { maxTests           =  60
+  { maxTests           =  360
   , maxSize            =  12
   , maxEvalRecursions  =  60
   , maxEquationSize    =   5
   , maxSearchTests     =  100000
   , requireDescent     =  True
+  , usePatterns        =  True
+  , showTheory         =  False
   , forceTests         =  []
   }
 
@@ -138,6 +143,13 @@
   print (var (head $ words nm) f)
   putStrLn $ "-- testing " ++ show (length ts) ++ " combinations of argument values"
   putStrLn $ "-- pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"
+  when (showTheory args) $ do
+    putStrLn $ "{-"
+    printThy thy
+    putStrLn $ "-}"
+  when (filtered thy) $
+    putStrLn $ "-- reasoning produced incorrect properties," -- TODO: add Num
+            ++ " please re-run with more tests for faster results"
   pr 1 rs
   where
   pr n []  =  putStrLn $ "cannot conjure\n"
@@ -212,7 +224,11 @@
 
 -- | Return apparently unique candidate definitions.
 candidateDefns :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy)
-candidateDefns  =  candidateDefns1
+candidateDefns args  =  cds args
+  where
+  cds  =  if usePatterns args
+          then candidateDefnsC
+          else candidateDefns1
 
 
 -- | Return apparently unique candidate definitions
@@ -246,12 +262,13 @@
   efxs  =  conjureVarApplication nm f
   (ef:exs)  =  unfoldApp efxs
   keep  =  isRootNormalE thy . fastMostGeneralVariation
-  ds  =  map snd $ deconstructors f maxTests es
+  ds  =  filter (conjureIsDeconstructor f maxTests) es
   keepR | requireDescent  =  descends (`elem` ds) efxs
         | otherwise       =  const True
   recs  =  filterT keepR
         $  foldAppProducts ef [forN h | h <- conjureArgumentHoles f]
-  thy  =  theoryFromAtoms (===) maxEquationSize . (:[]) . nub
+  thy  =  filterTheory (===)
+       .  theoryFromAtoms (===) maxEquationSize . (:[]) . nub
        $  cjHoles (prim nm f:ps) ++ [val False, val True] ++ es
   (===)  =  cjAreEqual (prim nm f:ps) maxTests
 
@@ -260,7 +277,8 @@
 candidateDefnsC :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy)
 candidateDefnsC Args{..} nm f ps  =  (concatMapT fillingsFor fss,thy)
   where
-  fss  =  concatMapT ps2fss (conjurePats es nm f)
+  pats  =  conjurePats es nm f
+  fss  =  concatMapT ps2fss pats
   es  =  map fst ps
 
   eh  =  holeAsTypeOf efxs
@@ -280,32 +298,46 @@
     p2eess pat  =  mapT (pat,)
                 .  appsWith pat
                 .  tail
-                $  vars pat ++ [eh | length pats > 1, any should aes]
+                $  vars pat ++ [eh | any (uncurry should) (zip aess aes)]
       where
-      should ae  =  hasVar ae && (isApp ae || isUnbreakable ae)
-      (_:aes)  =  unfoldApp pat
+      should aes ae  =  length (nub aes) > 1 && hasVar ae && (isApp ae || isUnbreakable ae)
+      aes   =                  (tail . unfoldApp . rehole) pat
+      aess  =  transpose $ map (tail . unfoldApp . rehole) pats
 
   fillingsFor1 :: Bndn -> [[Bndn]]
   fillingsFor1 (ep,er)  =  mapT (\es -> (ep,fill er es))
                         .  products
                         .  replicate (length $ holes er)
-                        $  recs ep es
+                        $  recs' ep
 
   fillingsFor :: Defn -> [[Defn]]
   fillingsFor  =  products . map fillingsFor1
 
-  recs ep es  =  discardT (\e -> e == ep)
-              $  filterT (\e -> any (`elem` vs) (vars e))
-              $  foldAppProducts ef [appsWith h (vs ++ es) | h <- conjureArgumentHoles f]
-    where -- TODO: proper descent check above
-    vs  =  tail (vars ep)
+  ds  =  filter (conjureIsDeconstructor f maxTests) es
+  keepR ep | requireDescent  =  descends (`elem` ds) ep
+           | otherwise       =  const True
+  recs ep  =  filterT (keepR ep)
+           .  discardT (\e -> e == ep)
+           $  recsV' (tail (vars ep))
+  recsV vs  =  filterT (\e -> any (`elem` vs) (vars e))
+            $  foldAppProducts ef [appsWith h vs | h <- conjureArgumentHoles f]
+  -- like recs, but memoized
+  recs' ep  =  fromMaybe errRP $ lookup ep eprs
+    where
+    eprs = [(ep, recs ep) | ep <- possiblePats]
+  possiblePats  =  nubSort . concat . concat $ pats
+  -- like recsV, but memoized
+  recsV' vs  =  fromMaybe errRV $ lookup vs evrs
+    where
+    evrs = [(vs, recsV vs) | vs <- nubSort $ map (tail . vars) possiblePats]
 
-  thy  =  theoryFromAtoms (===) maxEquationSize . (:[]) . nub
+  thy  =  filterTheory (===)
+       .  theoryFromAtoms (===) maxEquationSize . (:[]) . nub
        $  cjHoles (prim nm f:ps) ++ [val False, val True] ++ es
   (===)  =  cjAreEqual (prim nm f:ps) maxTests
   isUnbreakable  =  conjureIsUnbreakable f
--- this seems to work, see:
--- > blindCandidateDefns args "fact" (undefined :: [Int] -> Int) [pr (0::Int), pr (1::Int), prim "+" ((+)::Int->Int->Int)]
+  errRP  =  error "candidateDefnsC: unexpected pattern.  You have found a bug, please report it."
+  errRV  =  error "candidateDefnsC: unexpected variables.  You have found a bug, please report it."
 
 
 -- | Returns whether the given recursive call
@@ -364,60 +396,19 @@
 descends :: (Expr -> Bool) -> Expr -> Expr -> Bool
 descends isDec e' e  =  any d1 ss
   where
-  d1 exys  =  nubVars (foldApp exs) == nubVars (foldApp eys)
-           && all isNotConstruction eys
-           && any isDeconstruction eys
-    where
-    exs  =  map fst exys
-    eys  =  map snd exys
+  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 e  =  not (null cs) && all isDec cs
-    where
-    cs  =  consts e
-  isNotConstruction e  =  all isDec cs
+  isDeconstruction (p,e) | isVar p    =  not (null cs) && all isDec cs
+                         | otherwise  =  size e < size p
     where
     cs  =  consts e
-
--- | Example:
---
--- > > deconstructors and 60
--- > >   [ val False
--- > >   , val True
--- > >   , value "null" (null::[Bool]->Bool)
--- > >   , value "head" (head :: [Bool] -> Bool)
--- > >   , value "tail" (tail :: [Bool] -> [Bool])
--- > >   , value "drop1" (drop 1 :: [Bool] -> [Bool])
--- > >   ]
--- > [tail :: [Bool] -> [Bool]]
---
--- In this case, inc is a deconstructor as it converges for more than half the
--- values:
---
--- > > deconstructors (negate :: Int -> Int) 60
--- > >   [ value "eq0" ((==0) :: Int -> Bool)
--- > >   , val (0 :: Int)
--- > >   , value "==" ((==) :: Int -> Int -> Bool)
--- > >   , value "dec" (subtract 1 :: Int -> Int)
--- > >   , value "inc" ((+1) :: Int -> Int)
--- > >   ]
--- > [ ((0 ==) :: Int -> Bool,dec :: Int -> Int)
--- > , ((0 ==) :: Int -> Bool,inc :: Int -> Int)
--- > ]
-deconstructors :: Conjurable f => f -> Int -> [Expr] -> [(Expr, Expr)]
-deconstructors f maxTests es  =
-  [ (z, d)
-  | d <- es
-  , h <- take 1 [h | h <- hs, mtyp (d :$ h) == mtyp h]
-  , z <- take 1 [z | z <- es2, mtyp (z :$ h) == mtyp b && isDeconstructor h z d]
-  ]
-  where
-  b  =  hole (undefined :: Bool)
-  hs  =  nub $ conjureArgumentHoles f
-  isDeconstructor  =  conjureIsDeconstructor f maxTests
-  es2  =  es ++ [e1 :$ e2 | e1 <- es, e2 <- es, isWellTyped (e1 :$ e2)]
+  isNotConstruction (p,e) | isVar p    =  all isDec (consts e)
+                          | otherwise  =  size e <= size p -- TODO: allow filter and id somehow
 
 
 candidatesTD :: (Expr -> Bool) -> Expr -> [Expr] -> [[Expr]]
@@ -475,6 +466,29 @@
   where
   trie  =  T.fromList $ equations thy ++ map swap (equations thy)
   (->-)  =  canReduceTo thy
+
+
+--- double checks ---
+
+filtered :: Thy -> Bool
+filtered  =  (< 0) . closureLimit
+
+filterTheory :: (Expr -> Expr -> Bool) -> Thy -> Thy
+-- TODO: move filterTheory into Speculate, and add new Thy field "doubleChecked / invalid"
+--       or maybe have a third list of equations:
+--       invalid :: (Expr,Expr)
+--       that lists ones that were discarded
+filterTheory (===) thy  =  thy
+                        {  rules = rs
+                        ,  equations = es
+                        ,  closureLimit = if r' && e'
+                                          then closureLimit thy
+                                          else -1
+                        }
+  where
+  correct  =  uncurry (===)
+  (rs,r')  =  filterAnd correct (rules thy)
+  (es,e')  =  filterAnd correct (equations thy)
 
 
 --- tiers utils ---
diff --git a/src/Conjure/Expr.hs b/src/Conjure/Expr.hs
--- a/src/Conjure/Expr.hs
+++ b/src/Conjure/Expr.hs
@@ -11,6 +11,7 @@
   ( module Data.Express
   , module Data.Express.Fixtures
 
+  , rehole
   , (>$$<)
   , funToVar
   , recursexpr
@@ -33,6 +34,7 @@
   , isDeconstructionE
   , revaluate
   , reval
+  , useMatches
 
   , enumerateAppsFor
   , enumerateFillings
@@ -365,6 +367,29 @@
                                \/ delay (productWith f xss yss)
   where
   xs ** ys  =  [x `f` y | x <- xs, y <- ys]
+
+-- |
+--
+-- > useMatches [xx,yy] [xx,yy]  =  [[(xx,xx), (yy,yy)]]
+-- > useMatches [xx,yy] [yy,xx]  =  [[(xx,xx), (yy,yy)]]
+-- > useMatches [yy,xx] [xx,yy]  =  [[(yy,yy), (xx,xx)]]
+-- > useMatches [xx,yy] [xx,xx]  =  []
+-- > useMatches [xx,yy] [abs' xx, abs' yy]  =  [[(xx,abs' xx), (yy, abs' yy)]]
+-- > useMatches [xx-:-xxs, yy-:-yys] [abs' xx, abs' yy]
+-- >   =  [(xx-:-xxs, abs' xx), (yy-:-yys, abs' yy)]
+useMatches :: [Expr] -> [Expr] -> [[(Expr,Expr)]]
+useMatches [] []  =  [[]]
+useMatches [] es  =  [] -- no matches when lists have different lengths
+useMatches es []  =  [] -- no matches when lists have different lengths
+useMatches (e:es) es'  =  concat
+  [ map ((e,e'):) (useMatches es es')
+  | (e',es') <- choicesThat (\e' _ -> any (`elem` vars e') (vars e)) es'
+  ]
+
+rehole :: Expr -> Expr
+rehole (e1 :$ e2)    = rehole e1 :$ rehole e2
+rehole e | isVar e   = "" `varAsTypeOf` e
+         | otherwise = e
 
 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
@@ -13,6 +13,7 @@
   ( Prim (..)
   , prim
   , pr
+  , prif
   , cjHoles
   , cjTiersFor
   , cjAreEqual
@@ -47,19 +48,24 @@
 prim s x  =  (value s x, conjureType x)
 
 
+-- | Provides an if condition bound to the given return type.
+prif :: Conjurable a => a -> Prim
+prif x  =  (ifFor x, conjureType x)
+
+
 -- the following functions mirror their "conjure" counterparts from
 -- Conjure.Conjurable but need a list of Prims instead of a Conjurable
 -- representative.
 
 cjReification :: [Prim] -> [Reification1]
-cjReification ps  =  nubOn (\(eh,_,_,_) -> eh)
+cjReification ps  =  nubOn (\(eh,_,_,_,_,_) -> eh)
                   $  foldr (.) id (map snd ps) [conjureReification1 bool]
 
 cjHoles :: [Prim] -> [Expr]
-cjHoles ps  =  [eh | (eh,_,Just _,_) <- cjReification ps]
+cjHoles ps  =  [eh | (eh,_,Just _,_,_,_) <- cjReification ps]
 
 cjMkEquation :: [Prim] -> Expr -> Expr -> Expr
-cjMkEquation ps  =  mkEquation [eq | (_,Just eq,_,_) <- cjReification ps]
+cjMkEquation ps  =  mkEquation [eq | (_,Just eq,_,_,_,_) <- cjReification ps]
 
 cjAreEqual :: [Prim] -> Int -> Expr -> Expr -> Bool
 cjAreEqual ps maxTests  =  (===)
@@ -73,7 +79,7 @@
 cjTiersFor ps e  =  tf allTiers
   where
   allTiers :: [ [[Expr]] ]
-  allTiers  =  [etiers | (_,_,Just etiers,_) <- cjReification ps]
+  allTiers  =  [etiers | (_,_,Just etiers,_,_,_) <- cjReification ps]
   tf []  =  [[e]] -- no tiers found, keep variable
   tf (etiers:etc)  =  case etiers of
                       ((e':_):_) | typ e' == typ e -> etiers
diff --git a/src/Conjure/Utils.hs b/src/Conjure/Utils.hs
--- a/src/Conjure/Utils.hs
+++ b/src/Conjure/Utils.hs
@@ -18,6 +18,7 @@
 
   , count
   , nubOn
+  , nubSort
   , iterateUntil
   , mzip
   , groupOn
@@ -34,6 +35,9 @@
   , sets
   , headOr
   , allEqual
+  , choices
+  , choicesThat
+  , filterAnd
   )
 where
 
@@ -58,6 +62,14 @@
 nubOn :: Eq b => (a -> b) -> [a] -> [a]
 nubOn f  =  nubBy ((==) `on` f)
 
+nubSort :: Ord a => [a] -> [a]
+nubSort  =  nnub . sort
+  where
+  -- linear nub of adjacent values
+  nnub [] = []
+  nnub [x] = [x]
+  nnub (x:xs) = x : nnub (dropWhile (==x) xs)
+
 iterateUntil :: (a -> a -> Bool) -> (a -> a) -> a -> a
 iterateUntil (?) f  =  iu
   where
@@ -130,3 +142,19 @@
 headOr :: a -> [a] -> a
 headOr x []  =  x
 headOr _ (x:xs)  =  x
+
+choices :: [a] -> [(a,[a])]
+choices []  =  []
+choices (x:xs)  =  (x,xs) : map (mapSnd (x:)) (choices xs)
+  where
+  mapSnd f (x,y)  =  (x,f y)
+
+choicesThat :: (a -> [a] -> Bool) -> [a] -> [(a,[a])]
+choicesThat (?)  =  filter (uncurry (?)) . choices
+
+filterAnd :: (a -> Bool) -> [a] -> ([a],Bool)
+filterAnd p xs  =  (xs', and ps)
+  where
+  xps  =  [(x,p x) | x <- xs]
+  xs'  =  [x | (x,True) <- xps]
+  ps   =  [p | (_,p) <- xps]
diff --git a/test/Test/ListableExpr.hs b/test/Test/ListableExpr.hs
--- a/test/Test/ListableExpr.hs
+++ b/test/Test/ListableExpr.hs
@@ -50,8 +50,6 @@
   )
 where
 
--- TODO: StringE
-
 import Test.LeanCheck
 import Test.LeanCheck.Function.ShowFunction
 import Data.Express.Fixtures
diff --git a/test/conjurable.hs b/test/conjurable.hs
--- a/test/conjurable.hs
+++ b/test/conjurable.hs
@@ -11,6 +11,7 @@
 deriving instance Typeable Unit  -- for GHC < 7.10
 
 instance Listable Unit where list = [Unit]
+instance Name Unit where name _ = "u"
 instance Conjurable Unit where
   conjureExpress = reifyExpress
   conjureTiers = reifyTiers
@@ -144,6 +145,50 @@
          ]
        , [ [ ffs nilInt
            , ffs (xx -:- xxs)
+           ]
+         ]
+       ]
+
+  , take 4 (conjurePats [zero, one] "?" (undefined :: Int -> Int -> Int))
+    == [ [ [ xx -?- yy
+           ]
+         ]
+       , [ [ xx -?- zero
+           , xx -?- yy
+           ]
+         , [ zero -?- xx
+           , xx -?- yy
+           ]
+         ]
+       , [ [ xx -?- one
+           , xx -?- yy
+           ]
+         , [ zero -?- zero
+           , zero -?- xx
+           , xx -?- zero
+           , xx -?- yy
+           ]
+         , [ one -?- xx
+           , xx -?- yy
+           ]
+         ]
+       , [ [ xx -?- zero
+           , xx -?- one
+           , xx -?- yy
+           ]
+         , [ zero -?- one
+           , zero -?- xx
+           , xx -?- one
+           , xx -?- yy
+           ]
+         , [ one -?- zero
+           , one -?- xx
+           , xx -?- zero
+           , xx -?- yy
+           ]
+         , [ zero -?- xx
+           , one -?- xx
+           , xx -?- yy
            ]
          ]
        ]
diff --git a/test/defn.hs b/test/defn.hs
--- a/test/defn.hs
+++ b/test/defn.hs
@@ -4,6 +4,7 @@
 import Test
 import Conjure.Defn
 import Test.LeanCheck.Error (errorToLeft)
+import Data.Express.Fixtures
 
 main :: IO ()
 main  =  mainTest tests 5040
@@ -16,6 +17,24 @@
   , dvl sumDefn (sumV :$ val [1,2,3::Int])    == ( 6 :: Int)
   , dvl sumDefn (sumV :$ val [1,2,3,4::Int])  == (10 :: Int)
 
+  , dvl andDefn (andV :$ val [False,False])     == False
+  , dvl andDefn (andV :$ val [False,True])      == False
+  , dvl andDefn (andV :$ val [True,True])       == True
+  , dvl andDefn (andV :$ val [True,False,True]) == False
+  , dvl orDefn  (orV  :$ val [False,False])     == False
+  , dvl orDefn  (orV  :$ val [False,True])      == True
+  , dvl orDefn  (orV  :$ val [True,True])       == True
+  , dvl orDefn  (orV  :$ val [True,False,True]) == True
+
+  , dvl and1Defn (andV :$ val [False,False])     == False
+  , dvl and1Defn (andV :$ val [False,True])      == False
+  , dvl and1Defn (andV :$ val [True,True])       == True
+  , dvl and1Defn (andV :$ val [True,False,True]) == False
+  , dvl or1Defn  (orV  :$ val [False,False])     == False
+  , dvl or1Defn  (orV  :$ val [False,True])      == True
+  , dvl or1Defn  (orV  :$ val [True,True])       == True
+  , dvl or1Defn  (orV  :$ val [True,False,True]) == True
+
   , dvl factDefn (factV :$ val (0 :: Int)) == (1 :: Int)
   , dvl factDefn (factV :$ val (1 :: Int)) == (1 :: Int)
   , dvl factDefn (factV :$ val (2 :: Int)) == (2 :: Int)
@@ -27,26 +46,56 @@
   , errorToLeft (dvl factDefn (factV :$ val (11 :: Int)) == (39916800 :: Int))
     == Left "toDynamicWithDefn: recursion limit reached"
 
+  , dvl fact1Defn (factV :$ val (0 :: Int)) == (1 :: Int)
+  , dvl fact1Defn (factV :$ val (1 :: Int)) == (1 :: Int)
+  , dvl fact1Defn (factV :$ val (2 :: Int)) == (2 :: Int)
+  , dvl fact1Defn (factV :$ val (3 :: Int)) == (6 :: Int)
+  , dvl fact1Defn (factV :$ val (4 :: Int)) == (24 :: Int)
+  , dvl fact1Defn (factV :$ val (9 :: Int)) == (362880 :: Int)
+  , errorToLeft (dvl fact1Defn (factV :$ val (10 :: Int)))
+    == Right (3628800 :: Int)
+  , errorToLeft (dvl fact1Defn (factV :$ val (11 :: Int)) == (39916800 :: Int))
+    == Left "toDynamicWithDefn: recursion limit reached"
+
   , dvl isZeroDefn (isZeroV :$ val (0 :: Int)) == True
   , dvl isZeroDefn (isZeroV :$ val (1 :: Int)) == False
+  , dvl isOneDefn  (isOneV  :$ val (0 :: Int)) == False
+  , dvl isOneDefn  (isOneV  :$ val (1 :: Int)) == True
 
   , dvl nullDefn (nullV :$ val [0,1,2,3::Int]) == False
-  , dvl nullDefn (nullV :$ val ([] :: [Int])) == False
+  , dvl nullDefn (nullV :$ val ([] :: [Int]))  == True
+
+  , holds n $ cevl 60 sumDefn    === (sum :: [Int] -> Int)
+  , holds n $ cevl 60 andDefn    === (and :: [Bool] -> Bool)
+  , holds n $ cevl 60 orDefn     === (or :: [Bool] -> Bool)
+  , holds n $ cevl 60 isZeroDefn === ((==0) :: Int -> Bool)
+  , holds n $ cevl 60 isOneDefn  === ((==1) :: Int -> Bool)
+  , holds n $ cevl 60 nullDefn   === (null :: [Int] -> Bool)
+  , holds n $ cevl 60 appendDefn ==== ((++) :: [Int] -> [Int] -> [Int])
+
+  -- evaluating at the incorrect types should return Nothing
+  , isNothing (cevaluate 60 sumDefn :: Maybe ([Bool] -> Bool))
+  , isNothing (cevaluate 60 andDefn :: Maybe ([Int] -> Int))
+  , isNothing (cevaluate 60 nullDefn :: Maybe ([Int] -> Int))
   ]
 
 dvl :: Typeable a => Defn -> Expr -> a
-dvl  =  devl exprExpr 12
+dvl  =  devl exprExpr 11
 
 sumV, factV, nullV, isZeroV :: Expr
 factV    =  var "fact"   (undefined :: Int -> Int)
 sumV     =  var "sum"    (undefined :: [Int] -> Int)
+andV     =  var "and"    (undefined :: [Bool] -> Bool)
+orV      =  var "or"     (undefined :: [Bool] -> Bool)
 isZeroV  =  var "isZero" (undefined :: Int -> Bool)
+isOneV   =  var "isOne"  (undefined :: Int -> Bool)
 nullV    =  var "null"   (undefined :: [Int] -> Bool)
+appendV  =  var "++"     (undefined :: [Int] -> [Int] -> [Int])
 
 -- NOTE: a hack for testing needs all types that are Express as arguments of
 --       undefined.
 exprExpr :: Expr -> Expr
-exprExpr  =  conjureExpress (undefined :: Int -> [Int] -> ())
+exprExpr  =  conjureExpress (undefined :: Bool -> [Bool] -> Int -> [Int] -> ())
 
 sumDefn :: Defn
 sumDefn  =  [ sum' nil           =-  zero
@@ -58,8 +107,12 @@
              , fact' xx    =-  xx -*- (factV :$ (xx -+- minusOne))
              ]  where  fact' e  =  factV :$ e
 
+fact1Defn :: Defn
+fact1Defn  =  [ fact' xx  =-  if' (xx -==- zero) (one) (xx -*- (factV :$ (minus :$ xx :$ one)))
+              ]  where  fact' e  =  factV :$ e
+
 nullDefn :: Defn
-nullDefn  =  [ null' nil           =-  false
+nullDefn  =  [ null' nil           =-  true
              , null' (xx -:- xxs)  =-  false
              ]  where  null' e  =  nullV :$ e
 
@@ -67,6 +120,33 @@
 isZeroDefn  =  [ isZero' zero  =-  true
                , isZero' xx    =-  false
                ]  where  isZero' e  =  isZeroV :$ e
+
+isOneDefn :: Defn
+isOneDefn  =  [ isOne' xx  =-  xx -==- one ]
+  where isOne' e  =  isOneV :$ e
+
+andDefn :: Defn
+andDefn  =  [ and' nilBool       =-  true
+            , and' (pp -:- pps)  =-  pp -&&- (andV :$ pps)
+            ]  where  and' e  =  andV :$ e
+
+orDefn :: Defn
+orDefn  =  [ or' nilBool       =-  false
+           , or' (pp -:- pps)  =-  pp -||- (orV :$ pps)
+           ]  where or' e  =  orV :$ e
+
+and1Defn :: Defn
+and1Defn  =  [ and' pps  =-  null' pps -||- head' pps -&&- and' (tail' pps)
+             ]  where  and' e  =  andV :$ e
+
+or1Defn :: Defn
+or1Defn  =  [ or' pps  =-  not' (null' pps) -&&- (head' pps -||- or' (tail' pps))
+            ]  where or' e  =  orV :$ e
+
+appendDefn :: Defn
+appendDefn  =  [ nil -++- xxs  =-  xxs
+               , (xx -:- xxs) -++- yys  =-  xx -:- (xxs -++- yys)
+               ]  where  exs -++- eys  =  appendV :$ exs :$ eys
 
 (=-) = (,)
 infixr 0 =-
diff --git a/test/expr.hs b/test/expr.hs
--- a/test/expr.hs
+++ b/test/expr.hs
@@ -188,4 +188,42 @@
        , hole (undefined :: Int -> Int)
        , hole (undefined :: Int -> Int -> Int)
        ]
+
+  , useMatches [xx,yy] [xx,yy] == [[(xx,xx), (yy,yy)]]
+  , useMatches [xx,yy] [yy,xx] == [[(xx,xx), (yy,yy)]]
+  , useMatches [yy,xx] [xx,yy] == [[(yy,yy), (xx,xx)]]
+  , useMatches [xx,yy] [xx,xx] == []
+
+  , useMatches [xx,yy] [abs' xx, abs' yy]
+    == [ [ (xx, abs' xx)
+         , (yy, abs' yy)
+         ]
+       ]
+
+  , useMatches [xx-:-xxs, yy-:-yys] [abs' xx, abs' yy]
+    == [ [ (xx-:-xxs, abs' xx)
+         , (yy-:-yys, abs' yy)
+         ]
+       ]
+
+  , useMatches [xx-:-xxs, yy-:-yys] [xx-:-xxs, yy-:-yys]
+    == [ [ (xx-:-xxs, xx-:-xxs)
+         , (yy-:-yys, yy-:-yys)
+         ]
+       ]
+
+  , useMatches [xx-:-xxs, yy-:-yys] [yy-:-xxs, yy-:-yys]
+    == [ [ (xx-:-xxs, yy-:-xxs)
+         , (yy-:-yys, yy-:-yys)
+         ]
+       ]
+
+  , useMatches [xx-:-xxs, yy-:-yys] [yy-:-xxs, xx-:-yys]
+    == [ [ (xx-:-xxs, yy-:-xxs)
+         , (yy-:-yys, xx-:-yys)
+         ]
+       , [ (xx-:-xxs, xx-:-yys)
+         , (yy-:-yys, yy-:-xxs)
+         ]
+       ]
   ]
