packages feed

code-conjure 0.4.0 → 0.4.2

raw patch · 84 files changed

+9338/−2660 lines, 84 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Conjure: [showTheory] :: Args -> Bool
+ Conjure: [usePatterns] :: Args -> Bool
+ Conjure: prif :: Conjurable a => a -> Prim
+ Conjure.Conjurable: ceval :: Conjurable f => Int -> f -> Defn -> f
+ Conjure.Conjurable: cevaluate :: Conjurable f => Int -> Defn -> Maybe f
+ Conjure.Conjurable: cevl :: Conjurable f => Int -> Defn -> f
+ Conjure.Conjurable: conjureEvaluate :: Conjurable a => (Expr -> Expr) -> Int -> Defn -> Expr -> Maybe a
+ Conjure.Conjurable: conjureSize :: Conjurable a => a -> Int
+ Conjure.Conjurable: instance Data.Express.Name.Name Test.LeanCheck.Utils.Types.A
+ Conjure.Conjurable: instance Data.Express.Name.Name Test.LeanCheck.Utils.Types.B
+ Conjure.Conjurable: instance Data.Express.Name.Name Test.LeanCheck.Utils.Types.C
+ Conjure.Conjurable: instance Data.Express.Name.Name Test.LeanCheck.Utils.Types.D
+ Conjure.Conjurable: instance Data.Express.Name.Name Test.LeanCheck.Utils.Types.E
+ Conjure.Conjurable: instance Data.Express.Name.Name Test.LeanCheck.Utils.Types.F
+ Conjure.Engine: [showTheory] :: Args -> Bool
+ Conjure.Engine: [usePatterns] :: Args -> Bool
+ Conjure.Expr: rehole :: Expr -> Expr
+ Conjure.Expr: useMatches :: [Expr] -> [Expr] -> [[(Expr, Expr)]]
+ Conjure.Prim: prif :: Conjurable a => a -> Prim
+ Conjure.Utils: choices :: [a] -> [(a, [a])]
+ Conjure.Utils: choicesThat :: (a -> [a] -> Bool) -> [a] -> [(a, [a])]
+ Conjure.Utils: filterAnd :: (a -> Bool) -> [a] -> ([a], Bool)
+ Conjure.Utils: nubSort :: Ord a => [a] -> [a]
- Conjure: Args :: Int -> Int -> Int -> Int -> Int -> Bool -> [[Expr]] -> Args
+ Conjure: Args :: Int -> Int -> Int -> Int -> Int -> Bool -> Bool -> Bool -> [[Expr]] -> Args
- Conjure: class Typeable a => Conjurable a
+ Conjure: class (Typeable a, Name a) => Conjurable a
- Conjure.Conjurable: class Typeable a => Conjurable a
+ Conjure.Conjurable: class (Typeable a, Name a) => Conjurable a
- Conjure.Conjurable: conjureIsDeconstructor :: Conjurable f => f -> Int -> Expr -> Expr -> Expr -> Bool
+ Conjure.Conjurable: conjureIsDeconstructor :: Conjurable f => f -> Int -> Expr -> Bool
- Conjure.Conjurable: type Reification1 = (Expr, Maybe Expr, Maybe [[Expr]], Bool)
+ Conjure.Conjurable: type Reification1 = (Expr, Maybe Expr, Maybe [[Expr]], [String], Bool, Expr)
- Conjure.Engine: Args :: Int -> Int -> Int -> Int -> Int -> Bool -> [[Expr]] -> Args
+ Conjure.Engine: Args :: Int -> Int -> Int -> Int -> Int -> Bool -> Bool -> Bool -> [[Expr]] -> Args

Files

