code-conjure 0.7.6 → 0.7.8
raw patch · 61 files changed
+590/−274 lines, 61 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Conjure: (\/) :: [[a]] -> [[a]] -> [[a]]
+ Conjure: class Listable a
+ Conjure: cons0 :: a -> [[a]]
+ Conjure: cons1 :: Listable a => (a -> b) -> [[b]]
+ Conjure: cons10 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> [[k]]
+ Conjure: cons11 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l) -> [[l]]
+ Conjure: cons12 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k, Listable l) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m) -> [[m]]
+ Conjure: cons2 :: (Listable a, Listable b) => (a -> b -> c) -> [[c]]
+ Conjure: cons3 :: (Listable a, Listable b, Listable c) => (a -> b -> c -> d) -> [[d]]
+ Conjure: cons4 :: (Listable a, Listable b, Listable c, Listable d) => (a -> b -> c -> d -> e) -> [[e]]
+ Conjure: cons5 :: (Listable a, Listable b, Listable c, Listable d, Listable e) => (a -> b -> c -> d -> e -> f) -> [[f]]
+ Conjure: cons6 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f) => (a -> b -> c -> d -> e -> f -> g) -> [[g]]
+ Conjure: cons7 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g) => (a -> b -> c -> d -> e -> f -> g -> h) -> [[h]]
+ Conjure: cons8 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h) => (a -> b -> c -> d -> e -> f -> g -> h -> i) -> [[i]]
+ Conjure: cons9 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> [[j]]
+ Conjure: infixr 7 \/
+ Conjure: list :: Listable a => [a]
+ Conjure: reset :: [[a]] -> [[a]]
+ Conjure: tiers :: Listable a => [[a]]
+ Conjure.Conjurable: (\/) :: [[a]] -> [[a]] -> [[a]]
+ Conjure.Conjurable: class Listable a
+ Conjure.Conjurable: conjureUndefined :: Conjurable a => a -> Expr
+ Conjure.Conjurable: cons0 :: a -> [[a]]
+ Conjure.Conjurable: cons1 :: Listable a => (a -> b) -> [[b]]
+ Conjure.Conjurable: cons10 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) -> [[k]]
+ Conjure.Conjurable: cons11 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l) -> [[l]]
+ Conjure.Conjurable: cons12 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i, Listable j, Listable k, Listable l) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m) -> [[m]]
+ Conjure.Conjurable: cons2 :: (Listable a, Listable b) => (a -> b -> c) -> [[c]]
+ Conjure.Conjurable: cons3 :: (Listable a, Listable b, Listable c) => (a -> b -> c -> d) -> [[d]]
+ Conjure.Conjurable: cons4 :: (Listable a, Listable b, Listable c, Listable d) => (a -> b -> c -> d -> e) -> [[e]]
+ Conjure.Conjurable: cons5 :: (Listable a, Listable b, Listable c, Listable d, Listable e) => (a -> b -> c -> d -> e -> f) -> [[f]]
+ Conjure.Conjurable: cons6 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f) => (a -> b -> c -> d -> e -> f -> g) -> [[g]]
+ Conjure.Conjurable: cons7 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g) => (a -> b -> c -> d -> e -> f -> g -> h) -> [[h]]
+ Conjure.Conjurable: cons8 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h) => (a -> b -> c -> d -> e -> f -> g -> h -> i) -> [[i]]
+ Conjure.Conjurable: cons9 :: (Listable a, Listable b, Listable c, Listable d, Listable e, Listable f, Listable g, Listable h, Listable i) => (a -> b -> c -> d -> e -> f -> g -> h -> i -> j) -> [[j]]
+ Conjure.Conjurable: infixr 7 \/
+ Conjure.Conjurable: list :: Listable a => [a]
+ Conjure.Conjurable: reset :: [[a]] -> [[a]]
+ Conjure.Conjurable: tiers :: Listable a => [[a]]
+ Conjure.Expr: isIfSymbol :: Expr -> Bool
+ Conjure.Utils: command :: [String] -> String
+ Conjure.Utils: nor :: [Bool] -> Bool
Files
- README.md +1/−1
- TODO.md +1/−8
- bench/gps.txt +64/−34
- bench/lowtests.txt +20/−14
- bench/psb2.txt +75/−33
- bench/runtime/lapmatrud/bench/gps.runtime +1/−1
- bench/runtime/lapmatrud/bench/gps2.runtime +0/−1
- bench/runtime/lapmatrud/bench/i12.runtime +1/−0
- bench/runtime/lapmatrud/bench/i30.runtime +1/−0
- bench/runtime/lapmatrud/bench/ill-hit.runtime +1/−1
- bench/runtime/lapmatrud/bench/lowtests.runtime +1/−1
- bench/runtime/lapmatrud/bench/p12.runtime +0/−1
- bench/runtime/lapmatrud/bench/p30.runtime +0/−1
- bench/runtime/lapmatrud/bench/psb2.runtime +1/−0
- bench/runtime/lapmatrud/bench/terpret.runtime +1/−1
- bench/runtime/lapmatrud/bench/unique.runtime +1/−1
- bench/runtime/lapmatrud/eg/arith.runtime +1/−1
- bench/runtime/lapmatrud/eg/bst.runtime +1/−1
- bench/runtime/lapmatrud/eg/conditionals.runtime +1/−1
- bench/runtime/lapmatrud/eg/count.runtime +1/−1
- bench/runtime/lapmatrud/eg/fib01.runtime +1/−1
- bench/runtime/lapmatrud/eg/ints.runtime +1/−1
- bench/runtime/lapmatrud/eg/pow.runtime +1/−1
- bench/runtime/lapmatrud/eg/subset.runtime +1/−1
- bench/runtime/lapmatrud/eg/tri.runtime +1/−1
- bench/runtime/lapmatrud/versions +1/−1
- bench/self.txt +3/−0
- bench/terpret.txt +16/−14
- bench/weird.hs +21/−1
- bench/weird.txt +9/−0
- changelog.md +9/−0
- code-conjure.cabal +2/−2
- eg/bst.hs +36/−7
- eg/bst.txt +98/−38
- eg/count.txt +2/−2
- eg/digits.txt +3/−0
- eg/dupos.txt +3/−0
- eg/either.txt +5/−2
- eg/fib01.txt +6/−0
- eg/ints.txt +6/−6
- eg/list.hs +1/−3
- eg/list.txt +4/−6
- eg/oddeven.txt +4/−4
- eg/peano.hs +0/−1
- eg/pow.hs +11/−7
- eg/pow.txt +10/−7
- eg/sort.txt +3/−0
- eg/spec.txt +5/−5
- eg/subset.txt +2/−2
- eg/these.hs +0/−1
- eg/these.txt +2/−2
- eg/tree.hs +4/−6
- eg/tree.txt +14/−13
- eg/tuple.txt +8/−8
- src/Conjure.hs +18/−2
- src/Conjure/Conjurable.hs +21/−0
- src/Conjure/Defn.hs +13/−1
- src/Conjure/Engine.hs +41/−24
- src/Conjure/Expr.hs +5/−0
- src/Conjure/Ingredient.hs +6/−2
- src/Conjure/Utils.hs +20/−0
README.md view
@@ -140,7 +140,7 @@ The above example also takes less than a second to run in a modern laptop. The selection of functions in the list of ingredients was minimized to what was absolutely needed here.-With a larger collection as ingredients YMMV.+With a larger collection of ingredients YMMV. Synthesizing from specifications (for advanced users)
TODO.md view
@@ -3,17 +3,10 @@ A non-exhaustive list of things TO DO for Conjure. -* Make so that derived Listable instances `reset`- constructors that are not recursive.- This change will need to be done in LeanCheck itself.- * Allow timeout setting? * Find most efficient of a given size (see below). -* Better error reporting when `Listable` is out-of-scope when using `deriveConjurable`.- This needs to be implemented on LeanCheck itself.- * forbid recursion into negatives (see below) * Add way to consider functions that don't increase size of arguments in recursive calls@@ -49,7 +42,7 @@ 2. use this on `showDefn` somehow 3. use this on `toDynamicWithDefn` somehow -Alternative: include the guard as part of the pattern "internally". As if we+Alternative: include the guard as part of the pattern internally. As if we had a n+k pattern. Like so: tri 1 = 1
bench/gps.txt view
@@ -33,7 +33,7 @@ gps3 :: Int -> Int -> Int -> [Int] -- testing 2 combinations of argument values -- pruning with 11/33 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 64 candidates of size 4@@ -41,7 +41,7 @@ -- 1248 candidates of size 6 -- 0 candidates of size 7 -- 13680 candidates of size 8--- tested 3238 candidates+-- tested 3239 candidates gps3 x y z = enumFromThenTo x (x + z) (y - 1) gps3_alt :: Int -> Int -> Int -> [Int]@@ -62,11 +62,14 @@ -- 13311 candidates of size 13 -- tested 20359 candidates gps3_alt = undefined -- search exhausted+-- could not find implementation using only+-- [], (:), (+), (<), and guarded equations+-- consider increasing target/maxSize or refining the ingredients gps4 :: [Char] -> [Char] -> [Char] -> Bool -- testing 9 combinations of argument values -- pruning with 11/15 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 0 candidates of size 4@@ -75,9 +78,9 @@ -- 0 candidates of size 7 -- 0 candidates of size 8 -- 51 candidates of size 9--- 0 candidates of size 10--- 15 candidates of size 11--- tested 60 candidates+-- 353 candidates of size 10+-- 118 candidates of size 11+-- tested 414 candidates gps4 cs ds es = length cs < length ds && length ds < length es gps5 :: [Char] -> [Char]@@ -97,6 +100,9 @@ -- 5 candidates of size 12 -- tested 26 candidates gps5 = undefined -- search exhausted+-- could not find implementation using only+-- "", (:), '!', (==), isLetter, and guarded equations+-- consider increasing target/maxSize or refining the ingredients gps6direct :: Int -> Int -- testing 9 combinations of argument values@@ -109,6 +115,9 @@ -- 0 candidates of size 6 -- tested 188 candidates gps6direct = undefined -- search exhausted+-- could not find implementation using only+-- 1, 2, 3, (+), (*), div, even, and if-expressions+-- consider increasing target/maxSize or refining the ingredients gps6step :: Int -> Int -- testing 9 combinations of argument values@@ -134,11 +143,14 @@ -- 0 candidates of size 6 -- tested 188 candidates nextCollatz = undefined -- search exhausted+-- could not find implementation using only+-- 1, 2, 3, (+), (*), div, even, and guarded equations+-- consider increasing target/maxSize or refining the ingredients gps7 :: [Char] -> ([Char],Int) -- testing 4 combinations of argument values -- pruning with 5/10 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 1 candidates of size 4@@ -149,23 +161,26 @@ -- 88 candidates of size 9 -- 201 candidates of size 10 -- 442 candidates of size 11--- tested 553 candidates+-- tested 554 candidates 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--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 0 candidates of size 4--- tested 0 candidates+-- tested 1 candidates gps8 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients gps9 :: Int -> [Int] -- testing 3 combinations of argument values -- pruning with 13/14 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 4 candidates of size 3 -- 4 candidates of size 4@@ -175,41 +190,41 @@ -- 69 candidates of size 8 -- 114 candidates of size 9 -- 212 candidates of size 10--- tested 278 candidates+-- tested 279 candidates 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 -- 1 candidates of size 1--- 0 candidates of size 2+-- 1 candidates of size 2 -- 3 candidates of size 3 -- 15 candidates of size 4 -- 4 candidates of size 5 -- 86 candidates of size 6 -- 5 candidates of size 7 -- 513 candidates of size 8--- tested 368 candidates+-- tested 369 candidates wallisNext (x % y) = (y + 1) % (x + 1) wallisNext :: Ratio Integer -> Ratio Integer -- testing 6 combinations of argument values -- pruning with 15/26 rules -- 1 candidates of size 1--- 0 candidates of size 2+-- 1 candidates of size 2 -- 4 candidates of size 3 -- 16 candidates of size 4 -- 3 candidates of size 5 -- 71 candidates of size 6 -- 5 candidates of size 7 -- 393 candidates of size 8--- tested 295 candidates+-- tested 296 candidates wallisNext (x % y) = (y + 1) % (x + 1) gps10 :: Int -> Ratio Integer -- testing 6 combinations of argument values -- pruning with 3/4 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 3 candidates of size 3 -- 3 candidates of size 4@@ -217,17 +232,17 @@ -- 5 candidates of size 6 -- 8 candidates of size 7 -- 13 candidates of size 8--- tested 33 candidates+-- tested 34 candidates gps10 x = product (take x (iterate wallisNext (2 % 3))) gps11 :: [[Char]] -> [Int] -- testing 4 combinations of argument values -- pruning with 1/1 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 1 candidates of size 3--- 1 candidates of size 4--- tested 2 candidates+-- 2 candidates of size 4+-- tested 3 candidates gps11 css = reverse (map length css) gps11 :: [[Char]] -> [Int]@@ -279,22 +294,22 @@ odd :: Int -> Bool -- testing 6 combinations of argument values -- pruning with 12/13 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 3 candidates of size 3 -- 0 candidates of size 4 -- 35 candidates of size 5--- tested 15 candidates+-- tested 16 candidates odd x = 0 /= x `mod` 2 gps14 :: [Int] -> Int -- testing 3 combinations of argument values -- pruning with 1/1 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 1 candidates of size 2 -- 0 candidates of size 3 -- 1 candidates of size 4--- tested 2 candidates+-- tested 3 candidates gps14 xs = length (filter odd xs) gps14 :: [Int] -> Int@@ -314,22 +329,22 @@ gps15 :: [Int] -> [Int] -> Bool -- testing 5 combinations of argument values -- pruning with 3/7 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 1 candidates of size 3 -- 4 candidates of size 4--- tested 3 candidates+-- tested 4 candidates gps15 xs ys = xs == reverse ys gps16 :: [Char] -> [Char] -> Bool -- testing 6 combinations of argument values -- pruning with 3/3 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 2 candidates of size 3 -- 6 candidates of size 4 -- 2 candidates of size 5--- tested 9 candidates+-- tested 10 candidates gps16 cs ds = sort cs `isSubsequenceOf` sort ds gps17 :: Int -> Int@@ -382,6 +397,9 @@ -- 0 candidates of size 2 -- tested 1 candidates gps19 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients isVowel :: Char -> Bool -- testing 12 combinations of argument values@@ -442,11 +460,11 @@ gps20c :: [Char] -> [Char] -- pruning with 1/1 rules -- 1 candidates of size 1--- 1 candidates of size 2--- 2 candidates of size 3--- 3 candidates of size 4--- 5 candidates of size 5--- tested 12 candidates+-- 2 candidates of size 2+-- 3 candidates of size 3+-- 6 candidates of size 4+-- 10 candidates of size 5+-- tested 17 candidates gps20c cs = unwords (map pig1 (words cs)) gps21 :: [Int] -> [Int]@@ -489,6 +507,9 @@ -- 0 candidates of size 13 -- tested 1 candidates scrabble1 = undefined -- search exhausted+-- could not find implementation using only+-- 1, 'd', 'g', 'b', 'c', 'm', 'p', 'f', 'h', 'v', 'w', 'y', 'k', 'j', 'x', 'q', and 'z'+-- consider increasing target/maxSize or refining the ingredients gps22 :: [Char] -> Int -- pruning with 5/9 rules@@ -537,6 +558,9 @@ -- 15042 candidates of size 10 -- tested 20277 candidates gps25 = undefined -- search exhausted+-- could not find implementation using only+-- 0, 10, [], (:), guarded equations, abs, (<), rem, and quot+-- consider increasing target/maxSize or refining the ingredients gps26 :: Int -> Int -> Int -> Int -> Int -> Char -- testing 5 combinations of argument values@@ -554,6 +578,9 @@ -- 40000 candidates of size 11 -- tested 40405 candidates gps26 = undefined -- search exhausted+-- could not find implementation using only+-- 'A', 'B', 'C', 'D', 'F', guarded equations, and (>=)+-- consider increasing target/maxSize or refining the ingredients gps27_median :: Int -> Int -> Int -> Int -- testing 6 combinations of argument values@@ -576,6 +603,9 @@ -- 11664 candidates of size 16 -- tested 20451 candidates gps27_median = undefined -- search exhausted+-- could not find implementation using only+-- (<=), (&&), (||), and guarded equations+-- consider increasing target/maxSize or refining the ingredients gps27b_median :: Int -> Int -> Int -> Int -- testing 6 combinations of argument values
bench/lowtests.txt view
@@ -13,26 +13,29 @@ invalid: xs `isSubsequenceOf` sort xs == True -}--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 2 candidates of size 3 -- 4 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6 -- 3 candidates of size 7--- 2 candidates of size 8--- 0 candidates of size 9+-- 5 candidates of size 8+-- 2 candidates of size 9 -- 4 candidates of size 10--- 8 candidates of size 11--- 4 candidates of size 12--- 0 candidates of size 13+-- 12 candidates of size 11+-- 12 candidates of size 12+-- 4 candidates of size 13 -- 0 candidates of size 14 -- 0 candidates of size 15 -- 0 candidates of size 16 -- 0 candidates of size 17 -- 0 candidates of size 18--- tested 27 candidates+-- tested 49 candidates subset = undefined -- search exhausted+-- could not find implementation using only+-- sort and isSubsequenceOf+-- consider increasing target/maxSize or refining the ingredients subset :: [Int] -> [Int] -> Bool -- testing 44 combinations of argument values@@ -44,12 +47,12 @@ sort xs `isSubsequenceOf` xs == xs `isSubsequenceOf` sort xs -}--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 2 candidates of size 3 -- 6 candidates of size 4 -- 2 candidates of size 5--- tested 9 candidates+-- tested 10 candidates subset xs ys = sort xs `isSubsequenceOf` sort ys replicates :: [Char] -> Int -> [Char]@@ -67,20 +70,23 @@ -- 1 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6--- 1 candidates of size 7+-- 2 candidates of size 7 -- 0 candidates of size 8 -- 0 candidates of size 9--- 1 candidates of size 10+-- 2 candidates of size 10 -- 0 candidates of size 11 -- 0 candidates of size 12--- 1 candidates of size 13+-- 2 candidates of size 13 -- 0 candidates of size 14 -- 0 candidates of size 15--- 1 candidates of size 16+-- 2 candidates of size 16 -- 0 candidates of size 17 -- 0 candidates of size 18--- tested 6 candidates+-- tested 10 candidates replicates = undefined -- search exhausted+-- could not find implementation using only+-- replicate, transpose, and concat+-- consider increasing target/maxSize or refining the ingredients replicates :: [Char] -> Int -> [Char] -- testing 360 combinations of argument values
bench/psb2.txt view
@@ -1,7 +1,7 @@ gps1 :: [Int] -> Maybe Int -- testing 4 combinations of argument values -- pruning with 11/21 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 1 candidates of size 4@@ -10,14 +10,14 @@ -- 1 candidates of size 7 -- 0 candidates of size 8 -- 1 candidates of size 9--- 2 candidates of size 10--- tested 4 candidates+-- 3 candidates of size 10+-- tested 5 candidates gps1 xs = findIndex (0 >) (map (foldr (+) 0) (tail (inits xs))) gps1 :: [Int] -> Maybe Int -- testing 4 combinations of argument values -- pruning with 11/21 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 1 candidates of size 4@@ -25,7 +25,7 @@ -- 0 candidates of size 6 -- 1 candidates of size 7 -- 4 candidates of size 8--- tested 4 candidates+-- tested 5 candidates gps1 xs = findIndex (0 >) (map sum (tail (inits xs))) gps1 :: Int -> [Int] -> Int@@ -37,6 +37,9 @@ -- 5 candidates of size 4 -- tested 12 candidates gps1 = undefined -- search exhausted+-- could not find implementation using only+-- 0, 1, (+), (<), guarded equations, and undefined+-- consider increasing target/maxSize or refining the ingredients gps2 :: Double -> Double -> Int -> Double -- testing 5 combinations of argument values@@ -49,6 +52,9 @@ -- 0 candidates of size 6 -- tested 270 candidates gps2 = undefined -- search exhausted+-- could not find implementation using only+-- 0, 1, (*), (/), (+), and (-)+-- consider increasing target/maxSize or refining the ingredients gps3 :: [Char] -> Int gps3 = error "could not reify specification, suggestion: conjureFromSpec"@@ -63,13 +69,19 @@ -- 119 candidates of size 6 -- tested 203 candidates gps4 = undefined -- search exhausted+-- could not find implementation using only+-- '-', "", (:), (==), head, tail, if-expressions, if-expressions, and toUpper+-- consider increasing target/maxSize or refining the ingredients gps5 :: Int -> [Int] -- testing 6 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1--- tested 0 candidates+-- 1 candidates of size 1+-- tested 1 candidates gps5 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients tell :: [Int] -> Int -> [Int] -- pruning with 0/0 rules@@ -116,25 +128,34 @@ gps6 :: [Int] -> Int -- testing 360 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2--- tested 0 candidates+-- tested 1 candidates gps6 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients gps7 :: Integer -> Integer -> Ratio Integer -- testing 6 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1--- tested 0 candidates+-- 1 candidates of size 1+-- tested 1 candidates gps7 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients gps8 :: Int -> [Int] -> (Int,Int) -- testing 3 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2--- tested 0 candidates+-- tested 1 candidates gps8 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients gps9 :: Int -> [Char] -- testing 7 combinations of argument values@@ -152,6 +173,9 @@ -- 2976 candidates of size 11 -- tested 3487 candidates gps9 = undefined -- search exhausted+-- could not find implementation using only+-- "Fizz", "Buzz", "FizzBuzz", 0, 3, 5, False, True, divBy, (&&), show, and if-expressions+-- consider increasing target/maxSize or refining the ingredients gps10 :: [Int] -> Int -- testing 7 combinations of argument values@@ -185,12 +209,12 @@ gps12 :: [Char] -> [Char] -> [Int] -- testing 5 combinations of argument values -- pruning with 1/2 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 0 candidates of size 4 -- 4 candidates of size 5--- tested 3 candidates+-- tested 4 candidates gps12 cs ds = findIndices (ds `isPrefixOf`) (tails cs) gps13_leaders :: [Int] -> [Int]@@ -252,6 +276,9 @@ -- 4 candidates of size 6 -- tested 8 candidates gps17_pds = undefined -- search exhausted+-- could not find implementation using only+-- 0, guarded equations, not, null, (==), head, (+), and (&&)+-- consider increasing target/maxSize or refining the ingredients gps17_pds :: [Int] -> Int -- testing 9 combinations of argument values@@ -264,6 +291,9 @@ -- 8 candidates of size 6 -- tested 14 candidates gps17_pds = undefined -- search exhausted+-- could not find implementation using only+-- 0, guarded equations, (==), and (+)+-- consider increasing target/maxSize or refining the ingredients gps18_price :: [Double] -> [Double] -> Double -- testing 4 combinations of argument values@@ -276,6 +306,9 @@ -- 176 candidates of size 6 -- tested 213 candidates gps18_price = undefined -- search exhausted+-- could not find implementation using only+-- 0.0, 1.0, (+), (*), and (-)+-- consider increasing target/maxSize or refining the ingredients gps19_snowday :: Int -> Double -> Double -> Double -> Double -- testing 7 combinations of argument values@@ -288,6 +321,9 @@ -- 0 candidates of size 6 -- tested 333 candidates gps19_snowday = undefined -- search exhausted+-- could not find implementation using only+-- 0, 1, max, (+), and (-)+-- consider increasing target/maxSize or refining the ingredients gps20 :: [Char] -> Bool gps20 = error "could not reify specification, suggestion: conjureFromSpec"@@ -296,14 +332,14 @@ -- pruning with 6/6 rules -- reasoning produced 1 incorrect properties, please re-run with more tests for faster results -- 1 candidates of size 1--- 1 candidates of size 2--- 0 candidates of size 3--- 0 candidates of size 4+-- 2 candidates of size 2+-- 1 candidates of size 3+-- 1 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6 -- 0 candidates of size 7 -- 4 candidates of size 8--- tested 6 candidates+-- tested 9 candidates spin cs | length cs >= 5 = reverse cs | otherwise = cs@@ -312,11 +348,11 @@ -- pruning with 16/16 rules -- reasoning produced 2 incorrect properties, please re-run with more tests for faster results -- 1 candidates of size 1--- 2 candidates of size 2--- 2 candidates of size 3--- 3 candidates of size 4--- 5 candidates of size 5--- tested 12 candidates+-- 3 candidates of size 2+-- 4 candidates of size 3+-- 7 candidates of size 4+-- 10 candidates of size 5+-- tested 19 candidates gps21_spinwords cs = unwords (map spin (words cs)) gps22 :: Int -> [Char]@@ -342,16 +378,19 @@ -- 3 candidates of size 1 -- 12 candidates of size 2 -- 33 candidates of size 3--- 36 candidates of size 4--- 127 candidates of size 5--- 507 candidates of size 6--- 839 candidates of size 7--- 784 candidates of size 8--- 600 candidates of size 9--- 2722 candidates of size 10--- 5292 candidates of size 11--- tested 10955 candidates+-- 42 candidates of size 4+-- 140 candidates of size 5+-- 523 candidates of size 6+-- 897 candidates of size 7+-- 1127 candidates of size 8+-- 1144 candidates of size 9+-- 2959 candidates of size 10+-- 6272 candidates of size 11+-- tested 13152 candidates gps23 = undefined -- search exhausted+-- could not find implementation using only+-- nothing+-- consider increasing target/maxSize or refining the ingredients gps24 :: [Char] -> Twitter -- pruning with 4/8 rules@@ -385,4 +424,7 @@ -- 438 candidates of size 6 -- tested 532 candidates gps25 = undefined -- search exhausted+-- could not find implementation using only+-- 0.0, 2.0, (+), (-), (**), zipWith, map, and sqrt+-- consider increasing target/maxSize or refining the ingredients
bench/runtime/lapmatrud/bench/gps.runtime view
@@ -1,1 +1,1 @@-14.2+19.0
− bench/runtime/lapmatrud/bench/gps2.runtime
@@ -1,1 +0,0 @@-11.7
+ bench/runtime/lapmatrud/bench/i12.runtime view
@@ -0,0 +1,1 @@+1.7
+ bench/runtime/lapmatrud/bench/i30.runtime view
@@ -0,0 +1,1 @@+0.0
bench/runtime/lapmatrud/bench/ill-hit.runtime view
@@ -1,1 +1,1 @@-0.5+0.6
bench/runtime/lapmatrud/bench/lowtests.runtime view
@@ -1,1 +1,1 @@-0.2+0.4
− bench/runtime/lapmatrud/bench/p12.runtime
@@ -1,1 +0,0 @@-1.6
− bench/runtime/lapmatrud/bench/p30.runtime
@@ -1,1 +0,0 @@-0.0
+ bench/runtime/lapmatrud/bench/psb2.runtime view
@@ -0,0 +1,1 @@+12.3
bench/runtime/lapmatrud/bench/terpret.runtime view
@@ -1,1 +1,1 @@-10.2+10.4
bench/runtime/lapmatrud/bench/unique.runtime view
@@ -1,1 +1,1 @@-2.4+2.5
bench/runtime/lapmatrud/eg/arith.runtime view
@@ -1,1 +1,1 @@-1.0+0.9
bench/runtime/lapmatrud/eg/bst.runtime view
@@ -1,1 +1,1 @@-4.1+4.6
bench/runtime/lapmatrud/eg/conditionals.runtime view
@@ -1,1 +1,1 @@-8.7+8.6
bench/runtime/lapmatrud/eg/count.runtime view
@@ -1,1 +1,1 @@-0.5+0.6
bench/runtime/lapmatrud/eg/fib01.runtime view
@@ -1,1 +1,1 @@-0.5+0.6
bench/runtime/lapmatrud/eg/ints.runtime view
@@ -1,1 +1,1 @@-0.9+1.0
bench/runtime/lapmatrud/eg/pow.runtime view
@@ -1,1 +1,1 @@-1.6+2.4
bench/runtime/lapmatrud/eg/subset.runtime view
@@ -1,1 +1,1 @@-0.5+0.6
bench/runtime/lapmatrud/eg/tri.runtime view
@@ -1,1 +1,1 @@-0.2+0.3
bench/runtime/lapmatrud/versions view
@@ -1,4 +1,4 @@ GHC 9.4.8-leancheck-1.0.2+leancheck-1.0.4 express-1.0.18 speculate-0.4.20
bench/self.txt view
@@ -33,4 +33,7 @@ -- 10 candidates of size 3 -- tested 13 candidates d = undefined -- search exhausted+-- could not find implementation using only+-- 0, 1, (+), and (*)+-- consider increasing target/maxSize or refining the ingredients
bench/terpret.txt view
@@ -52,7 +52,7 @@ -- pruning with 37/47 rules -- reasoning produced 2 incorrect properties, please re-run with more tests for faster results -- 1 candidates of size 1--- 0 candidates of size 2+-- 1 candidates of size 2 -- 0 candidates of size 3 -- 12 candidates of size 4 -- 125 candidates of size 5@@ -62,7 +62,7 @@ -- 3087 candidates of size 9 -- 9281 candidates of size 10 -- 180325 candidates of size 11--- tested 40096 candidates+-- tested 40097 candidates cshift (p,q,r) | p = (p,r,q) | otherwise = (p,q,r)@@ -71,15 +71,15 @@ -- testing 4 combinations of argument values -- pruning with 37/47 rules -- reasoning produced 2 incorrect properties, please re-run with more tests for faster results--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 125 candidates of size 4 -- 225 candidates of size 5 -- 585 candidates of size 6 -- 1242 candidates of size 7--- 3088 candidates of size 8--- tested 5265 candidates+-- 3090 candidates of size 8+-- tested 5266 candidates cshift False p q = (False,p,q) cshift True p q = (True,q,p) @@ -88,7 +88,7 @@ fadder :: Bool -> Bool -> Bool -> (Bool,Bool) -- testing 8 combinations of argument values -- pruning with 72/90 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 25 candidates of size 3 -- 60 candidates of size 4@@ -96,7 +96,7 @@ -- 348 candidates of size 6 -- 999 candidates of size 7 -- 7009 candidates of size 8--- tested 8567 candidates+-- tested 8568 candidates fadder False False False = (False,False) fadder False False True = (False,True) fadder False True False = (False,True)@@ -112,24 +112,27 @@ -- testing 5 combinations of argument values -- pruning with 70/88 rules -- reasoning produced 2 incorrect properties, please re-run with more tests for faster results--- 0 candidates of size 1--- 0 candidates of size 2--- 0 candidates of size 3+-- 1 candidates of size 1+-- 2 candidates of size 2+-- 1 candidates of size 3 -- 8 candidates of size 4 -- 128 candidates of size 5 -- 408 candidates of size 6--- tested 544 candidates+-- tested 548 candidates adder2 = undefined -- search exhausted+-- could not find implementation using only+-- False, True, not, (&&), (||), [], (:), guarded equations, (,,), (==), (^^), and guarded equations+-- consider increasing target/maxSize or refining the ingredients TerpreT benchmark #7: access access :: [A] -> Int -> A -- testing 5 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 1 candidates of size 3--- tested 1 candidates+-- tested 2 candidates xs `access` x = xs !! x access :: [A] -> Int -> A@@ -143,7 +146,6 @@ -- 0 candidates of size 6 -- 3 candidates of size 7 -- tested 5 candidates-[] `access` x = undefined (x:xs) `access` 0 = x (x:xs) `access` y = xs `access` (y - 1)
bench/weird.hs view
@@ -10,7 +10,19 @@ -- we do not use partial definitions here. -- We use fully defined functions to conjure themselves. import Conjure+import Test.LeanCheck.Error (errorToNothing)+import Data.Maybe (isNothing) +-- | An undefined function.+bottom :: Int+bottom = undefined++-- | A specification for the above undefined function.+bottomSpec :: Int -> [Property]+bottomSpec bottom = [property $ isError bottom]+ where+ isError = isNothing . errorToNothing -- TODO: add to LeanCheck.Error?+ -- | xor for integers -- -- returns the sum but only when one of the arguments is 0@@ -29,7 +41,15 @@ main :: IO () main = do- -- TODO: Conjure should find isq, but doesn't due to overpruning+ -- We try to ask Conjure to generate undefined+ -- Conjure complains about not being able to reify specification.+ -- Fair enough: there's no way to distinguish an undefined function+ -- from an empty specification.+ conjure "bottom" bottom []++ -- With a spec, Conjure finds the "implementation"+ conjureFromSpec "bottom" bottomSpec []+ conjure "isq" isq ingredients conjure "^^^" (^^^) ingredients
bench/weird.txt view
@@ -1,3 +1,12 @@+bottom :: Int+bottom = error "could not reify specification, suggestion: conjureFromSpec"++bottom :: Int+-- pruning with 0/0 rules+-- 1 candidates of size 1+-- tested 1 candidates+bottom = undefined+ isq :: Bool -> Int -> Int -- testing 360 combinations of argument values -- pruning with 56/91 rules
changelog.md view
@@ -2,6 +2,15 @@ ============================ +v0.7.8 (August 2025)+--------------------++* automatically use `undefined` as RHS when no suitable symbols are found;+* longer message upon search exhausted;+* fix `Conjurable` derivation when `Listable` is not in scope;+* improve a few examples and internal tests.++ v0.7.6 (August 2025) --------------------
code-conjure.cabal view
@@ -3,7 +3,7 @@ -- Copyright (C) 2021-2025 Rudy Matela -- Distributed under the 3-Clause BSD licence (see the file LICENSE). name: code-conjure-version: 0.7.6+version: 0.7.8 synopsis: synthesize Haskell functions out of partial definitions description: Conjure is a tool that synthesizes Haskell functions out of partial definitions.@@ -68,7 +68,7 @@ source-repository this type: git location: https://github.com/rudymatela/conjure- tag: v0.7.6+ tag: v0.7.8 library exposed-modules: Conjure
eg/bst.hs view
@@ -6,14 +6,19 @@ import Conjure import Test.LeanCheck+import Data.Function (on) import Data.Express hiding (height,size) data Tree = Leaf | Node Tree Int Tree- deriving (Eq, Ord, Show, Read)+ deriving (Show, Read) -deriveExpress ''Tree+instance Eq Tree where+ (==) = (==) `on` inorder +instance Ord Tree where+ compare = compare `on` inorder+ unit :: Int -> Tree unit x = Node Leaf x Leaf @@ -78,6 +83,13 @@ EQ -> Node l y r -- 16 GT -> Node l y (insert x r) -- 22 +insertAlt :: Int -> Tree -> Tree+insertAlt x Leaf = unit x -- 2+insertAlt x (Node l y r)+ | x < y = Node (insert x l) y r -- 12+ | y < x = Node l y (insert x r) -- 22+ | otherwise = Node l y r -- 25+ before :: Int -> Tree -> Tree before _ Leaf = Leaf before y (Node l x r) = case y `compare` x of@@ -97,9 +109,13 @@ union t (Node l x r) = Node (union (before x t) l) x (union (beyond x t) r) +deriveExpress ''Tree++ instance Listable Tree where tiers = cons0 Leaf- \/ cons3 Node `suchThat` ordered+ \/ cons3 Node `suchThat` (\(Node l x r) -> (nil l || rightmost l < x)+ && (nil r || x < leftmost r)) instance Name Tree where name _ = "t1"@@ -124,8 +140,7 @@ main = do conjure "mem" mem [ con False- , fun "||" (||)- , fun "==" ((==) :: Int -> Int -> Bool)+ , con True , fun "<" ((<) :: Int -> Int -> Bool) , guard ]@@ -137,10 +152,18 @@ , ordcase (undefined :: Bool) ] + -- out of reach performance-wise as well (reaching 19 but needs size 25)+ conjure "insert" insert+ [ fun "Node" Node+ , fun "unit" unit+ , guard+ , fun "<" ((<) :: Int -> Int -> Bool)+ , maxSize 12+ ]+ -- simply out of reach performance-wise (reaching 16 but need size 22) conjure "insert" insert- [ con Leaf- , fun "Node" Node+ [ fun "Node" Node , fun "unit" unit , fun "`compare`" (compare :: Int -> Int -> Ordering) , ordcase (undefined :: Tree)@@ -189,6 +212,12 @@ , ordcase (undefined :: Tree) , maxSize 12 , maxEquationSize 7+ ]++ conjure "insert" insert+ [ fun "Node" Node+ , fun "before" before+ , fun "beyond" beyond ] -- reachable in 55s, candidate #173109 at size 13.
eg/bst.txt view
@@ -1,21 +1,28 @@ mem :: Int -> Tree -> Bool -- testing 360 combinations of argument values--- pruning with 20/30 rules--- 1 candidates of size 1+-- pruning with 9/17 rules+-- 2 candidates of size 1 -- 0 candidates of size 2 -- 0 candidates of size 3 -- 0 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6--- 0 candidates of size 7--- 24 candidates of size 8--- 48 candidates of size 9+-- 4 candidates of size 7+-- 0 candidates of size 8+-- 80 candidates of size 9 -- 0 candidates of size 10--- 180 candidates of size 11--- 80 candidates of size 12--- tested 274 candidates+-- 144 candidates of size 11+-- 48 candidates of size 12+-- 0 candidates of size 13+-- 1136 candidates of size 14+-- 0 candidates of size 15+-- 5056 candidates of size 16+-- tested 2632 candidates mem x Leaf = False-mem x (Node t1 y t2) = mem x t1 || (x == y || mem x t2)+mem x (Node t1 y t2)+ | x < y = mem x t1+ | y < x = mem x t2+ | otherwise = True mem :: Int -> Tree -> Bool -- testing 360 combinations of argument values@@ -41,22 +48,46 @@ insert :: Int -> Tree -> Tree -- testing 360 combinations of argument values--- pruning with 2/3 rules--- 2 candidates of size 1--- 0 candidates of size 2+-- pruning with 4/4 rules+-- 1 candidates of size 1+-- 1 candidates of size 2 -- 0 candidates of size 3--- 4 candidates of size 4--- 0 candidates of size 5--- 0 candidates of size 6--- 26 candidates of size 7--- 0 candidates of size 8--- 0 candidates of size 9--- 176 candidates of size 10--- 0 candidates of size 11--- 32 candidates of size 12--- tested 240 candidates+-- 1 candidates of size 4+-- 6 candidates of size 5+-- 1 candidates of size 6+-- 2 candidates of size 7+-- 22 candidates of size 8+-- 22 candidates of size 9+-- 39 candidates of size 10+-- 148 candidates of size 11+-- 310 candidates of size 12+-- tested 553 candidates insert = undefined -- search exhausted+-- could not find implementation using only+-- Node, unit, guarded equations, and (<)+-- consider increasing target/maxSize or refining the ingredients +insert :: Int -> Tree -> Tree+-- testing 360 combinations of argument values+-- pruning with 1/2 rules+-- 1 candidates of size 1+-- 1 candidates of size 2+-- 0 candidates of size 3+-- 1 candidates of size 4+-- 6 candidates of size 5+-- 1 candidates of size 6+-- 2 candidates of size 7+-- 25 candidates of size 8+-- 25 candidates of size 9+-- 42 candidates of size 10+-- 198 candidates of size 11+-- 380 candidates of size 12+-- tested 682 candidates+insert = undefined -- search exhausted+-- could not find implementation using only+-- Node, unit, compare, and case+-- consider increasing target/maxSize or refining the ingredients+ before :: Int -> Tree -> Tree -- pruning with 5/6 rules -- 2 candidates of size 1@@ -72,6 +103,9 @@ -- 3543 candidates of size 11 -- tested 5343 candidates before = undefined -- search exhausted+-- could not find implementation using only+-- Leaf, Node, (==), (<), and guarded equations+-- consider increasing target/maxSize or refining the ingredients beyond :: Int -> Tree -> Tree -- pruning with 5/6 rules@@ -88,41 +122,64 @@ -- 3543 candidates of size 11 -- tested 5343 candidates beyond = undefined -- search exhausted+-- could not find implementation using only+-- Leaf, Node, (==), (<=), and guarded equations+-- consider increasing target/maxSize or refining the ingredients before :: Int -> Tree -> Tree--- pruning with 2/4 rules+-- pruning with 3/5 rules -- 2 candidates of size 1 -- 2 candidates of size 2 -- 0 candidates of size 3 -- 4 candidates of size 4 -- 21 candidates of size 5 -- 0 candidates of size 6--- 68 candidates of size 7--- 287 candidates of size 8+-- 60 candidates of size 7+-- 176 candidates of size 8 -- 32 candidates of size 9--- 1216 candidates of size 10--- 5103 candidates of size 11--- 1472 candidates of size 12--- tested 8207 candidates+-- 716 candidates of size 10+-- 2373 candidates of size 11+-- 896 candidates of size 12+-- tested 4282 candidates before = undefined -- search exhausted+-- could not find implementation using only+-- Leaf, Node, compare, and case+-- consider increasing target/maxSize or refining the ingredients beyond :: Int -> Tree -> Tree--- pruning with 2/4 rules+-- pruning with 3/5 rules -- 2 candidates of size 1 -- 2 candidates of size 2 -- 0 candidates of size 3 -- 4 candidates of size 4 -- 21 candidates of size 5 -- 0 candidates of size 6--- 68 candidates of size 7--- 287 candidates of size 8+-- 60 candidates of size 7+-- 176 candidates of size 8 -- 32 candidates of size 9--- 1216 candidates of size 10--- 5103 candidates of size 11--- 1472 candidates of size 12--- tested 8207 candidates+-- 716 candidates of size 10+-- 2373 candidates of size 11+-- 896 candidates of size 12+-- tested 4282 candidates beyond = undefined -- search exhausted+-- could not find implementation using only+-- Leaf, Node, compare, and case+-- consider increasing target/maxSize or refining the ingredients +insert :: Int -> Tree -> Tree+-- testing 360 combinations of argument values+-- pruning with 3/6 rules+-- 1 candidates of size 1+-- 0 candidates of size 2+-- 2 candidates of size 3+-- 1 candidates of size 4+-- 1 candidates of size 5+-- 6 candidates of size 6+-- 2 candidates of size 7+-- 15 candidates of size 8+-- tested 25 candidates+insert x t1 = Node (before x t1) x (beyond x t1)+ union :: Tree -> Tree -> Tree -- testing 360 combinations of argument values -- pruning with 6/8 rules@@ -135,7 +192,10 @@ -- 152 candidates of size 7 -- 82 candidates of size 8 -- 2438 candidates of size 9--- 3970 candidates of size 10--- tested 6735 candidates+-- 4322 candidates of size 10+-- tested 7087 candidates union = undefined -- search exhausted+-- could not find implementation using only+-- Leaf, Node, before, and beyond+-- consider increasing target/maxSize or refining the ingredients
eg/count.txt view
@@ -1,12 +1,12 @@ count :: A -> [A] -> Int -- testing 13 combinations of argument values -- pruning with 1/2 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 1 candidates of size 2 -- 0 candidates of size 3 -- 0 candidates of size 4 -- 1 candidates of size 5--- tested 2 candidates+-- tested 3 candidates count x xs = length (filter (x ==) xs) count :: A -> [A] -> Int
eg/digits.txt view
@@ -61,4 +61,7 @@ -- 12715 candidates of size 7 -- tested 13449 candidates digitCount = undefined -- search exhausted+-- could not find implementation using only+-- 0, 10, (+), div, mod, (==), and guarded equations+-- consider increasing target/maxSize or refining the ingredients
eg/dupos.txt view
@@ -67,4 +67,7 @@ -- 1363 candidates of size 13 -- tested 1858 candidates positionsFrom = undefined -- search exhausted+-- could not find implementation using only+-- [], 1, (+), (:), (==), and guarded equations+-- consider increasing target/maxSize or refining the ingredients
eg/either.txt view
@@ -36,11 +36,11 @@ either :: (A -> A) -> (A -> A) -> Either A A -> A -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 1 candidates of size 2 -- 4 candidates of size 3 -- 12 candidates of size 4--- tested 11 candidates+-- tested 12 candidates either f g (Left x) = f x either f g (Right x) = g x @@ -51,4 +51,7 @@ -- 0 candidates of size 2 -- tested 1 candidates lefts = undefined -- search exhausted+-- could not find implementation using only+-- Left, Right, False, True, [], and (:)+-- consider increasing target/maxSize or refining the ingredients
eg/fib01.txt view
@@ -8,6 +8,9 @@ -- 27 candidates of size 5 -- tested 52 candidates fib01 = undefined -- search exhausted+-- could not find implementation using only+-- 0, dec, and (+)+-- consider increasing target/maxSize or refining the ingredients fib01 :: Int -> Int -> Int -> Int -- testing 8 combinations of argument values@@ -15,4 +18,7 @@ -- 4 candidates of size 1 -- tested 4 candidates fib01 = undefined -- search exhausted+-- could not find implementation using only+-- 0, (+), dec, (<=), and if-expressions+-- consider increasing target/maxSize or refining the ingredients
eg/ints.txt view
@@ -1,20 +1,20 @@ second :: [Int] -> Int -- testing 360 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 1 candidates of size 2--- 1 candidates of size 3--- tested 2 candidates+-- 2 candidates of size 3+-- tested 3 candidates second xs = head (tail xs) third :: [Int] -> Int -- testing 360 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 1 candidates of size 2 -- 1 candidates of size 3--- 1 candidates of size 4--- tested 3 candidates+-- 2 candidates of size 4+-- tested 4 candidates third xs = head (tail (tail xs)) sum :: [Int] -> Int
eg/list.hs view
@@ -83,13 +83,11 @@ , fun ":" ((:) :: Int -> [Int] -> [Int]) , fun "null" (null :: [Int] -> Bool) , guard- , fun "undefined" (undefined :: Int) ] conjure "last" last' [ con ([] :: [Int]) , fun ":" ((:) :: Int -> [Int] -> [Int])- , fun "undefined" (undefined :: Int) , maxPatternDepth 2 ] @@ -99,7 +97,7 @@ , fun "," ((,) :: Int -> Int -> (Int,Int)) ] - conjure "\\/" (\/)+ conjure "\\/" (Main.\/) [ con ([] :: [Int]) , fun ":" ((:) :: Int -> [Int] -> [Int]) ]
eg/list.txt view
@@ -56,9 +56,8 @@ -- 0 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6--- 4 candidates of size 7+-- 2 candidates of size 7 -- tested 2 candidates-last [] = undefined last (x:xs) | null xs = x | otherwise = last xs@@ -70,10 +69,9 @@ -- 0 candidates of size 2 -- 0 candidates of size 3 -- 1 candidates of size 4--- 2 candidates of size 5--- 2 candidates of size 6--- tested 6 candidates-last [] = undefined+-- 0 candidates of size 5+-- 1 candidates of size 6+-- tested 3 candidates last [x] = x last (x:y:xs) = last (y:xs)
eg/oddeven.txt view
@@ -31,22 +31,22 @@ odd :: Int -> Bool -- testing 6 combinations of argument values -- pruning with 36/55 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 3 candidates of size 3 -- 0 candidates of size 4 -- 44 candidates of size 5--- tested 30 candidates+-- tested 31 candidates odd x = 1 == x `mod` 2 even :: Int -> Bool -- testing 6 combinations of argument values -- pruning with 36/55 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 3 candidates of size 3 -- 0 candidates of size 4 -- 44 candidates of size 5--- tested 20 candidates+-- tested 21 candidates even x = 0 == x `mod` 2
eg/peano.hs view
@@ -7,7 +7,6 @@ -- Distributed under the 3-Clause BSD licence (see the file LICENSE). {-# LANGUAGE TemplateHaskell #-} import Conjure-import Test.LeanCheck data Peano = Z | S Peano deriving (Show, Eq)
eg/pow.hs view
@@ -23,15 +23,19 @@ ] -- 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+ -- pow b e+ -- | odd e = b * pow b (e - 1) -- 11+ -- | otherwise = square (pow b (halve e)) -- 16 conjure "pow" pow [ con (0::Int) , con (1::Int)--- , fun "sq" ((\x -> x*x) :: Int -> Int) -- cheat! OOM still+ , fun "square" ((\x -> x*x) :: Int -> Int) -- cheat , fun "*" ((*) :: Int -> Int -> Int)- , fun "halve" ((`div` 2) :: Int -> Int)- , iif (undefined :: Int)- , maxSize 6 -- OOM at size 9+ , fun "-" ((-) :: Int -> Int -> Int)+ , fun "halve" ((`div` 2) :: Int -> Int) -- cheat+ , fun "odd" (odd :: Int -> Bool)+ , guard+ , maxSize 6 -- remove to find the first version...+ -- simply out of reach:+ -- , maxSize 16, carryOn ]
eg/pow.txt view
@@ -15,13 +15,16 @@ pow :: Int -> Int -> Int -- testing 5 combinations of argument values--- pruning with 15/19 rules+-- pruning with 49/71 rules -- 4 candidates of size 1--- 2 candidates of size 2--- 5 candidates of size 3--- 9 candidates of size 4--- 31 candidates of size 5--- 178 candidates of size 6--- tested 229 candidates+-- 4 candidates of size 2+-- 17 candidates of size 3+-- 60 candidates of size 4+-- 294 candidates of size 5+-- 1386 candidates of size 6+-- tested 1765 candidates pow = undefined -- search exhausted+-- could not find implementation using only+-- 0, 1, square, (*), (-), halve, odd, and guarded equations+-- consider increasing target/maxSize or refining the ingredients
eg/sort.txt view
@@ -67,6 +67,9 @@ -- 3728 candidates of size 16 -- tested 5768 candidates merge = undefined -- search exhausted+-- could not find implementation using only+-- [], (:), (<=), and guarded equations+-- consider increasing target/maxSize or refining the ingredients qsort :: [Int] -> [Int] -- testing 9 combinations of argument values
eg/spec.txt view
@@ -29,11 +29,11 @@ -- pruning with 3/3 rules -- 2 candidates of size 1 -- 4 candidates of size 2--- 11 candidates of size 3--- 31 candidates of size 4--- 94 candidates of size 5--- 225 candidates of size 6--- tested 286 candidates+-- 13 candidates of size 3+-- 35 candidates of size 4+-- 113 candidates of size 5+-- 288 candidates of size 6+-- tested 347 candidates [] ++ xs = xs (x:xs) ++ ys = x:(xs ++ ys)
eg/subset.txt view
@@ -16,11 +16,11 @@ subset :: [Int] -> [Int] -> Bool -- testing 44 combinations of argument values -- pruning with 3/3 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 2 candidates of size 3 -- 6 candidates of size 4 -- 2 candidates of size 5--- tested 9 candidates+-- tested 10 candidates subset xs ys = sort xs `isSubsequenceOf` sort ys
eg/these.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE TemplateHaskell #-} import Conjure-import Test.LeanCheck -- This was inspired by the These datatype from the cathis package.
eg/these.txt view
@@ -1,7 +1,7 @@ fromThese :: A -> B -> These A B -> (A,B) -- testing 4 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 1 candidates of size 3 -- 0 candidates of size 4@@ -11,7 +11,7 @@ -- 0 candidates of size 8 -- 0 candidates of size 9 -- 1 candidates of size 10--- tested 2 candidates+-- tested 3 candidates fromThese x y Neither = (x,y) fromThese x y (This z) = (z,y) fromThese x y (That z) = (x,z)
eg/tree.hs view
@@ -97,15 +97,13 @@ main :: IO () main = do conjure "leftmost" leftmost- [ fun "undefined" (undefined :: Int)- , iif (undefined :: Int)- , fun "nil" nil+ [ fun "nil" nil+ , guard ] conjure "rightmost" rightmost- [ fun "undefined" (undefined :: Int)- , iif (undefined :: Int)- , fun "nil" nil+ [ fun "nil" nil+ , guard ] conjure "size" size
eg/tree.txt view
@@ -7,12 +7,11 @@ -- 0 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6--- 16 candidates of size 7+-- 8 candidates of size 7 -- tested 2 candidates-leftmost Leaf = undefined-leftmost (Node t1 x t2) = if nil t1- then x- else leftmost t1+leftmost (Node t1 x t2)+ | nil t1 = x+ | otherwise = leftmost t1 rightmost :: Tree -> Int -- testing 360 combinations of argument values@@ -23,12 +22,11 @@ -- 0 candidates of size 4 -- 0 candidates of size 5 -- 0 candidates of size 6--- 16 candidates of size 7--- tested 11 candidates-rightmost Leaf = undefined-rightmost (Node t1 x t2) = if nil t2- then x- else rightmost t2+-- 8 candidates of size 7+-- tested 7 candidates+rightmost (Node t1 x t2)+ | nil t2 = x+ | otherwise = rightmost t2 size :: Tree -> Int -- testing 360 combinations of argument values@@ -96,14 +94,17 @@ -- 712 candidates of size 12 -- tested 1127 candidates ordered = undefined -- search exhausted+-- could not find implementation using only+-- True, False, (&&), (||), (<), rightmost, leftmost, and nil+-- consider increasing target/maxSize or refining the ingredients ordered :: Tree -> Bool -- testing 360 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 0 candidates of size 2 -- 1 candidates of size 3--- tested 1 candidates+-- tested 2 candidates ordered t1 = strictlyOrdered (inorder t1) preorder :: Tree -> [Int]
eg/tuple.txt view
@@ -1,27 +1,27 @@ fst :: (A,A) -> A -- testing 4 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 2 candidates of size 2--- tested 1 candidates+-- tested 2 candidates fst (x,y) = x snd :: (A,A) -> A -- testing 4 combinations of argument values -- pruning with 0/0 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 2 candidates of size 2--- tested 2 candidates+-- tested 3 candidates snd (x,y) = y swap :: (A,A) -> (A,A) -- testing 4 combinations of argument values -- pruning with 10/10 rules -- 1 candidates of size 1--- 0 candidates of size 2+-- 1 candidates of size 2 -- 0 candidates of size 3 -- 4 candidates of size 4--- tested 4 candidates+-- tested 5 candidates swap (x,y) = (y,x) curry :: ((A,A) -> A) -> A -> A -> A@@ -35,11 +35,11 @@ uncurry :: (A -> A -> A) -> (A,A) -> A -- pruning with 10/10 rules--- 0 candidates of size 1+-- 1 candidates of size 1 -- 4 candidates of size 2 -- 0 candidates of size 3 -- 4 candidates of size 4--- tested 6 candidates+-- tested 7 candidates uncurry f (x,y) = f x y pairwise :: [A] -> [(A,A)]
src/Conjure.hs view
@@ -120,11 +120,27 @@ , reifyEquality , reifyTiers , conjureType- , Name (..)- , Express (..) , deriveConjurable , deriveConjurableIfNeeded , deriveConjurableCascading+ , Name (..)+ , Express (..)+ , Listable (..)+ , cons0+ , cons1+ , cons2+ , cons3+ , cons4+ , cons5+ , cons6+ , (\/)+ , reset+ , cons7+ , cons8+ , cons9+ , cons10+ , cons11+ , cons12 -- * Pure interfaces , Results (..)
src/Conjure/Conjurable.hs view
@@ -41,6 +41,22 @@ , cevl , Name (..) , Express (..)+ , Listable (..)+ , cons0+ , cons1+ , cons2+ , cons3+ , cons4+ , cons5+ , cons6+ , (\/)+ , reset+ , cons7+ , cons8+ , cons9+ , cons10+ , cons11+ , cons12 , conjureArgumentPats , conjureMostGeneralCanonicalVariation , conjureCasesFor@@ -149,6 +165,10 @@ conjureSubTypes :: a -> Reification conjureSubTypes _ = id + -- | Returns an undefined value of the return value type.+ conjureUndefined :: a -> Expr+ conjureUndefined x = value "undefined" (undefined `asTypeOf` x)+ -- | Returns an if-function encoded as an 'Expr'. conjureIf :: a -> Expr conjureIf = ifFor@@ -619,6 +639,7 @@ conjureArgumentHoles f = hole (argTy f) : conjureArgumentHoles (f undefined) conjureResultHole f = conjureResultHole (f undefined) conjureSubTypes f = conjureType (argTy f) . conjureType (resTy f)+ conjureUndefined f = conjureUndefined (f undefined) conjureIf f = conjureIf (f undefined) conjureArgumentCases f = conjureCases (argTy f) : conjureArgumentCases (f undefined) conjureExpress f e
src/Conjure/Defn.hs view
@@ -70,7 +70,7 @@ -- > sum [] = 0 -- > sum (x:xs) = x + sum xs showDefn :: Defn -> String-showDefn = unlines . map show1+showDefn = unlines . map show1 . removeUndefinedBindings where show1 (lhs,rhs) = case rhs of@@ -356,3 +356,15 @@ | otherwise = d reduce (lhs :$ _, rhs :$ _) = (lhs, rhs) reduce _ = error "Conjure.Defn.etaReduce: the impossible happened, this is a bug"+++removeUndefinedBindings :: Defn -> Defn+removeUndefinedBindings defn =+ case u defn of+ [] -> defn+ bs -> bs+ where+ u [] = []+ u ((lhs,Value "undefined" _):bs)+ | nor [lhs `isInstanceOf` l | (l,_) <- bs] = removeUndefinedBindings bs+ u (b:bs) = b:removeUndefinedBindings bs
src/Conjure/Engine.hs view
@@ -159,7 +159,7 @@ -- -- This works like the functions 'conjure' and 'conjureFromSpec' combined. conjure0 :: Conjurable f => String -> f -> (f -> [Property]) -> [Ingredient] -> IO ()-conjure0 nm f p es = do+conjure0 nm f p ingredients = do -- the code section below became quite ugly with time and patches. -- it is still maintainable and readable as it is, but perhaps -- needs to be cleaned up and simplified@@ -201,8 +201,14 @@ where showEq eq = showExpr (fst eq) ++ " == " ++ showExpr (snd eq) pr :: Integer -> Int -> Int -> [([Defn], [Defn])] -> IO ()- pr t0 n t [] = do putWithTimeSince t0 $ "tested " ++ show t ++ " candidates"- putStrLn $ nm ++ " = undefined -- search exhausted\n"+ pr t0 n t [] = do+ putWithTimeSince t0 $ "tested " ++ show t ++ " candidates"+ putStrLn $ nm ++ " = undefined -- search exhausted"+ when (not carryOn) $+ putStrLn $ "-- could not find implementation using only\n-- "+ ++ command [showSymbol e | (e,_) <- actual ingredients]+ ++ "\n-- consider increasing target/maxSize or refining the ingredients"+ putStrLn "" pr t0 n t ((is,cs):rs) = do let nc = length cs putWithTimeSince t0 $ show nc ++ " candidates of size " ++ show n@@ -221,21 +227,25 @@ putStrLn $ showDefn $ etaReduce $ normalizeDefn thy i when carryOn $ pr1 t' is (drop 1 cs'') rs = zip iss css- results = conjpure0 nm f p es+ results = conjpure0 nm f p ingredients iss = implementationss results css = candidatess results ts = bindings results thy = theory results nRules = length (rules thy) nREs = length (equations thy) + nRules+ showSymbol e+ | isGuardSymbol e = "guarded equations"+ | isIfSymbol e = "if-expressions"+ | otherwise = showExpr e -- we could avoid the following as most are called once -- but is nice to have a summary of which settings are used- carryOn = carryOnI es- showTests = showTestsI es- showTheory = showTheoryI es- showPatterns = showPatternsI es- showCandidates = showCandidatesI es- showDeconstructions = showDeconstructionsI es+ carryOn = carryOnI ingredients+ showTests = showTestsI ingredients+ showTheory = showTheoryI ingredients+ showPatterns = showPatternsI ingredients+ showCandidates = showCandidatesI ingredients+ showDeconstructions = showDeconstructionsI ingredients -- | Results to the 'conjpure' family of functions.@@ -267,7 +277,7 @@ -- 'conjpure', 'conjpureFromSpec', 'conjure' and 'conjureFromSpec' -- all refer to this. conjpure0 :: Conjurable f => String -> f -> (f -> [Property]) -> [Ingredient] -> Results-conjpure0 nm f p es = Results+conjpure0 nm f p is = Results { implementationss = implementationsT , candidatess = candidatesT , bindings = tests@@ -284,17 +294,17 @@ $ (if target > 0 then targetiers target else id) $ (if maxSize > 0 then take maxSize else id) $ candidatesTT- (candidatesTT, thy, patternss, deconstructions) = candidateDefns nm f es+ (candidatesTT, thy, patternss, deconstructions) = candidateDefns nm f is test dfn = all (errorToFalse . deval (conjureExpress f) maxRecursions dfn False) $ [funToVar lhs -==- rhs | (lhs, rhs) <- tests] tests = conjureTestDefn maxTests maxSearchTests nm f (-==-) = conjureMkEquation f- maxTests = maxTestsI es- (target, maxSize) = targetAndMaxSizeI es- maxRecursions = maxRecursionsI es- maxSearchTests = maxSearchTestsI es- uniqueCandidates = uniqueCandidatesI es+ maxTests = maxTestsI is+ (target, maxSize) = targetAndMaxSizeI is+ maxRecursions = maxRecursionsI is+ maxSearchTests = maxSearchTestsI is+ uniqueCandidates = uniqueCandidatesI is -- | Return apparently unique candidate definitions.@@ -396,8 +406,8 @@ | otherwise = conjurePats maxPatternDepth es nm f partialDefns = concatMapT partialDefnsFromPats pats -- replaces the any guard symbol with a guard of the correct type- ps = actual is -- extract actual ingredients/primitives from the list- es = [if isGuardSymbol e then conjureGuard f else e | (e,_) <- ps]+ ais = actual is+ es = [if isGuardSymbol e then conjureGuard f else e | (e,_) <- ais] eh = conjureResultHole f efxs = conjureVarApplication nm f@@ -423,10 +433,10 @@ keepConstant | maxConstantSize > 0 = \e -> isFun e || isConst e || not (isGround e) || size e <= maxConstantSize | otherwise = const True - isRedundant | adHocRedundancy = \e -> isRedundantDefn e || isRedundantModuloRewriting (normalize thy) e+ isRedundant | assortedPruning = \e -> isRedundantDefn e || isRedundantModuloRewriting (normalize thy) e | otherwise = const False - hasRedundant | adHocRedundancy = hasRedundantRecursion+ hasRedundant | assortedPruning = hasRedundantRecursion | otherwise = const False isNumeric = conjureIsNumeric f@@ -458,6 +468,7 @@ | copyBindings && isGroundPat f pat = [[(pat, toValPat f pat)]] | otherwise = mapT (pat,) . filterT keepB+ . insemptier (conjureUndefined f) . appsWith pat . drop 1 -- this excludes the function name itself $ vars pat ++ [eh | any (uncurry should) (zip aess aes)]@@ -549,8 +560,8 @@ thy = doubleCheck (===) . theoryFromAtoms (===) maxEquationSize . (:[]) . nub- $ cjHoles (fun nm f:ps) ++ [val False, val True] ++ es- (===) = cjAreEqual (fun nm f:ps) maxTests+ $ cjHoles (fun nm f:ais) ++ [val False, val True] ++ es+ (===) = cjAreEqual (fun nm f:ais) maxTests isUnbreakable = conjureIsUnbreakable f maxTests = maxTestsI is@@ -563,7 +574,7 @@ requireDescent = requireDescentI is maxEarlyTests = maxEarlyTestsI is copyBindings = copyBindingsI is- adHocRedundancy = assortedPruningI is -- TODO: rename+ assortedPruning = assortedPruningI is -- TODO: rename atomicNumbers = atomicNumbersI is rewriting = rewriteI is @@ -720,3 +731,9 @@ catconMapT f = foldr (\+:/) [] . map (foldr (\/) []) . mapT f where xss \+:/ yss = ([]:yss) \/ xss++-- | If the first tier is empty,+-- populate it with the given value.+insemptier :: a -> [[a]] -> [[a]]+insemptier x ([]:xss) = [x]:xss+insemptier _ xss = xss
src/Conjure/Expr.hs view
@@ -39,6 +39,7 @@ , isGuardSymbol , isGuard , hasGuard+ , isIfSymbol , mapInnerFirstOuterLast , mappArgs , mappFun@@ -599,6 +600,10 @@ isGuardSymbol :: Expr -> Bool isGuardSymbol (Value "|" _) = True isGuardSymbol _ = False++isIfSymbol :: Expr -> Bool+isIfSymbol (Value "if" _) = True+isIfSymbol _ = False -- | Is the expression a guard application? isGuard :: Expr -> Bool
src/Conjure/Ingredient.hs view
@@ -165,8 +165,12 @@ -- > | otherwise = last xs guard :: Ingredient guard = (guardFor (undefined :: Bool), conjureType (undefined :: Bool))--- internally we always return a guard of the Bool return type,--- this is replaced by Conjure when enumerating candidates+-- Internally we always return a guard of the Bool return type,+-- this is replaced by Conjure when enumerating candidates.+-- The choice of Bool here is not incidental:+-- when reifying types based on this,+-- only Bool type information would be included.+-- With other types as the element type, we would have a spurious inclusion. -- | Provides a case condition bound to the given return type.
src/Conjure/Utils.hs view
@@ -40,6 +40,7 @@ , classifyBy -- from LeanCheck.Stats , classifyOn -- from LeanCheck.Stats , none+ , nor , updateAt , first , second@@ -47,6 +48,7 @@ , (+++) , isSubsetOf , prods+ , command ) where @@ -176,6 +178,9 @@ none :: (a -> Bool) -> [a] -> Bool none p = not . any p +nor :: [Bool] -> Bool+nor = not . or+ -- | Updates the value in a list at a given position. -- -- > > updateAt 2 (*10) [1,2,3,4]@@ -224,3 +229,18 @@ prods :: [[a]] -> [[a]] prods [] = [[]] prods (xs:xss) = [y:ys | y <- xs, ys <- prods xss]++-- | Separate a list of strings using comma-and-and.+--+-- This function includes the Oxford comma.+--+-- > > command ["this", "that"]+-- > "this and that"+--+-- > > command ["this", "that", "these"]+-- > "this, that, and these"+command :: [String] -> String+command [] = "nothing"+command [x] = x+command [x,y] = x ++ " and " ++ y+command xs = intercalate ", " (init xs) ++ ", and " ++ (last xs)