packages feed

code-conjure 0.3.4 → 0.3.6

raw patch · 36 files changed

+174/−152 lines, 36 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Conjure: [maxRecursionSize] :: Args -> Int
- Conjure: [maxRecursiveCalls] :: Args -> Int
- Conjure.Engine: [maxRecursionSize] :: Args -> Int
- Conjure.Engine: [maxRecursiveCalls] :: Args -> Int
+ Conjure: [maxBodyRecursions] :: Args -> Int
+ Conjure: [maxEvalRecursions] :: Args -> Int
+ Conjure: [requireDescent] :: Args -> Bool
+ Conjure.Engine: [maxBodyRecursions] :: Args -> Int
+ Conjure.Engine: [maxEvalRecursions] :: Args -> Int
+ Conjure.Engine: [requireDescent] :: Args -> Bool
+ Conjure.Expr: enumerateFillings :: Expr -> [[Expr]] -> [[Expr]]
- Conjure: Args :: Int -> Int -> Int -> Int -> Int -> Int -> [[Expr]] -> Args
+ Conjure: Args :: Int -> Int -> Int -> Int -> Int -> Int -> Bool -> [[Expr]] -> Args
- Conjure.Engine: Args :: Int -> Int -> Int -> Int -> Int -> Int -> [[Expr]] -> Args
+ Conjure.Engine: Args :: Int -> Int -> Int -> Int -> Int -> Int -> Bool -> [[Expr]] -> Args
- Conjure.Engine: candidateExprs :: Conjurable f => String -> f -> Int -> Int -> (Expr -> Expr -> Bool) -> [Expr] -> [[Expr]]
+ Conjure.Engine: candidateExprs :: Conjurable f => Args -> String -> f -> [Expr] -> [[Expr]]

Files

