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 +6/−0
- Makefile +10/−4
- README.md +22/−22
- TODO.md +11/−4
- bench/candidates.hs +22/−16
- bench/candidates.out +7246/−1703
- bench/gps.hs +337/−0
- bench/gps.out +156/−0
- bench/ill-hit.out +18/−30
- bench/longshot.hs +1/−114
- bench/longshot.out +0/−77
- bench/lowtests.hs +86/−0
- bench/lowtests.out +81/−0
- bench/p12.out +7/−6
- bench/runtime/zero/bench/candidates.runtime +1/−1
- bench/runtime/zero/bench/gps.runtime +1/−0
- bench/runtime/zero/bench/ill-hit.runtime +1/−1
- bench/runtime/zero/bench/longshot.runtime +1/−1
- bench/runtime/zero/bench/lowtests.runtime +1/−0
- bench/runtime/zero/bench/p12.runtime +1/−1
- bench/runtime/zero/bench/take-drop.runtime +1/−1
- bench/runtime/zero/eg/arith.runtime +1/−1
- bench/runtime/zero/eg/bools.runtime +1/−1
- bench/runtime/zero/eg/count.runtime +1/−1
- bench/runtime/zero/eg/dupos.runtime +1/−0
- bench/runtime/zero/eg/factorial.runtime +1/−1
- bench/runtime/zero/eg/fib01.runtime +1/−0
- bench/runtime/zero/eg/fibonacci.runtime +1/−1
- bench/runtime/zero/eg/ints.runtime +1/−1
- bench/runtime/zero/eg/list.runtime +1/−1
- bench/runtime/zero/eg/pow.runtime +1/−0
- bench/runtime/zero/eg/replicate.runtime +1/−1
- bench/runtime/zero/eg/setelem.runtime +1/−1
- bench/runtime/zero/eg/sort.runtime +1/−0
- bench/runtime/zero/eg/subset.runtime +1/−1
- bench/runtime/zero/eg/tapps.runtime +1/−1
- bench/runtime/zero/eg/tree.runtime +1/−1
- bench/runtime/zero/versions +2/−2
- bench/self.out +12/−12
- bench/take-drop.hs +7/−6
- bench/take-drop.out +27/−34
- changelog.md +13/−0
- code-conjure.cabal +2/−2
- eg/arith.out +12/−12
- eg/bools.out +18/−25
- eg/count.out +11/−15
- eg/dupos.hs +77/−0
- eg/dupos.out +43/−0
- eg/factorial.hs +0/−3
- eg/factorial.out +14/−17
- eg/fib01.hs +31/−0
- eg/fib01.out +25/−0
- eg/fibonacci.hs +15/−26
- eg/fibonacci.out +15/−32
- eg/gcd.hs +0/−1
- eg/gcd.out +8/−11
- eg/ints.out +29/−37
- eg/list.hs +0/−19
- eg/list.out +49/−88
- eg/pow.hs +42/−0
- eg/pow.out +24/−0
- eg/replicate.hs +3/−4
- eg/replicate.out +17/−24
- eg/setelem.out +20/−28
- eg/sort.hs +82/−0
- eg/sort.out +57/−0
- eg/spec.out +13/−21
- eg/subset.hs +6/−4
- eg/subset.out +11/−14
- eg/tapps.out +15/−19
- eg/tree.hs +9/−16
- eg/tree.out +66/−72
- mk/depend.mk +78/−0
- src/Conjure.hs +4/−2
- src/Conjure/Conjurable.hs +103/−14
- src/Conjure/Defn.hs +42/−31
- src/Conjure/Engine.hs +80/−66
- src/Conjure/Expr.hs +25/−0
- src/Conjure/Prim.hs +10/−4
- src/Conjure/Utils.hs +28/−0
- test/Test/ListableExpr.hs +0/−2
- test/conjurable.hs +45/−0
- test/defn.hs +84/−4
- test/expr.hs +38/−0
.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)+ ]+ ] ]