.gitignore view
@@ -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
Makefile view
@@ -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
README.md view
@@ -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
TODO.md view
@@ -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 
bench/candidates.hs view
@@ -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 "&&" (&&)
bench/candidates.out view
@@ -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:
+ bench/gps.hs view
@@ -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+         ]
+ bench/gps.out view
@@ -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)))+
bench/ill-hit.out view
@@ -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 
bench/longshot.hs view
@@ -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)
bench/longshot.out view
@@ -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-
+ bench/lowtests.hs view
@@ -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)+    ]
+ bench/lowtests.out view
@@ -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))+
bench/p12.out view
@@ -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) 
bench/runtime/zero/bench/candidates.runtime view
@@ -1,1 +1,1 @@-2.1+10.0
+ bench/runtime/zero/bench/gps.runtime view
@@ -0,0 +1,1 @@+15.2
bench/runtime/zero/bench/ill-hit.runtime view
@@ -1,1 +1,1 @@-1.4+1.3
bench/runtime/zero/bench/longshot.runtime view
@@ -1,1 +1,1 @@-10.0+0.0
+ bench/runtime/zero/bench/lowtests.runtime view
@@ -0,0 +1,1 @@+0.4
bench/runtime/zero/bench/p12.runtime view
@@ -1,1 +1,1 @@-2.9+3.5
bench/runtime/zero/bench/take-drop.runtime view
@@ -1,1 +1,1 @@-10.6+0.6
bench/runtime/zero/eg/arith.runtime view
@@ -1,1 +1,1 @@-0.9+1.2
bench/runtime/zero/eg/bools.runtime view
@@ -1,1 +1,1 @@-3.9+3.5
bench/runtime/zero/eg/count.runtime view
@@ -1,1 +1,1 @@-4.4+0.7
+ bench/runtime/zero/eg/dupos.runtime view
@@ -0,0 +1,1 @@+5.4
bench/runtime/zero/eg/factorial.runtime view
@@ -1,1 +1,1 @@-2.8+0.8
+ bench/runtime/zero/eg/fib01.runtime view
@@ -0,0 +1,1 @@+5.8
bench/runtime/zero/eg/fibonacci.runtime view
@@ -1,1 +1,1 @@-29.9+1.4
bench/runtime/zero/eg/ints.runtime view
@@ -1,1 +1,1 @@-1.3+1.6
bench/runtime/zero/eg/list.runtime view
@@ -1,1 +1,1 @@-1.1+0.5
+ bench/runtime/zero/eg/pow.runtime view
@@ -0,0 +1,1 @@+2.3
bench/runtime/zero/eg/replicate.runtime view
@@ -1,1 +1,1 @@-7.0+0.4
bench/runtime/zero/eg/setelem.runtime view
@@ -1,1 +1,1 @@-41.7+2.5
+ bench/runtime/zero/eg/sort.runtime view
@@ -0,0 +1,1 @@+1.3
bench/runtime/zero/eg/subset.runtime view
@@ -1,1 +1,1 @@-7.1+0.8
bench/runtime/zero/eg/tapps.runtime view
@@ -1,1 +1,1 @@-0.7+0.8
bench/runtime/zero/eg/tree.runtime view
@@ -1,1 +1,1 @@-8.1+2.2
bench/runtime/zero/versions view
@@ -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
bench/self.out view
@@ -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 
bench/take-drop.hs view
@@ -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])
bench/take-drop.out view
@@ -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 
changelog.md view
@@ -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 ------ 
code-conjure.cabal view
@@ -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
eg/arith.out view
@@ -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)) 
eg/bools.out view
@@ -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 
eg/count.out view
@@ -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 
+ eg/dupos.hs view
@@ -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])+    ]
+ eg/dupos.out view
@@ -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)+
eg/factorial.hs view
@@ -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:
eg/factorial.out view
@@ -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) 
+ eg/fib01.hs view
@@ -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
+ eg/fib01.out view
@@ -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+
eg/fibonacci.hs view
@@ -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++-}
eg/fibonacci.out view
@@ -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)) 
eg/gcd.hs view
@@ -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)
eg/gcd.out view
@@ -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) 
eg/ints.out view
@@ -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 
eg/list.hs view
@@ -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
eg/list.out view
@@ -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 
+ eg/pow.hs view
@@ -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)+    ]
+ eg/pow.out view
@@ -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+
eg/replicate.hs view
@@ -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)
eg/replicate.out view
@@ -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 
eg/setelem.out view
@@ -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 
+ eg/sort.hs view
@@ -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])+    ]
+ eg/sort.out view
@@ -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+
eg/spec.out view
@@ -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) 
eg/subset.hs view
@@ -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)     ]
eg/subset.out view
@@ -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
eg/tapps.out view
@@ -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 
eg/tree.hs view
@@ -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)     ]  
eg/tree.out view
@@ -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 
mk/depend.mk view
@@ -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
src/Conjure.hs view
@@ -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
src/Conjure/Conjurable.hs view
@@ -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
src/Conjure/Defn.hs view
@@ -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
src/Conjure/Engine.hs view
@@ -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 ---
src/Conjure/Expr.hs view
@@ -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
src/Conjure/Prim.hs view
@@ -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
src/Conjure/Utils.hs view
@@ -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]
test/Test/ListableExpr.hs view
@@ -50,8 +50,6 @@   ) where --- TODO: StringE- import Test.LeanCheck import Test.LeanCheck.Function.ShowFunction import Data.Express.Fixtures
test/conjurable.hs view
@@ -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            ]          ]        ]
test/defn.hs view
@@ -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 =-
test/expr.hs view
@@ -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)+         ]+       ]   ]