Makefile view
@@ -64,9 +64,6 @@ test-via-stack: 	stack test code-conjure:test:expr --ghc-options="$(GHCFLAGS) -O0" --system-ghc --no-install-ghc --no-terminal -hugs-test:-	echo 'Unsupported'- clean: clean-hi-o clean-haddock 	rm -f $(EG) $(TESTS) mk/toplibs 
TODO.md view
@@ -3,11 +3,6 @@  A non-exhaustive list of things TO DO for Conjure. -* think about how can we allow gcd to be produced--* use holes for recursions, code will probably become cleaner-  (and possibly faster)- * generate functions with top-level case patterns:          len []  =  0@@ -15,6 +10,10 @@   ### for later++* add machinery to reify `Int -> Int` from the `(Expr,Expr)` definition++* allow specifying properties that need to be true  * allow recursion under any lazy functions (discover them by testing!) 
bench/ill-hit.out view
@@ -8,8 +8,8 @@ -- looking through 5 candidates of size 6 -- looking through 15 candidates of size 7 -- looking through 27 candidates of size 8--- looking through 53 candidates of size 9--- looking through 101 candidates of size 10+-- 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)  sum :: [Int] -> Int@@ -22,8 +22,8 @@ -- looking through 5 candidates of size 6 -- looking through 15 candidates of size 7 -- looking through 27 candidates of size 8--- looking through 53 candidates of size 9--- looking through 101 candidates of size 10+-- 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)  sum :: [Int] -> Int@@ -36,7 +36,7 @@ -- looking through 5 candidates of size 6 -- looking through 15 candidates of size 7 -- looking through 27 candidates of size 8--- looking through 53 candidates of size 9--- looking through 101 candidates of size 10+-- 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) 
bench/longshot.out view
@@ -10,8 +10,8 @@ -- looking through 611 candidates of size 8 -- looking through 1779 candidates of size 9 -- looking through 5301 candidates of size 10--- looking through 16103 candidates of size 11--- looking through 49113 candidates of size 12+-- looking through 16107 candidates of size 11+-- looking through 49149 candidates of size 12 cannot conjure  pow :: Int -> Int -> Int@@ -51,7 +51,7 @@ -- looking through 154 candidates of size 9 -- looking through 366 candidates of size 10 -- looking through 914 candidates of size 11--- looking through 2234 candidates of size 12+-- looking through 2238 candidates of size 12 cannot conjure  positionsFrom :: Int -> Int -> [Int] -> [Int]@@ -66,7 +66,7 @@ -- looking through 170 candidates of size 8 -- looking through 358 candidates of size 9 -- looking through 810 candidates of size 10--- looking through 2046 candidates of size 11--- looking through 5578 candidates of size 12+-- looking through 2070 candidates of size 11+-- looking through 5706 candidates of size 12 cannot conjure 
bench/runtime/zero/bench/ill-hit.runtime view
@@ -1,1 +1,1 @@-1.1+1.2
bench/runtime/zero/bench/longshot.runtime view
@@ -1,1 +1,1 @@-4.3+4.7
bench/runtime/zero/bench/take-drop.runtime view
@@ -1,1 +1,1 @@-5.8+7.2
bench/runtime/zero/eg/arith.runtime view
@@ -1,1 +1,1 @@-0.8+0.9
bench/runtime/zero/eg/bools.runtime view
@@ -1,1 +1,1 @@-2.8+3.0
bench/runtime/zero/eg/count.runtime view
@@ -1,1 +1,1 @@-2.3+3.2
bench/runtime/zero/eg/factorial.runtime view
@@ -1,1 +1,1 @@-1.4+1.5
bench/runtime/zero/eg/fibonacci.runtime view
@@ -1,1 +1,1 @@-20.8+22.2
bench/runtime/zero/eg/gcd.runtime view
@@ -1,1 +1,1 @@-0.3+0.1
bench/runtime/zero/eg/list.runtime view
@@ -1,1 +1,1 @@-0.4+0.5
bench/runtime/zero/eg/setelem.runtime view
@@ -1,1 +1,1 @@-23.3+22.5
bench/runtime/zero/eg/tree.runtime view
@@ -1,1 +1,1 @@-4.6+5.6
bench/take-drop.out view
@@ -8,11 +8,11 @@ -- looking through 1 candidates of size 6 -- looking through 1 candidates of size 7 -- looking through 7 candidates of size 8--- looking through 33 candidates of size 9--- looking through 100 candidates of size 10--- looking through 236 candidates of size 11--- looking through 510 candidates of size 12--- looking through 1069 candidates of size 13+-- 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)  take :: Int -> [A] -> [A]@@ -25,13 +25,13 @@ -- looking through 14 candidates of size 6 -- looking through 26 candidates of size 7 -- looking through 62 candidates of size 8--- looking through 176 candidates of size 9--- looking through 470 candidates of size 10--- looking through 1190 candidates of size 11--- looking through 3116 candidates of size 12--- looking through 8020 candidates of size 13--- looking through 19658 candidates of size 14--- looking through 46906 candidates of size 15--- looking through 109976 candidates of size 16+-- 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) 
changelog.md view
@@ -2,6 +2,17 @@ ============================  +v0.3.6+------++* add switch for descending recursions+  to allow generation of `gcd`+* refactor recursion generation (replace a hole later)+* change `conjpureWith` to take `Args`+* rename two args fields to `maxBodyRecursions` and `maxEvalRecursions`+  at this point, the old names were misnomers.++ v0.3.4 ------ 
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.3.4+version:             0.3.6 synopsis:            conjure Haskell functions out of partial definitions description:   Conjure is a tool that produces Haskell functions out of partial definitions.@@ -65,7 +65,7 @@ source-repository this   type:            git   location:        https://github.com/rudymatela/conjure-  tag:             v0.3.4+  tag:             v0.3.6  library   exposed-modules: Conjure
eg/bools.out view
@@ -8,7 +8,7 @@ -- looking through 19 candidates of size 6 -- looking through 45 candidates of size 7 -- looking through 80 candidates of size 8--- looking through 156 candidates of size 9+-- looking through 172 candidates of size 9 and ps  =  null ps || head ps && and (tail ps)  or :: [Bool] -> Bool@@ -21,8 +21,8 @@ -- looking through 19 candidates of size 6 -- looking through 45 candidates of size 7 -- looking through 80 candidates of size 8--- looking through 156 candidates of size 9--- looking through 382 candidates of size 10+-- looking through 172 candidates of size 9+-- looking through 454 candidates of size 10 or ps  =  not (null ps) && (head ps || or (tail ps))  and :: [Bool] -> Bool
eg/count.out view
@@ -9,12 +9,12 @@ -- looking through 13 candidates of size 7 -- looking through 16 candidates of size 8 -- looking through 57 candidates of size 9--- looking through 84 candidates of size 10--- looking through 242 candidates of size 11--- looking through 401 candidates of size 12--- looking through 1045 candidates of size 13--- looking through 1895 candidates of size 14--- looking through 4672 candidates of size 15--- looking through 8990 candidates of size 16-count x xs  =  if null xs then 0 else count x (tail xs) + (if x == head xs then 1 else 0)+-- 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 5212 candidates of size 15+-- looking through 10296 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) 
eg/factorial.out view
@@ -15,8 +15,8 @@ -- looking through 20 candidates of size 5 -- looking through 27 candidates of size 6 -- looking through 87 candidates of size 7--- looking through 167 candidates of size 8--- looking through 417 candidates of size 9--- looking through 960 candidates of size 10+-- 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) 
eg/fibonacci.hs view
@@ -22,7 +22,7 @@ fib01 0 1 7  =  21  as :: Args-as  =  args{maxSize=13,maxRecursiveCalls=2}+as  =  args{maxSize=13,maxBodyRecursions=2}  main :: IO () main  =  do
eg/fibonacci.out view
@@ -9,10 +9,10 @@ -- looking through 27 candidates of size 7 -- looking through 20 candidates of size 8 -- looking through 95 candidates of size 9--- looking through 140 candidates of size 10--- looking through 407 candidates of size 11--- looking through 825 candidates of size 12--- looking through 2153 candidates of size 13+-- looking through 172 candidates of size 10+-- looking through 519 candidates of size 11+-- looking through 1281 candidates of size 12+-- looking through 3281 candidates of size 13 fibonacci n  =  if n <= 1 then 1 else fibonacci (dec n) + fibonacci (dec (dec n))  fib01 :: Int -> Int -> Int -> Int@@ -27,7 +27,7 @@ -- looking through 391 candidates of size 8 -- looking through 840 candidates of size 9 -- looking through 9294 candidates of size 10--- looking through 37807 candidates of size 11--- looking through 166308 candidates of size 12+-- 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) 
eg/gcd.hs view
@@ -18,7 +18,7 @@ gcd' 12 18  =  6  main :: IO ()-main = conjure "gcd a b" gcd'+main = conjureWith args{requireDescent=False} "gcd a b" gcd'   [ val (0::Int)   , value "`mod`" (mod :: Int -> Int -> Int)   , value "==" ((==) :: Int -> Int -> Bool)@@ -26,4 +26,3 @@   -- desired function:   -- gcd a b  =  if b == 0 then a else gcd b (a `mod` b)   --             1  2 3  4      5      6   7  8  9   10-  -- TODO: make it so that conjure is able to find this
eg/gcd.out view
@@ -7,10 +7,8 @@ -- looking through 54 candidates of size 5 -- looking through 0 candidates of size 6 -- looking through 405 candidates of size 7--- looking through 0 candidates of size 8+-- looking through 90 candidates of size 8 -- looking through 3402 candidates of size 9--- looking through 0 candidates of size 10--- looking through 30618 candidates of size 11--- looking through 0 candidates of size 12-cannot conjure+-- looking through 2016 candidates of size 10+gcd a b  =  if a == 0 then b else gcd (b `mod` a) a 
eg/ints.out view
@@ -23,8 +23,8 @@ -- looking through 5 candidates of size 6 -- looking through 15 candidates of size 7 -- looking through 27 candidates of size 8--- looking through 53 candidates of size 9--- looking through 101 candidates of size 10+-- 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)  product :: [Int] -> Int@@ -37,8 +37,8 @@ -- looking through 5 candidates of size 6 -- looking through 15 candidates of size 7 -- looking through 27 candidates of size 8--- looking through 53 candidates of size 9--- looking through 101 candidates of size 10+-- 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)  sum :: [Int] -> Int
eg/list.out view
@@ -8,7 +8,7 @@ -- looking through 0 candidates of size 6 -- looking through 5 candidates of size 7 -- looking through 8 candidates of size 8--- looking through 19 candidates of size 9+-- looking through 23 candidates of size 9 length xs  =  if null xs then 0 else 1 + length (tail xs)  reverse :: [Int] -> [Int]@@ -23,7 +23,7 @@ -- looking through 381 candidates of size 8 -- looking through 1014 candidates of size 9 -- looking through 2736 candidates of size 10--- looking through 7447 candidates of size 11+-- looking through 7451 candidates of size 11 reverse xs  =  if null xs then xs else reverse (tail xs) ++ unit (head xs)  sort :: [Int] -> [Int]
eg/setelem.hs view
@@ -7,20 +7,22 @@ elem' x [y,z,w]  =  x == y || x == z || x == w  set' :: [Int] -> Bool+set' []  =  True set' [x]  =  True set' [x,y]  =  not (x == y) set' [x,y,z]  =  not (x == y || y == z || x == z)  main :: IO () main = do-  -- elem x xs  =  if null xs then False else elem x (tail xs) || x == head xs+  -- elem x xs  =  not (null xs) && (elem x (tail xs) || x == head xs)+  --               1    2    3    4  5    6   7   8   9  10 11 12  13   conjureWithMaxSize 13 "elem" (elem')     [ val ([] :: [Int])     , val True     , val False-    , value "not" not     , value "||" (||)     , value "&&" (&&)+    , value "not" not     , value ":" ((:) :: Int -> [Int] -> [Int])     , value "head" (head :: [Int] -> Int)     , value "tail" (tail :: [Int] -> [Int])@@ -28,14 +30,15 @@     , value "==" ((==) :: Int -> Int -> Bool)     ] -  -- set xs  =  if null xs then True else not (head xs `elem` tail xs) && set (tail xs)-  conjureWithMaxSize 14 "set" (set')+  -- set xs  =  null xs || set (tail xs) && not (elem (head xs) (tail xs))+  --            1    2  3  4    5    6    7  8    9    10   11   12   13+  conjureWithMaxSize 13 "set" (set')     [ val ([] :: [Int])     , val True     , val False-    , value "not" not-    , value "||" (||)     , value "&&" (&&)+    , value "||" (||)+    , value "not" not     , value ":" ((:) :: Int -> [Int] -> [Int])     , value "head" (head :: [Int] -> Int)     , value "tail" (tail :: [Int] -> [Int])
eg/setelem.out view
@@ -6,14 +6,14 @@ -- looking through 8 candidates of size 4 -- looking through 14 candidates of size 5 -- looking through 25 candidates of size 6--- looking through 57 candidates of size 7--- looking through 137 candidates of size 8--- looking through 320 candidates of size 9--- looking through 720 candidates of size 10--- looking through 1737 candidates of size 11--- looking through 4204 candidates of size 12--- looking through 10333 candidates of size 13-elem x xs  =  not (null xs) && (elem x (tail xs) || x == head xs)+-- 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 4407 candidates of size 12+-- looking through 10888 candidates of size 13+elem x xs  =  not (null xs) && (head xs == x || elem x (tail xs))  set :: [Int] -> Bool -- testing 60 combinations of argument values@@ -23,13 +23,12 @@ -- looking through 5 candidates of size 4 -- looking through 11 candidates of size 5 -- looking through 26 candidates of size 6--- looking through 61 candidates of size 7--- looking through 142 candidates of size 8--- looking through 302 candidates of size 9--- looking through 692 candidates of size 10--- looking through 1651 candidates of size 11--- looking through 3945 candidates of size 12--- looking through 9309 candidates of size 13--- looking through 22246 candidates of size 14-set xs  =  not (elem (head xs) (tail xs)) && (null (tail xs) || set (tail xs))+-- looking through 64 candidates of size 7+-- looking through 145 candidates of size 8+-- looking through 310 candidates of size 9+-- looking through 717 candidates of size 10+-- looking through 1734 candidates of size 11+-- looking through 4135 candidates of size 12+-- looking through 9734 candidates of size 13+set xs  =  null xs || not (elem (head xs) (tail xs)) && set (tail xs) 
eg/spec.out view
@@ -9,7 +9,7 @@ -- looking through 5 candidates of size 7 -- looking through 10 candidates of size 8 -- looking through 17 candidates of size 9--- looking through 28 candidates of size 10+-- looking through 30 candidates of size 10 sum xs  =  if null xs then 0 else head xs + sum (tail xs)  (++) :: [Int] -> [Int] -> [Int]
eg/tapps.out view
@@ -16,8 +16,8 @@ -- looking through 5 candidates of size 6 -- looking through 15 candidates of size 7 -- looking through 27 candidates of size 8--- looking through 53 candidates of size 9--- looking through 101 candidates of size 10+-- 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)  product :: [Int] -> Int
eg/tree.hs view
@@ -91,7 +91,7 @@     , value "right" right     ] -  conjureWith args{maxRecursiveCalls=2, maxSize=13} "size" size+  conjureWith args{maxBodyRecursions=2, maxSize=13} "size" size     [ val (0 :: Int)     , val (1 :: Int)     , value "+" ((+) :: Int -> Int -> Int)@@ -100,7 +100,7 @@     , value "right" right     ] -  conjureWith args{maxRecursiveCalls=2, maxSize=13} "height" height+  conjureWith args{maxBodyRecursions=2, maxSize=13} "height" height     [ val (0 :: Int)     , val (1 :: Int)     , val (-1 :: Int)@@ -112,7 +112,7 @@     ]    -- out of reach performance-wise-  conjureWith args{maxRecursiveCalls=2, maxSize=12} "mem" mem+  conjureWith args{maxBodyRecursions=2, maxSize=12} "mem" mem     [ val False     , value "||" (||)     , value "==" ((==) :: Int -> Int -> Bool)@@ -123,7 +123,7 @@     ]    -- simply out of reach performance-wise (size 34)-  conjureWith args{maxRecursiveCalls=2, maxSize=9} "insert" mem+  conjureWith args{maxBodyRecursions=2, maxSize=9} "insert" mem     [ val Leaf     , value "Node" Node     , value "left" left
eg/tree.out view
@@ -34,11 +34,11 @@ -- looking through 0 candidates of size 6 -- looking through 9 candidates of size 7 -- looking through 32 candidates of size 8--- looking through 109 candidates of size 9--- looking through 304 candidates of size 10--- looking through 817 candidates of size 11--- looking through 2080 candidates of size 12--- looking through 5165 candidates of size 13+-- 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))  height :: Tree -> Int@@ -51,12 +51,12 @@ -- looking through 0 candidates of size 6 -- looking through 21 candidates of size 7 -- looking through 48 candidates of size 8--- looking through 239 candidates of size 9--- looking through 656 candidates of size 10--- looking through 2149 candidates of size 11--- looking through 5704 candidates of size 12--- looking through 16380 candidates of size 13-height x  =  if nil x then -1 else 1 + max (height (left x)) (height (right x))+-- looking through 299 candidates of size 9+-- looking through 896 candidates of size 10+-- looking through 3113 candidates of size 11+-- looking through 8528 candidates of size 12+-- looking through 24896 candidates of size 13+cannot conjure  mem :: Int -> Tree -> Bool -- testing 60 combinations of argument values@@ -69,9 +69,9 @@ -- looking through 64 candidates of size 7 -- looking through 156 candidates of size 8 -- looking through 376 candidates of size 9--- looking through 926 candidates of size 10--- looking through 2280 candidates of size 11--- looking through 5648 candidates of size 12+-- looking through 930 candidates of size 10+-- looking through 2302 candidates of size 11+-- looking through 5752 candidates of size 12 cannot conjure  insert :: Int -> Tree -> Bool
src/Conjure/Engine.hs view
@@ -94,10 +94,11 @@ data Args = Args   { maxTests          :: Int  -- ^ maximum number of tests to each candidate   , maxSize           :: Int  -- ^ maximum size of candidate bodies-  , maxRecursiveCalls :: Int  -- ^ maximum number of allowed recursive calls+  , maxBodyRecursions :: Int  -- ^ maximum number of recursive calls in candidate bodies+  , maxEvalRecursions :: Int  -- ^ maximum number of recursive evaluations when testing candidates   , maxEquationSize   :: Int  -- ^ maximum size of equation operands-  , maxRecursionSize  :: Int  -- ^ maximum size of a recursive expression expansion   , maxSearchTests    :: Int  -- ^ maximum number of tests to search for defined values+  , requireDescent    :: Bool -- ^ require recursive calls to deconstruct arguments   , forceTests :: [[Expr]]  -- ^ force tests   } @@ -106,18 +107,20 @@ -- -- * 60 tests -- * functions of up to 12 symbols--- * maximum of 1 recursive call+-- * maximum of one recursive call allowed in candidate bodies+-- * maximum evaluation of up to 60 recursions -- * pruning with equations up to size 5--- * recursion up to 60 symbols -- * search for defined applications for up to 100000 combinations+-- * require recursive calls to deconstruct arguments args :: Args args = Args   { maxTests           =  60   , maxSize            =  12-  , maxRecursiveCalls  =   1+  , maxBodyRecursions  =   1+  , maxEvalRecursions  =  60   , maxEquationSize    =   5-  , maxRecursionSize   =  60   , maxSearchTests     =  100000+  , requireDescent     =  True   , forceTests         =  []   } @@ -136,7 +139,7 @@     putStrLn $ "-- looking through "             ++ show (length cs)             ++ " candidates of size " ++ show n-    -- when (n<=7) $ putStrLn $ unlines $ map show es+    -- when (n<=12) $ putStrLn $ unlines $ map show cs     case is of       []     ->  pr (n+1) rs       (i:_)  ->  do putStrLn $ showEq i@@ -159,23 +162,22 @@  -- | Like 'conjpure' but allows setting options through 'Args' and 'args'. conjpureWith :: Conjurable f => Args -> String -> f -> [Expr] -> ([[Expr]], [[Expr]], [Expr])-conjpureWith Args{..} nm f es  =  (implementationsT, candidatesT, tests)+conjpureWith args@(Args{..}) nm f es  =  (implementationsT, candidatesT, tests)   where   tests  =  [ffxx //- bs | bs <- dbss]   implementationsT  =  mapT (vffxx -==-) $ filterT implements candidatesT   implements e  =  apparentlyTerminates rrff e                 && requal (vffxx,e) ffxx vffxx   candidatesT  =  take maxSize-               $  candidateExprs nm f maxEquationSize maxRecursiveCalls (===) es+               $  candidateExprs args nm f es   ffxx   =  conjureApplication nm f   vffxx  =  conjureVarApplication nm f   (rrff:xxs)  =  unfoldApp vffxx -  (===)  =  conjureAreEqual f maxTests   requal dfn e1 e2  =  isTrueWhenDefined dfn (e1 -==- e2)   (-==-)  =  conjureMkEquation f -  isTrueWhenDefined dfn e  =  all (errorToFalse . reval dfn maxRecursionSize False) $ map (e //-) dbss+  isTrueWhenDefined dfn e  =  all (errorToFalse . reval dfn maxEvalRecursions False) $ map (e //-) dbss    bss, dbss :: [[(Expr,Expr)]]   bss  =  take maxSearchTests $ groundBinds (conjureTiersFor f) ffxx@@ -187,14 +189,8 @@     e  =  ffxx -==- ffxx  -candidateExprs :: Conjurable f-               => String -> f-               -> Int-               -> Int-               -> (Expr -> Expr -> Bool)-               -> [Expr]-               -> [[Expr]]-candidateExprs nm f sz mc (===) es  =  as \/ ts+candidateExprs :: Conjurable f => Args -> String -> f -> [Expr] -> [[Expr]]+candidateExprs Args{..} nm f es  =  as \/ concatMapT (`enumerateFillings` recs) ts   where   ts | typ efxs == boolTy  =  foldAppProducts andE [cs, rs]                            \/ foldAppProducts orE  [cs, rs]@@ -206,17 +202,21 @@   as  =  forN efxs   rs  =  forR efxs   forN h  =  enumerateAppsFor h keep [exs ++ es]-  forR h  =  filterT (\e -> (ef `elem`) (vars e))-          $  enumerateAppsFor h keep $ [exs ++ es] \/ recs+  forR h  =  filterT (\e -> (eh `elem`) (holes e))+          $  enumerateAppsFor h keep $ [exs ++ es ++ [eh]]+  eh  =  holeAsTypeOf efxs   efxs  =  conjureVarApplication nm f   (ef:exs)  =  unfoldApp efxs   keep e  =  isRootNormalE thy e-          && count (== ef) (vars e) <= mc-  thy  =  theoryFromAtoms (===) sz . (:[]) . nub-       $  conjureHoles f ++ [val False, val True] ++ es-  ds  =  map snd $ deconstructors f 60 es-  recs  =  filterT (descends (`elem` ds) efxs)+          && count (== ef) (vars e) <= maxBodyRecursions+  ds  =  map snd $ deconstructors 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+       $  conjureHoles f ++ [val False, val True] ++ es+  (===)  =  conjureAreEqual f maxTests  -- | Returns whether the given recursive call --   deconstructs one of its arguments.
src/Conjure/Expr.hs view
@@ -36,6 +36,7 @@    , enumerateApps   , enumerateAppsFor+  , enumerateFillings    , module Conjure.Utils   )@@ -50,7 +51,8 @@ import Data.Dynamic import Control.Applicative ((<$>)) -- for GHC <= 7.8 -import Test.LeanCheck (filterT, (\/), delay, productWith, productMaybeWith)+import Test.LeanCheck (mapT, filterT, (\/), delay, productWith, productMaybeWith)+import Test.LeanCheck.Tiers (products)  -- | /O(n)/. -- Compares the simplicity of two 'Expr's.@@ -326,13 +328,18 @@   for h  =  filterT (\e -> typ h == typ e) ess \/ delay apps     where     apps  =  foldr (\/) []-          [  filterT keep $ productWith (:$) (for hf) (for hx)+          [  filterT keep $ fliproductWith (:$) (for hf) (for hx)           |  hf <- hs           ,  hx <- hs           ,  Just hfx <- [hf $$ hx]           ,  typ h == typ hfx           ] +enumerateFillings :: Expr -> [[Expr]] -> [[Expr]]+enumerateFillings e  =  mapT (fill e)+                     .  products+                     .  replicate (length $ holes e)+ -- Like 'isDeconstruction' but lifted over the 'Expr' type. isDeconstructionE :: [Expr] -> Expr -> Expr -> Bool --                   [a] -> (a -> Bool) -> (a -> a) -> Bool@@ -383,3 +390,12 @@  reval :: Typeable a => (Expr,Expr) -> Int -> a -> Expr -> a reval dfn n x e = fromMaybe x (revaluate dfn n e)++-- | like 'productWith' but prefers enumerating from the second tiers first+fliproductWith :: (a->b->c) -> [[a]] -> [[b]] -> [[c]]+fliproductWith _ [] _  =  []+fliproductWith _ _ []  =  []+fliproductWith f xss (ys:yss)  =  map (** ys) xss+                               \/ delay (productWith f xss yss)+  where+  xs ** ys  =  [x `f` y | x <- xs, y <- ys]