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 +0/−3
- TODO.md +4/−5
- bench/ill-hit.out +6/−6
- bench/longshot.out +5/−5
- bench/runtime/zero/bench/ill-hit.runtime +1/−1
- bench/runtime/zero/bench/longshot.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/factorial.runtime +1/−1
- bench/runtime/zero/eg/fibonacci.runtime +1/−1
- bench/runtime/zero/eg/gcd.runtime +1/−1
- bench/runtime/zero/eg/list.runtime +1/−1
- bench/runtime/zero/eg/setelem.runtime +1/−1
- bench/runtime/zero/eg/tree.runtime +1/−1
- bench/take-drop.out +13/−13
- changelog.md +11/−0
- code-conjure.cabal +2/−2
- eg/bools.out +3/−3
- eg/count.out +8/−8
- eg/factorial.out +3/−3
- eg/fibonacci.hs +1/−1
- eg/fibonacci.out +6/−6
- eg/gcd.hs +1/−2
- eg/gcd.out +3/−5
- eg/ints.out +4/−4
- eg/list.out +2/−2
- eg/setelem.hs +9/−6
- eg/setelem.out +16/−17
- eg/spec.out +1/−1
- eg/tapps.out +2/−2
- eg/tree.hs +4/−4
- eg/tree.out +14/−14
- src/Conjure/Engine.hs +26/−26
- src/Conjure/Expr.hs +18/−2
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]