packages feed

code-conjure 0.6.10 → 0.7.0

raw patch · 147 files changed

+2714/−2090 lines, 147 filesdep ~expressdep ~leancheckdep ~speculatePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: express, leancheck, speculate

API changes (from Hackage documentation)

- Conjure: Args :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Args
- Conjure: [adHocRedundancy] :: Args -> Bool
- Conjure: [atomicNumbers] :: Args -> Bool
- Conjure: [carryOn] :: Args -> Bool
- Conjure: [copyBindings] :: Args -> Bool
- Conjure: [earlyTests] :: Args -> Bool
- Conjure: [maxConstantSize] :: Args -> Int
- Conjure: [maxDeconstructionSize] :: Args -> Int
- Conjure: [maxEquationSize] :: Args -> Int
- Conjure: [maxEvalRecursions] :: Args -> Int
- Conjure: [maxPatternDepth] :: Args -> Int
- Conjure: [maxPatternSize] :: Args -> Int
- Conjure: [maxSearchTests] :: Args -> Int
- Conjure: [maxSize] :: Args -> Int
- Conjure: [maxTests] :: Args -> Int
- Conjure: [requireDescent] :: Args -> Bool
- Conjure: [requireZero] :: Args -> Bool
- Conjure: [rewriting] :: Args -> Bool
- Conjure: [showCandidates] :: Args -> Bool
- Conjure: [showDeconstructions] :: Args -> Bool
- Conjure: [showPatterns] :: Args -> Bool
- Conjure: [showRuntime] :: Args -> Bool
- Conjure: [showTests] :: Args -> Bool
- Conjure: [showTheory] :: Args -> Bool
- Conjure: [target] :: Args -> Int
- Conjure: [uniqueCandidates] :: Args -> Bool
- Conjure: [usePatterns] :: Args -> Bool
- Conjure: args :: Args
- Conjure: conjpureWith :: Conjurable f => Args -> String -> f -> [Prim] -> Results
- Conjure: conjureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> IO ()
- Conjure: conjureWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO ()
- Conjure: conjureWithMaxSize :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()
- Conjure: data Args
- Conjure: prif :: Conjurable a => a -> Prim
- Conjure: primOrdCaseFor :: Conjurable a => a -> Prim
- Conjure.Engine: Args :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Args
- Conjure.Engine: [adHocRedundancy] :: Args -> Bool
- Conjure.Engine: [atomicNumbers] :: Args -> Bool
- Conjure.Engine: [carryOn] :: Args -> Bool
- Conjure.Engine: [copyBindings] :: Args -> Bool
- Conjure.Engine: [earlyTests] :: Args -> Bool
- Conjure.Engine: [maxConstantSize] :: Args -> Int
- Conjure.Engine: [maxDeconstructionSize] :: Args -> Int
- Conjure.Engine: [maxEquationSize] :: Args -> Int
- Conjure.Engine: [maxEvalRecursions] :: Args -> Int
- Conjure.Engine: [maxPatternDepth] :: Args -> Int
- Conjure.Engine: [maxPatternSize] :: Args -> Int
- Conjure.Engine: [maxSearchTests] :: Args -> Int
- Conjure.Engine: [maxSize] :: Args -> Int
- Conjure.Engine: [maxTests] :: Args -> Int
- Conjure.Engine: [requireDescent] :: Args -> Bool
- Conjure.Engine: [requireZero] :: Args -> Bool
- Conjure.Engine: [rewriting] :: Args -> Bool
- Conjure.Engine: [showCandidates] :: Args -> Bool
- Conjure.Engine: [showDeconstructions] :: Args -> Bool
- Conjure.Engine: [showPatterns] :: Args -> Bool
- Conjure.Engine: [showRuntime] :: Args -> Bool
- Conjure.Engine: [showTests] :: Args -> Bool
- Conjure.Engine: [showTheory] :: Args -> Bool
- Conjure.Engine: [target] :: Args -> Int
- Conjure.Engine: [uniqueCandidates] :: Args -> Bool
- Conjure.Engine: [usePatterns] :: Args -> Bool
- Conjure.Engine: args :: Args
- Conjure.Engine: candidateDefns1 :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy, [[Defn]], [Expr])
- Conjure.Engine: candidateDefnsC :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy, [[Defn]], [Expr])
- Conjure.Engine: conjpure0With :: Conjurable f => Args -> String -> f -> (f -> Bool) -> [Prim] -> Results
- Conjure.Engine: conjpureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> Results
- Conjure.Engine: conjpureWith :: Conjurable f => Args -> String -> f -> [Prim] -> Results
- Conjure.Engine: conjure0With :: Conjurable f => Args -> String -> f -> (f -> Bool) -> [Prim] -> IO ()
- Conjure.Engine: conjureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> IO ()
- Conjure.Engine: conjureTheory :: Conjurable f => String -> f -> [Prim] -> IO ()
- Conjure.Engine: conjureTheoryWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO ()
- Conjure.Engine: conjureWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO ()
- Conjure.Engine: conjureWithMaxSize :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()
- Conjure.Engine: data Args
- Conjure.Prim: cjAreEqual :: [Prim] -> Int -> Expr -> Expr -> Bool
- Conjure.Prim: cjHoles :: [Prim] -> [Expr]
- Conjure.Prim: cjMkEquation :: [Prim] -> Expr -> Expr -> Expr
- Conjure.Prim: cjTiersFor :: [Prim] -> Expr -> [[Expr]]
- Conjure.Prim: guard :: Prim
- Conjure.Prim: pr :: (Conjurable a, Show a) => a -> Prim
- Conjure.Prim: prif :: Conjurable a => a -> Prim
- Conjure.Prim: prim :: Conjurable a => String -> a -> Prim
- Conjure.Prim: primOrdCaseFor :: Conjurable a => a -> Prim
- Conjure.Prim: type Prim = (Expr, Reification)
+ Conjure: carryOn :: Ingredient
+ Conjure: con :: (Conjurable a, Show a) => a -> Ingredient
+ Conjure: dontCopyBindings :: Ingredient
+ Conjure: dontRequireDescent :: Ingredient
+ Conjure: dontRewrite :: Ingredient
+ Conjure: fun :: Conjurable a => String -> a -> Ingredient
+ Conjure: iif :: Conjurable a => a -> Ingredient
+ Conjure: maxConstantSize :: Int -> Ingredient
+ Conjure: maxDeconstructionSize :: Int -> Ingredient
+ Conjure: maxEquationSize :: Int -> Ingredient
+ Conjure: maxPatternDepth :: Int -> Ingredient
+ Conjure: maxPatternSize :: Int -> Ingredient
+ Conjure: maxRecursions :: Int -> Ingredient
+ Conjure: maxSearchTests :: Int -> Ingredient
+ Conjure: maxSize :: Int -> Ingredient
+ Conjure: maxTests :: Int -> Ingredient
+ Conjure: nonAtomicNumbers :: Ingredient
+ Conjure: omitAssortedPruning :: Ingredient
+ Conjure: omitEarlyTests :: Ingredient
+ Conjure: ordcase :: Conjurable a => a -> Ingredient
+ Conjure: showCandidates :: Ingredient
+ Conjure: showDeconstructions :: Ingredient
+ Conjure: showPatterns :: Ingredient
+ Conjure: showTests :: Ingredient
+ Conjure: showTheory :: Ingredient
+ Conjure: singlePattern :: Ingredient
+ Conjure: target :: Int -> Ingredient
+ Conjure: type Ingredient = (Expr, Reification)
+ Conjure: uniqueCandidates :: Ingredient
+ Conjure.Engine: carryOn :: Ingredient
+ Conjure.Engine: dontCopyBindings :: Ingredient
+ Conjure.Engine: dontRequireDescent :: Ingredient
+ Conjure.Engine: dontRewrite :: Ingredient
+ Conjure.Engine: maxConstantSize :: Int -> Ingredient
+ Conjure.Engine: maxDeconstructionSize :: Int -> Ingredient
+ Conjure.Engine: maxEquationSize :: Int -> Ingredient
+ Conjure.Engine: maxPatternDepth :: Int -> Ingredient
+ Conjure.Engine: maxPatternSize :: Int -> Ingredient
+ Conjure.Engine: maxRecursions :: Int -> Ingredient
+ Conjure.Engine: maxSearchTests :: Int -> Ingredient
+ Conjure.Engine: maxSize :: Int -> Ingredient
+ Conjure.Engine: maxTests :: Int -> Ingredient
+ Conjure.Engine: nonAtomicNumbers :: Ingredient
+ Conjure.Engine: omitAssortedPruning :: Ingredient
+ Conjure.Engine: omitEarlyTests :: Ingredient
+ Conjure.Engine: showCandidates :: Ingredient
+ Conjure.Engine: showDeconstructions :: Ingredient
+ Conjure.Engine: showPatterns :: Ingredient
+ Conjure.Engine: showTests :: Ingredient
+ Conjure.Engine: showTheory :: Ingredient
+ Conjure.Engine: singlePattern :: Ingredient
+ Conjure.Engine: target :: Int -> Ingredient
+ Conjure.Engine: uniqueCandidates :: Ingredient
+ Conjure.Expr: mapInnerFirstOuterLast :: (Expr -> Expr) -> Expr -> Expr
+ Conjure.Ingredient: cjAreEqual :: [Ingredient] -> Int -> Expr -> Expr -> Bool
+ Conjure.Ingredient: cjHoles :: [Ingredient] -> [Expr]
+ Conjure.Ingredient: cjMkEquation :: [Ingredient] -> Expr -> Expr -> Expr
+ Conjure.Ingredient: cjTiersFor :: [Ingredient] -> Expr -> [[Expr]]
+ Conjure.Ingredient: con :: (Conjurable a, Show a) => a -> Ingredient
+ Conjure.Ingredient: fun :: Conjurable a => String -> a -> Ingredient
+ Conjure.Ingredient: guard :: Ingredient
+ Conjure.Ingredient: iif :: Conjurable a => a -> Ingredient
+ Conjure.Ingredient: ordcase :: Conjurable a => a -> Ingredient
+ Conjure.Ingredient: pr :: (Conjurable a, Show a) => a -> Ingredient
+ Conjure.Ingredient: prif :: Conjurable a => a -> Ingredient
+ Conjure.Ingredient: prim :: Conjurable a => String -> a -> Ingredient
+ Conjure.Ingredient: primOrdCaseFor :: Conjurable a => a -> Ingredient
+ Conjure.Ingredient: type Ingredient = (Expr, Reification)
+ Conjure.Ingredient: type Prim = Ingredient
+ Conjure.Settings: actual :: [Ingredient] -> [Ingredient]
+ Conjure.Settings: assortedPruningI :: [Ingredient] -> Bool
+ Conjure.Settings: atomicNumbersI :: [Ingredient] -> Bool
+ Conjure.Settings: carryOn :: Ingredient
+ Conjure.Settings: carryOnI :: [Ingredient] -> Bool
+ Conjure.Settings: copyBindingsI :: [Ingredient] -> Bool
+ Conjure.Settings: dontCopyBindings :: Ingredient
+ Conjure.Settings: dontRequireDescent :: Ingredient
+ Conjure.Settings: dontRewrite :: Ingredient
+ Conjure.Settings: earlyTestsI :: [Ingredient] -> Bool
+ Conjure.Settings: instance GHC.Classes.Eq Conjure.Settings.Setting
+ Conjure.Settings: instance GHC.Classes.Ord Conjure.Settings.Setting
+ Conjure.Settings: instance GHC.Read.Read Conjure.Settings.Setting
+ Conjure.Settings: instance GHC.Show.Show Conjure.Settings.Setting
+ Conjure.Settings: maxConstantSize :: Int -> Ingredient
+ Conjure.Settings: maxConstantSizeI :: [Ingredient] -> Int
+ Conjure.Settings: maxDeconstructionSize :: Int -> Ingredient
+ Conjure.Settings: maxDeconstructionSizeI :: [Ingredient] -> Int
+ Conjure.Settings: maxEquationSize :: Int -> Ingredient
+ Conjure.Settings: maxEquationSizeI :: [Ingredient] -> Int
+ Conjure.Settings: maxPatternDepth :: Int -> Ingredient
+ Conjure.Settings: maxPatternDepthI :: [Ingredient] -> Int
+ Conjure.Settings: maxPatternSize :: Int -> Ingredient
+ Conjure.Settings: maxPatternSizeI :: [Ingredient] -> Int
+ Conjure.Settings: maxRecursions :: Int -> Ingredient
+ Conjure.Settings: maxRecursionsI :: [Ingredient] -> Int
+ Conjure.Settings: maxSearchTests :: Int -> Ingredient
+ Conjure.Settings: maxSearchTestsI :: [Ingredient] -> Int
+ Conjure.Settings: maxSize :: Int -> Ingredient
+ Conjure.Settings: maxTests :: Int -> Ingredient
+ Conjure.Settings: maxTestsI :: [Ingredient] -> Int
+ Conjure.Settings: nonAtomicNumbers :: Ingredient
+ Conjure.Settings: omitAssortedPruning :: Ingredient
+ Conjure.Settings: omitEarlyTests :: Ingredient
+ Conjure.Settings: requireDescentI :: [Ingredient] -> Bool
+ Conjure.Settings: rewriteI :: [Ingredient] -> Bool
+ Conjure.Settings: showCandidates :: Ingredient
+ Conjure.Settings: showCandidatesI :: [Ingredient] -> Bool
+ Conjure.Settings: showDeconstructions :: Ingredient
+ Conjure.Settings: showDeconstructionsI :: [Ingredient] -> Bool
+ Conjure.Settings: showPatterns :: Ingredient
+ Conjure.Settings: showPatternsI :: [Ingredient] -> Bool
+ Conjure.Settings: showTests :: Ingredient
+ Conjure.Settings: showTestsI :: [Ingredient] -> Bool
+ Conjure.Settings: showTheory :: Ingredient
+ Conjure.Settings: showTheoryI :: [Ingredient] -> Bool
+ Conjure.Settings: singlePattern :: Ingredient
+ Conjure.Settings: singlePatternI :: [Ingredient] -> Bool
+ Conjure.Settings: target :: Int -> Ingredient
+ Conjure.Settings: targetAndMaxSizeI :: [Ingredient] -> (Int, Int)
+ Conjure.Settings: uniqueCandidates :: Ingredient
+ Conjure.Settings: uniqueCandidatesI :: [Ingredient] -> Bool
+ Conjure.Utils: curry :: ((a, b) -> c) -> a -> b -> c
+ Conjure.Utils: data Solo a
+ Conjure.Utils: fst :: (a, b) -> a
+ Conjure.Utils: getSolo :: Solo a -> a
+ Conjure.Utils: notNull :: [a] -> Bool
+ Conjure.Utils: pattern Solo :: a -> Solo a
+ Conjure.Utils: snd :: (a, b) -> b
+ Conjure.Utils: swap :: (a, b) -> (b, a)
+ Conjure.Utils: uncurry :: (a -> b -> c) -> (a, b) -> c
- Conjure: class () => Name a
+ Conjure: class Name a
- Conjure: conjpure :: Conjurable f => String -> f -> [Prim] -> Results
+ Conjure: conjpure :: Conjurable f => String -> f -> [Ingredient] -> Results
- Conjure: conjure :: Conjurable f => String -> f -> [Prim] -> IO ()
+ Conjure: conjure :: Conjurable f => String -> f -> [Ingredient] -> IO ()
- Conjure: conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> IO ()
+ Conjure: conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Ingredient] -> IO ()
- Conjure: data () => A
+ Conjure: data A
- Conjure: data () => B
+ Conjure: data B
- Conjure: data () => C
+ Conjure: data C
- Conjure: data () => D
+ Conjure: data D
- Conjure: data () => E
+ Conjure: data E
- Conjure: data () => Expr
+ Conjure: data Expr
- Conjure: data () => F
+ Conjure: data F
- Conjure: guard :: Prim
+ Conjure: guard :: Ingredient
- Conjure: pr :: (Conjurable a, Show a) => a -> Prim
+ Conjure: pr :: (Conjurable a, Show a) => a -> Ingredient
- Conjure: prim :: Conjurable a => String -> a -> Prim
+ Conjure: prim :: Conjurable a => String -> a -> Ingredient
- Conjure: type Prim = (Expr, Reification)
+ Conjure: type Prim = Ingredient
- Conjure.Conjurable: class () => Name a
+ Conjure.Conjurable: class Name a
- Conjure.Conjurable: data () => A
+ Conjure.Conjurable: data A
- Conjure.Conjurable: data () => B
+ Conjure.Conjurable: data B
- Conjure.Conjurable: data () => C
+ Conjure.Conjurable: data C
- Conjure.Conjurable: data () => D
+ Conjure.Conjurable: data D
- Conjure.Conjurable: data () => E
+ Conjure.Conjurable: data E
- Conjure.Conjurable: data () => F
+ Conjure.Conjurable: data F
- Conjure.Engine: candidateDefns :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy, [[Defn]], [Expr])
+ Conjure.Engine: candidateDefns :: Conjurable f => String -> f -> [Ingredient] -> ([[Defn]], Thy, [[Defn]], [Expr])
- Conjure.Engine: candidateExprs :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Expr]], Thy, [[Defn]], [Expr])
+ Conjure.Engine: candidateExprs :: Conjurable f => String -> f -> [Ingredient] -> ([[Expr]], Thy, [[Defn]], [Expr])
- Conjure.Engine: class () => Name a
+ Conjure.Engine: class Name a
- Conjure.Engine: conjpure :: Conjurable f => String -> f -> [Prim] -> Results
+ Conjure.Engine: conjpure :: Conjurable f => String -> f -> [Ingredient] -> Results
- Conjure.Engine: conjpure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Prim] -> Results
+ Conjure.Engine: conjpure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Ingredient] -> Results
- Conjure.Engine: conjpureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> Results
+ Conjure.Engine: conjpureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Ingredient] -> Results
- Conjure.Engine: conjure :: Conjurable f => String -> f -> [Prim] -> IO ()
+ Conjure.Engine: conjure :: Conjurable f => String -> f -> [Ingredient] -> IO ()
- Conjure.Engine: conjure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Prim] -> IO ()
+ Conjure.Engine: conjure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Ingredient] -> IO ()
- Conjure.Engine: conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> IO ()
+ Conjure.Engine: conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Ingredient] -> IO ()
- Conjure.Engine: data () => Expr
+ Conjure.Engine: data Expr
- Conjure.Expr: class () => Name a
+ Conjure.Expr: class Name a
- Conjure.Expr: data () => Expr
+ Conjure.Expr: data Expr
- Conjure.Reason: data () => Thy
+ Conjure.Reason: data Thy

Files

.gitignore view
@@ -86,3 +86,4 @@ test/defn test/derive test/red+test/factorial
Makefile view
@@ -8,10 +8,6 @@   $(shell grep -q "Arch Linux" /etc/lsb-release && echo -dynamic) # -Wall -Werror -Wno-unused-matches -Wno-orphans -Wno-name-shadowing -Wno-incomplete-uni-patterns -Wno-unused-pattern-binds HADDOCKFLAGS = \-  -i $(shell find ~/.cabal -name leancheck.haddock | tail -1) \-  -i $(shell find ~/.cabal -name express.haddock   | tail -1) \-  -i $(shell find ~/.cabal -name speculate.haddock | tail -1) \-  -i $(shell find /usr/share/doc/ghc*/html/libraries -name template-haskell.haddock | tail -1) \   $(shell grep -q "Arch Linux" /etc/lsb-release && echo --optghc=-dynamic) \   | grep -v "^Warning: Couldn't find .haddock for export [A-Z]$$" INSTALL_DEPS = leancheck express speculate template-haskell@@ -69,6 +65,7 @@   proto/u-conjure  TESTS = \+  test/factorial \   test/expr \   test/defn \   test/conjurable \@@ -86,8 +83,8 @@  ghci: src/Conjure.ghci -tags: src test/Test.hs-	hasktags $^+tags: src+	ctags -R src  # Disclaimer: This bench target is not intended to generate paper-grade runtime #             datapoints as it runs each benchmark just once.  This target is
README.md view
@@ -57,22 +57,22 @@ 	factorial 3  =  6 	factorial 4  =  24 -Next, declare a list of primitives that seem like interesting pieces+Next, declare a list of ingredients that seem like interesting pieces in the final fully-defined implementation. For example,-here is a list of primitives including+here is a list of ingredients including addition, multiplication, subtraction and their neutral elements: -	primitives :: [Prim]-	primitives  =  [ pr (0::Int)-	               , pr (1::Int)-	               , prim "+" ((+) :: Int -> Int -> Int)-	               , prim "*" ((*) :: Int -> Int -> Int)-	               , prim "-" ((-) :: Int -> Int -> Int)-	               ]+	ingredients :: [Ingredient]+	ingredients  =  [ con (0::Int)+	                , con (1::Int)+	                , fun "+" ((+) :: Int -> Int -> Int)+	                , fun "*" ((*) :: Int -> Int -> Int)+	                , fun "-" ((-) :: Int -> Int -> Int)+	                ]  Finally, call the [`conjure`] function,-passing the function name, the partial definition and the list of primitives:+passing the function name, the partial definition and the list of ingredients:  	factorial :: Int -> Int 	-- 0.1s, testing 4 combinations of argument values@@ -121,11 +121,11 @@ given list constructors, zero, one and subtraction:  	> conjure "take" (take' :: Int -> [A] -> [A])-	>   [ pr (0 :: Int)-	>   , pr (1 :: Int)-	>   , pr ([] :: [A])-	>   , prim ":" ((:) :: A -> [A] -> [A])-	>   , prim "-" ((-) :: Int -> Int -> Int)+	>   [ con (0 :: Int)+	>   , con (1 :: Int)+	>   , con ([] :: [A])+	>   , fun ":" ((:) :: A -> [A] -> [A])+	>   , fun "-" ((-) :: Int -> Int -> Int) 	>   ] 	take :: Int -> [A] -> [A] 	-- 0.2s, testing 153 combinations of argument values@@ -138,9 +138,9 @@ 	take x (y:xs)  =  y:take (x - 1) xs  The above example also takes less than a second to run in a modern laptop.-The selection of functions in the list of primitives was minimized+The selection of functions in the list of ingredients was minimized to what was absolutely needed here.-With a larger collection as primitives YMMV.+With a larger collection as ingredients YMMV.   Synthesizing from specifications (for advanced users)@@ -161,16 +161,16 @@ We will first try to use a partial definition to arrive at an appropriate result. Then we'll see how to use [`conjureFromSpec`]. -Let's start with the primitives:+Let's start with the ingredients: -	primitives :: [Prim]-	primitives  =  [ pr ([] :: [Int])-	               , prim "not" not-	               , prim "&&" (&&)-	               , prim ":" ((:) :: Int -> [Int] -> [Int])-	               , prim "elem" (elem :: Int -> [Int] -> Bool)-	               , prif (undefined :: [Int])-	               ]+	ingredients :: [Ingredient]+	ingredients  =  [ con ([] :: [Int])+	                , fun "not" not+	                , fun "&&" (&&)+	                , fun ":" ((:) :: Int -> [Int] -> [Int])+	                , fun "elem" (elem :: Int -> [Int] -> Bool)+	                , iif (undefined :: [Int])+	                ]  Now here's a first attempt at a partial definition: @@ -183,7 +183,7 @@  Here is what [`conjure`] prints: -	> conjure "duplicates" duplicates primitives+	> conjure "duplicates" duplicates ingredients 	duplicates :: [Int] -> [Int] 	-- testing 1 combinations of argument values 	-- pruning with 21/26 rules@@ -206,7 +206,7 @@  Here is what [`conjure`] now prints: -	> conjure "duplicates" duplicates primitives+	> conjure "duplicates" duplicates ingredients 	duplicates :: [Int] -> [Int] 	-- testing 3 combinations of argument values 	-- pruning with 21/26 rules@@ -246,7 +246,7 @@  Now Conjure prints a correct implementation: -	> conjure "duplicates" duplicates primitives+	> conjure "duplicates" duplicates ingredients 	duplicates :: [Int] -> [Int] 	-- 0.2s, testing 6 combinations of argument values 	-- 0.3s, pruning with 21/26 rules@@ -283,7 +283,7 @@ Now, we can use the function [`conjureFromSpecWith`] to generate the same duplicates function passing our `duplicatesSpec` as argument: -	> conjureFromSpecWith args{maxSize=18} "duplicates" duplicatesSpec primitives+	> conjureFromSpecWith args{maxSize=18} "duplicates" duplicatesSpec ingredients 	duplicates :: [Int] -> [Int] 	duplicates []  =  [] 	duplicates (x:xs)  =  if elem x xs && not (elem x (duplicates xs)) then x:duplicates xs else duplicates xs
TODO.md view
@@ -3,37 +3,26 @@  A non-exhaustive list of things TO DO for Conjure. -* Warn when there are no tests!-  Test this on high order functions.-  Encode `error "could not reify specification"`--* change cannot conjure to "search exhausted",-  to indicate that Conjure has _shown_ that-  there is no way to build the given function-  with the given ingredients up to the given size.--* Expand tests on `conjurableOK`?--* Add `test/conjure.hs` with some basic conjuring...+* Make so that derived Listable instances `reset`+  constructors that are not recursive.+  This change will need to be done in LeanCheck itself. -* Fix bug with pairwise in eg/tuple+* Detail two new proposed pruning rules from Colin.+  (email from Feb 24 and follow-up in meeting)  * Allow timeout setting?  * Rethink Conjurable typeclass? -* Rename primitives to ingredients?- * Allow chains of guards (see below). -* Move `Args` into `[Prim]`?- * 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) -* Warn when no tests are present somehow?+* Add way to consider functions that don't increase size of arguments in recursive calls+	(qsort example)   ## Allow chains of guards
bench/candidates.hs view
@@ -7,7 +7,7 @@ import Conjure.Defn import Data.Express.Fixtures -printCandidates :: Conjurable f => Int -> Int -> String -> f -> [Prim] -> IO ()+printCandidates :: Conjurable f => Int -> Int -> String -> f -> [Ingredient] -> IO () printCandidates m n nm f ps  =  do   putStrLn $ "Candidates for: " ++ nm ++ " :: " ++ show (typeOf f)   putStrLn $ "  pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"@@ -32,54 +32,54 @@   csC  =  concat cssC   css1  =  take m css1'   cssC  =  take m cssC'-  (css1', thy, _, _)  =  candidateDefns1 args nm f ps-  (cssC', _, pss, ds)  =  candidateDefnsC args nm f ps+  (css1', thy, _, _)  =  candidateDefns nm f (singlePattern : ps)+  (cssC', _, pss, ds)  =  candidateDefns nm f ps   nRules  =  length (rules thy)   nREs  =  length (equations thy) + nRules  main :: IO () main  =  do   printCandidates 9 6 "foo" (undefined :: Int -> Int)-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]    printCandidates 9 5 "?" (undefined :: Int -> Int -> Int)-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "dec" (subtract 1 :: Int -> Int)+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "dec" (subtract 1 :: Int -> Int)     ]    printCandidates 9 6 "goo" (undefined :: [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printCandidates 9 6 "??" (undefined :: [Int] -> [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printCandidates 9 6 "ton" (undefined :: Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]    printCandidates 9 6 "&|" (undefined :: Bool -> Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]    -- Degenerate case:@@ -88,6 +88,6 @@   -- nevertheless useful for observing candidate filtering   -- through other means   printCandidates 9 6 "gcd" (undefined :: Int -> Int -> Int)-    [ pr (0::Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)+    [ con (0::Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)     ]
bench/carry-on.hs view
@@ -14,12 +14,14 @@ main :: IO () main  =  do   -- carry on Conjuring larger implementations-  conjureWith args{carryOn = True, maxSize = 11} "factorial n" factorial-    [ pr (0::Int)-    , pr (1::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+  conjure "factorial n" factorial+    [ con (0::Int)+    , con (1::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)+    , carryOn+    , maxSize 11     ]   -- should produce:   -- factorial 0  =  1
bench/carry-on.txt view
@@ -43,5 +43,5 @@ factorial x  =  (0 - x) * (0 - factorial (x - 1))  -- tested 10001 candidates-cannot conjure+factorial n  =  undefined  -- search exhausted 
bench/erroneous.hs view
@@ -22,8 +22,8 @@ -- * maximum candidate size (5 = few seconds, 7 = few minutes); -- * function name (for pretty-printing purposes); -- * proxy value to indicate the type of functions to generate;--- * list of primitives, in Conjure-compatible form.-printErroneousCandidates :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()+-- * list of ingredients, in Conjure-compatible form.+printErroneousCandidates :: Conjurable f => Int -> String -> f -> [Ingredient] -> IO () printErroneousCandidates n nm f ps  =  do   putStrLn $ "Erroneous candidates for: " ++ nm ++ " :: " ++ show (typeOf f)   putStrLn $ "  pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"@@ -40,7 +40,7 @@   css            =  take n                  .  discardT isRedundantByIntroduction -- additional pruning rule                  $  css'-  (css', thy, _, _) =  candidateDefnsC args nm f ps  -- Conjure uses this for listing candidates+  (css', thy, _, _) =  candidateDefns nm f ps  -- Conjure uses this for listing candidates   nRules         =  length (rules thy)   nREs           =  length (equations thy) + nRules   maxTests       =  60 -- a hardcoded value probably will not hurt in this simple benchmark@@ -58,45 +58,45 @@   let n = 6    printErroneousCandidates (n+1) "foo" (undefined :: Int -> Int)-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr (2 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , con (2 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]    printErroneousCandidates n "?" (undefined :: Int -> Int -> Int)-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "dec" (subtract 1 :: Int -> Int)+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "dec" (subtract 1 :: Int -> Int)     ]    printErroneousCandidates (n+1) "goo" (undefined :: [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printErroneousCandidates n "??" (undefined :: [Int] -> [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printErroneousCandidates n "ton" (undefined :: Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]    printErroneousCandidates n "&|" (undefined :: Bool -> Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]
bench/gps.hs view
@@ -38,44 +38,44 @@  gps1c :: IO () gps1c  =  conjure "gps1" gps1p-  [ prim "+" ((+) :: Float -> Float -> Float)-  , prim "fromIntegral" (fromIntegral :: Int -> Float)+  [ fun "+" ((+) :: Float -> Float -> Float)+  , fun "fromIntegral" (fromIntegral :: Int -> Float)   ]  gps1c30p :: IO () gps1c30p  =  conjure "gps1" gps1p-  [ pr (0 :: Float)-  , pr (1 :: Float)-  , pr (1/2 :: Float)-  , pr (-1 :: Float)-  , prim "+" ((+) :: Float -> Float -> Float)-  , prim "*" ((*) :: Float -> Float -> Float)-  , prim "-" ((-) :: Float -> Float -> Float)-  , prim "abs" (abs :: Float -> Float)-  , prim "negate" (negate :: Float -> Float)-  , prim "id" (id :: Float -> Float)-  , prim "fromIntegral" (fromIntegral :: Int -> Float)+  [ con (0 :: Float)+  , con (1 :: Float)+  , con (1/2 :: Float)+  , con (-1 :: Float)+  , fun "+" ((+) :: Float -> Float -> Float)+  , fun "*" ((*) :: Float -> Float -> Float)+  , fun "-" ((-) :: Float -> Float -> Float)+  , fun "abs" (abs :: Float -> Float)+  , fun "negate" (negate :: Float -> Float)+  , fun "id" (id :: Float -> Float)+  , fun "fromIntegral" (fromIntegral :: Int -> Float) -  , pr (0 :: Int)-  , pr (1 :: Int)-  , pr (-1 :: Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "-" ((-) :: Int -> Int -> Int)-  , prim "div" (div :: Int -> Int -> Int)-  , prim "mod" (mod :: Int -> Int -> Int)-  , prim "^" ((^) :: Int -> Int -> Int)-  , prim "abs" (abs :: Int -> Int)-  , prim "negate" (negate :: Int -> Int)-  , prim "id" (id :: Int -> Int)-  , prim "round" (round :: Float -> Int)-  , prim "truncate" (truncate :: Float -> Int)+  , con (0 :: Int)+  , con (1 :: Int)+  , con (-1 :: Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "-" ((-) :: Int -> Int -> Int)+  , fun "div" (div :: Int -> Int -> Int)+  , fun "mod" (mod :: Int -> Int -> Int)+  , fun "^" ((^) :: Int -> Int -> Int)+  , fun "abs" (abs :: Int -> Int)+  , fun "negate" (negate :: Int -> Int)+  , fun "id" (id :: Int -> Int)+  , fun "round" (round :: Float -> Int)+  , fun "truncate" (truncate :: Float -> Int) -  , pr False-  , pr True-  , prim "&&" (&&)-  , prim "||" (||)-  , prim "not" not+  , con False+  , con True+  , fun "&&" (&&)+  , fun "||" (||)+  , fun "not" not   ]  @@ -94,16 +94,18 @@   | otherwise  =  Nothing  gps2c :: IO ()-gps2c  =  conjureWith args{maxTests=5040, maxSize=30} "gps2" gps2p-  [ pr "small"-  , pr "large"-  , pr (1000 :: Int)-  , pr (2000 :: Int)-  , prim "Just" (Just :: String -> Maybe String)-  , prim "Nothing" (Nothing :: Maybe String)-  , prim "<=" ((<=) :: Int -> Int -> Bool)-  , prim "<" ((<) :: Int -> Int -> Bool)-  , prif (undefined :: Maybe String)+gps2c  =  conjure "gps2" gps2p+  [ con "small"+  , con "large"+  , con (1000 :: Int)+  , con (2000 :: Int)+  , fun "Just" (Just :: String -> Maybe String)+  , fun "Nothing" (Nothing :: Maybe String)+  , fun "<=" ((<=) :: Int -> Int -> Bool)+  , fun "<" ((<) :: Int -> Int -> Bool)+  , iif (undefined :: Maybe String)+  , maxTests 5040+  , maxSize 30   ]  @@ -122,19 +124,20 @@ gps3c :: IO () gps3c  =  do   conjure "gps3" gps3p-    [ pr (1 :: Int)-    , prim "enumFromThenTo" ((\x y z -> take 720 $ enumFromThenTo x y z) :: Int -> Int -> Int -> [Int])-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (1 :: Int)+    , fun "enumFromThenTo" ((\x y z -> take 720 $ enumFromThenTo x y z) :: Int -> Int -> Int -> [Int])+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]    -- not possible, no recursive descent-  conjureWith args{maxSize=8} "gps3" gps3p-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "<" ((<) :: Int -> Int -> Bool)-    , prif (undefined :: [Int])+  conjure "gps3" gps3p+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "<" ((<) :: Int -> Int -> Bool)+    , iif (undefined :: [Int])+    , maxSize 8     ]  @@ -155,9 +158,9 @@ gps4c :: IO () gps4c  =  do   conjure "gps4" gps4p-    [ prim "length" (length :: String -> Int)-    , prim "<" ((<) :: Int -> Int -> Bool)-    , prim "&&" (&&)+    [ fun "length" (length :: String -> Int)+    , fun "<" ((<) :: Int -> Int -> Bool)+    , fun "&&" (&&)     ]  @@ -176,13 +179,14 @@   | otherwise   =  c:gps5g cs  gps5c :: IO ()-gps5c  =  conjureWith args{maxSize=6} "gps5" gps5p -- can't find-  [ pr ""-  , prim ":" ((:) :: Char -> String -> String)-  , pr '!'-  , prim "==" ((==) :: Char -> Char -> Bool)-  , prim "isLetter" (isLetter :: Char -> Bool)-  , prif (undefined :: String -> String)+gps5c  =  conjure "gps5" gps5p -- can't find+  [ con ""+  , fun ":" ((:) :: Char -> String -> String)+  , con '!'+  , fun "==" ((==) :: Char -> Char -> Bool)+  , fun "isLetter" (isLetter :: Char -> Bool)+  , iif (undefined :: String -> String)+  , maxSize 6   ]  @@ -213,15 +217,17 @@ -- Removing three or setting maxEqSize to 4 makes it unhang. -- But a size of 15 or 17 is simplyl out of our reach. gps6c :: IO ()-gps6c  =  conjureWith args{maxSize=6,maxEquationSize=3} "gps6" gps6p-  [ pr (1 :: Int)-  , pr (2 :: Int)-  , pr (3 :: Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "`div`" (div :: Int -> Int -> Int)-  , prim "even" (even :: Int -> Bool)-  , prif (undefined :: Int)+gps6c  =  conjure "gps6" gps6p+  [ con (1 :: Int)+  , con (2 :: Int)+  , con (3 :: Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "`div`" (div :: Int -> Int -> Int)+  , fun "even" (even :: Int -> Bool)+  , iif (undefined :: Int)+  , maxSize 6+  , maxEquationSize 3   ]  @@ -238,15 +244,15 @@  gps7c :: IO () gps7c  =  conjure "gps7" gps7p-  [ prim "," ((,) :: String -> Int -> (String, Int))-  , prim "init" (init :: String -> String)-  , prim "unlines" unlines-  , prim "words" words-  , prim "length" (length :: String -> Int)-  , prim "filter" (filter :: (Char -> Bool) -> String -> String)-  , prim "not" not-  , prim "." ((.) :: (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool) -- cheat?-  , prim "isSpace" (isSpace :: Char -> Bool)+  [ fun "," ((,) :: String -> Int -> (String, Int))+  , fun "init" (init :: String -> String)+  , fun "unlines" unlines+  , fun "words" words+  , fun "length" (length :: String -> Int)+  , fun "filter" (filter :: (Char -> Bool) -> String -> String)+  , fun "not" not+  , fun "." ((.) :: (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool) -- cheat?+  , fun "isSpace" (isSpace :: Char -> Bool)   ]  @@ -294,14 +300,15 @@   sq  =  (^2)  gps9c :: IO ()-gps9c  =  conjureWith args{maxTests=60} "gps9" gps9p-  [ pr (1 :: Int)-  , prim "map" (map :: (Int -> Int) -> [Int] -> [Int])-  , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])-  , prim ".." (enumFromTo :: Int -> Int -> [Int])-  , prim ">" ((>) :: Int -> Int -> Bool)-  , prim "even" (even :: Int -> Bool)-  , prim "sq" ((^2) :: Int -> Int)  -- invented separately+gps9c  =  conjure "gps9" gps9p+  [ con (1 :: Int)+  , fun "map" (map :: (Int -> Int) -> [Int] -> [Int])+  , fun "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+  , fun ".." (enumFromTo :: Int -> Int -> [Int])+  , fun ">" ((>) :: Int -> Int -> Bool)+  , fun "even" (even :: Int -> Bool)+  , fun "sq" ((^2) :: Int -> Int)  -- invented separately+  , maxTests 60   ]  @@ -346,35 +353,35 @@ gps10c :: IO () gps10c  =  do   conjure "wallisNext" wallisNextP-    [ pr (1 :: Integer)-    , pr (2 :: Integer)-    , prim "+" ((+) :: Integer -> Integer -> Integer)-    , prim "*" ((*) :: Integer -> Integer -> Integer)-    , prim "%" ((%) :: Integer -> Integer -> Rational)-    , prim "<" ((<) :: Integer -> Integer -> Bool)---  , prim "numerator" (numerator :: Rational -> Integer)---  , prim "denominator" (denominator :: Rational -> Integer)-    , prif (undefined :: Rational)+    [ con (1 :: Integer)+    , con (2 :: Integer)+    , fun "+" ((+) :: Integer -> Integer -> Integer)+    , fun "*" ((*) :: Integer -> Integer -> Integer)+    , fun "%" ((%) :: Integer -> Integer -> Rational)+    , fun "<" ((<) :: Integer -> Integer -> Bool)+--  , fun "numerator" (numerator :: Rational -> Integer)+--  , fun "denominator" (denominator :: Rational -> Integer)+    , iif (undefined :: Rational)     ]    -- simplified background   conjure "wallisNext" wallisNextP-    [ pr (0 :: Integer)-    , pr (1 :: Integer)-    , prim "+" ((+) :: Integer -> Integer -> Integer)-    , prim "*" ((*) :: Integer -> Integer -> Integer)-    , prim "%" ((%) :: Integer -> Integer -> Rational)+    [ con (0 :: Integer)+    , con (1 :: Integer)+    , fun "+" ((+) :: Integer -> Integer -> Integer)+    , fun "*" ((*) :: Integer -> Integer -> Integer)+    , fun "%" ((%) :: Integer -> Integer -> Rational)     ]    conjure "gps10" gps10p-    [ pr (2 :: Integer)-    , pr (3 :: Integer)-    , prim "%" ((%) :: Integer -> Integer -> Rational)---  , pr (2/3 :: Rational)-    , prim "product"    (product :: [Rational] -> Rational)-    , prim "take"       (take :: Int -> [Rational] -> [Rational])-    , prim "iterate"    ((\f -> take 720 . iterate f) :: (Rational -> Rational) -> Rational -> [Rational])-    , prim "wallisNext" wallisNext+    [ con (2 :: Integer)+    , con (3 :: Integer)+    , fun "%" ((%) :: Integer -> Integer -> Rational)+--  , con (2/3 :: Rational)+    , fun "product"    (product :: [Rational] -> Rational)+    , fun "take"       (take :: Int -> [Rational] -> [Rational])+    , fun "iterate"    ((\f -> take 720 . iterate f) :: (Rational -> Rational) -> Rational -> [Rational])+    , fun "wallisNext" wallisNext     ]  @@ -396,16 +403,16 @@ gps11c :: IO () gps11c  =  do   conjure "gps11" gps11p-    [ prim "reverse" (reverse :: [Int] -> [Int])-    , prim "length"  (length :: String -> Int)-    , prim "map"     (map :: (String -> Int) -> [String] -> [Int])+    [ fun "reverse" (reverse :: [Int] -> [Int])+    , fun "length"  (length :: String -> Int)+    , fun "map"     (map :: (String -> Int) -> [String] -> [Int])     ]    conjure "gps11" gps11p-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])-    , prim "length"  (length :: String -> Int)+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])+    , fun "length"  (length :: String -> Int)     ]  @@ -424,15 +431,16 @@  gps12c :: IO () gps12c  =  do-  conjureWith args{maxSize = 11} "gps12" gps12p-    [ prim "length"    (length :: [Int] -> Int)-    , prim "reverse"   (reverse :: [Int] -> [Int])-    , prim "findIndex" (findIndex :: (Int -> Bool) -> [Int] -> Maybe Int)-    , prim "fromJust"  (fromJust :: Maybe Int -> Int)-    , prim "-"         ((-) :: Int -> Int -> Int)-    , prim "=="        ((==) :: Int -> Int -> Bool)-    , pr (0 :: Int)-    , pr (1 :: Int)+  conjure "gps12" gps12p+    [ fun "length"    (length :: [Int] -> Int)+    , fun "reverse"   (reverse :: [Int] -> [Int])+    , fun "findIndex" (findIndex :: (Int -> Bool) -> [Int] -> Maybe Int)+    , fun "fromJust"  (fromJust :: Maybe Int -> Int)+    , fun "-"         ((-) :: Int -> Int -> Int)+    , fun "=="        ((==) :: Int -> Int -> Bool)+    , con (0 :: Int)+    , con (1 :: Int)+    , maxSize 11     ]  @@ -450,12 +458,12 @@ gps13c :: IO () gps13c  =  do   conjure "gps13" gps13p-    [ prim "0" (0 :: Rational)-    , prim "+" ((+) :: Rational -> Rational -> Rational)-    , prim "/" ((/) :: Rational -> Rational -> Rational)-    , prim "foldr" (foldr :: (Rational -> Rational -> Rational) -> Rational -> [Rational] -> Rational)-    , prim "length" (length :: [Rational] -> Int)-    , prim "fromIntegral" (fromIntegral :: Int -> Rational)+    [ fun "0" (0 :: Rational)+    , fun "+" ((+) :: Rational -> Rational -> Rational)+    , fun "/" ((/) :: Rational -> Rational -> Rational)+    , fun "foldr" (foldr :: (Rational -> Rational -> Rational) -> Rational -> [Rational] -> Rational)+    , fun "length" (length :: [Rational] -> Int)+    , fun "fromIntegral" (fromIntegral :: Int -> Rational)     ]  @@ -488,30 +496,30 @@ gps14c :: IO () gps14c  =  do   conjure "odd" odd'-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr (2 :: Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)-    , prim "/=" ((/=) :: Int -> Int -> Bool)+    [ con (0 :: Int)+    , con (1 :: Int)+    , con (2 :: Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)+    , fun "/=" ((/=) :: Int -> Int -> Bool)     ]    conjure "gps14" gps14p-    [ prim "odd" (odd :: Int -> Bool)-    , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])-    , prim "length" (length :: [Int] -> Int)+    [ fun "odd" (odd :: Int -> Bool)+    , fun "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+    , fun "length" (length :: [Int] -> Int)     ]    -- hah!  I was expecting Conjure to use an if like above, but it was smarter:   -- gps14 []  =  0   -- gps14 (x:xs)  =  x `mod` 2 + gps14 xs   conjure "gps14" gps14p-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr (2 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)-    , prim "==" ((==) :: Int -> Int -> Bool)-    , prif (undefined :: Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , con (2 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)+    , fun "==" ((==) :: Int -> Int -> Bool)+    , iif (undefined :: Int)     ]  @@ -530,8 +538,8 @@ gps15c :: IO () gps15c  =  do   conjure "gps15" gps15p-    [ prim "==" ((==) :: [Int] -> [Int] -> Bool)-    , prim "reverse" (reverse :: [Int] -> [Int])+    [ fun "==" ((==) :: [Int] -> [Int] -> Bool)+    , fun "reverse" (reverse :: [Int] -> [Int])     ]  @@ -551,8 +559,8 @@ gps16c :: IO () gps16c  =  do   conjure "gps16" gps16p-    [ prim "`isSubsequenceOf`" (isSubsequenceOf :: String -> String -> Bool)-    , prim "sort" (sort :: String -> String)+    [ fun "`isSubsequenceOf`" (isSubsequenceOf :: String -> String -> Bool)+    , fun "sort" (sort :: String -> String)     ]  @@ -569,11 +577,11 @@  gps17c :: IO () gps17c  =  conjure "gps17" gps17p-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "-" ((-) :: Int -> Int -> Int)+  [ con (0 :: Int)+  , con (1 :: Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "-" ((-) :: Int -> Int -> Int)   ]  @@ -594,14 +602,14 @@ gps18c :: IO () gps18c  =  do   conjure "gps18" gps18p-    [ pr ([] :: [Int])-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim ":" ((:) :: Int -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun ":" ((:) :: Int -> [Int] -> [Int])     ]    conjure "gps18" gps18p-    [ prim "+" ((+) :: Int -> Int -> Int)-    , prim "zipWith" (zipWith :: (Int -> Int -> Int) -> [Int] -> [Int] -> [Int])+    [ fun "+" ((+) :: Int -> Int -> Int)+    , fun "zipWith" (zipWith :: (Int -> Int -> Int) -> [Int] -> [Int] -> [Int])     ]  @@ -623,12 +631,12 @@ gps19c  =  do   -- speculate takes too long   conjure "gps19" gps19p $ take 0-    [ prim "words" (words :: String -> [String])---  , prim "words" (lines :: String -> [String])-    , prim "unwords" (unwords :: [String] -> String)-    , prim "unlines" (unlines :: [String] -> String)---  , prim "chunk" (chunk :: Int -> [String] -> [[String]])---  , prim "map" (map :: ([String] -> String) -> [[String]] -> [String])+    [ fun "words" (words :: String -> [String])+--  , fun "words" (lines :: String -> [String])+    , fun "unwords" (unwords :: [String] -> String)+    , fun "unlines" (unlines :: [String] -> String)+--  , fun "chunk" (chunk :: Int -> [String] -> [[String]])+--  , fun "map" (map :: ([String] -> String) -> [[String]] -> [String])     ]  @@ -680,29 +688,30 @@ gps20c :: IO () gps20c  =  do   conjure "isVowel" isVowel'-    [ pr 'a'-    , pr 'e'-    , pr 'i'-    , pr 'o'-    , pr 'u'-    , pr 'y'-    , pr True-    , pr False+    [ con 'a'+    , con 'e'+    , con 'i'+    , con 'o'+    , con 'u'+    , con 'y'+    , con True+    , con False     ] -  conjureFromSpecWith args{target=50400} "pig1" pig1Spec-    [ pr "ay"-    , prif (undefined :: String)-    , prim "isVowel" isVowel-    , prim "++" ((++) :: String -> String -> String)-    , prim ":" ((:) :: Char -> String -> String)+  conjureFromSpec "pig1" pig1Spec+    [ con "ay"+    , iif (undefined :: String)+    , fun "isVowel" isVowel+    , fun "++" ((++) :: String -> String -> String)+    , fun ":" ((:) :: Char -> String -> String)+    , target 50400     ]    conjureFromSpec "gps20c" gps20s-    [ prim "words" (words :: String -> [String])-    , prim "unwords" (unwords :: [String] -> String)-    , prim "map" (map :: (String -> String) -> [String] -> [String])-    , prim "pig1" pig1+    [ fun "words" (words :: String -> [String])+    , fun "unwords" (unwords :: [String] -> String)+    , fun "map" (map :: (String -> String) -> [String] -> [String])+    , fun "pig1" pig1     ]  @@ -721,11 +730,11 @@  gps21c :: IO () gps21c  =  conjure "gps21" gps21p-  [ pr ([] :: [Int])-  , pr (0 :: Int)-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prim "<" ((<) :: Int -> Int -> Bool)-  , prif (undefined :: Int)+  [ con ([] :: [Int])+  , con (0 :: Int)+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , fun "<" ((<) :: Int -> Int -> Bool)+  , iif (undefined :: Int)   ]  @@ -764,10 +773,10 @@ gps22c :: IO () gps22c  =  do   conjureFromSpec "gps22" gps22s-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "map" (map :: (Int -> Int) -> [Int] -> [Int])-    , prim "scrabble1" scrabble1+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "map" (map :: (Int -> Int) -> [Int] -> [Int])+    , fun "scrabble1" scrabble1     ]  @@ -793,14 +802,14 @@  gps24c :: IO () gps24c  =  conjure "gps24" gps24p-  [ pr ' '-  , pr (64 :: Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "`mod`" (mod :: Int -> Int -> Int)-  , prim "sum" (sum :: [Int] -> Int)-  , prim "ord" ord-  , prim "chr" chr-  , prim "map" (map :: (Char -> Int) -> String -> [Int])+  [ con ' '+  , con (64 :: Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "`mod`" (mod :: Int -> Int -> Int)+  , fun "sum" (sum :: [Int] -> Int)+  , fun "ord" ord+  , fun "chr" chr+  , fun "map" (map :: (Char -> Int) -> String -> [Int])   ]  @@ -820,15 +829,15 @@ -- out of reach performance-wise gps25c :: IO () gps25c  =  conjure "gps25" gps25p $ take 0-  [ pr (0 :: Int)-  , pr (10 :: Int)-  , pr ([] :: [Int])-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prif (undefined :: [Int])-  , prim "abs" (abs :: Int -> Int)-  , prim "<" ((<) :: Int -> Int -> Bool)-  , prim "rem" (rem :: Int -> Int -> Int)-  , prim "quot" (quot :: Int -> Int -> Int)+  [ con (0 :: Int)+  , con (10 :: Int)+  , con ([] :: [Int])+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , iif (undefined :: [Int])+  , fun "abs" (abs :: Int -> Int)+  , fun "<" ((<) :: Int -> Int -> Bool)+  , fun "rem" (rem :: Int -> Int -> Int)+  , fun "quot" (quot :: Int -> Int -> Int)   ]  @@ -851,14 +860,15 @@  -- out of reach performance-wise gps26c :: IO ()-gps26c  =  conjureWith args{maxSize=2} "gps26" gps26p-  [ pr 'A'-  , pr 'B'-  , pr 'C'-  , pr 'D'-  , pr 'F'-  , prif (undefined :: Char)-  , prim ">=" ((>=) :: Int -> Int -> Bool)+gps26c  =  conjure "gps26" gps26p+  [ con 'A'+  , con 'B'+  , con 'C'+  , con 'D'+  , con 'F'+  , iif (undefined :: Char)+  , fun ">=" ((>=) :: Int -> Int -> Bool)+  , maxSize 2   ]  @@ -878,14 +888,14 @@ gps27c :: IO () gps27c  =  do   conjure "gps27" gps27p-    [ prim "<" ((<) :: Int -> Int -> Bool)-    , prim "&&" (&&)-    , prif (undefined :: Int)+    [ fun "<" ((<) :: Int -> Int -> Bool)+    , fun "&&" (&&)+    , iif (undefined :: Int)     ]    conjure "gps27b" gps27p-    [ prim "min" (min :: Int -> Int -> Int)-    , prim "max" (max :: Int -> Int -> Int)+    [ fun "min" (min :: Int -> Int -> Int)+    , fun "max" (max :: Int -> Int -> Int)     ]  @@ -899,7 +909,7 @@  gps28c :: IO () gps28c  =  conjure "gps28" gps28p-  [ prim "`min`" (min :: Int -> Int -> Int)+  [ fun "`min`" (min :: Int -> Int -> Int)   ]  @@ -920,11 +930,11 @@  gps29c :: IO () gps29c  =  conjureFromSpec "gps29" gps29s-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , prim "+" ((+) :: Int->Int->Int)-  , prif (undefined :: Int)-  , prim "isVowel" isVowel+  [ con (0 :: Int)+  , con (1 :: Int)+  , fun "+" ((+) :: Int->Int->Int)+  , iif (undefined :: Int)+  , fun "isVowel" isVowel   ]  
bench/gps.txt view
@@ -55,7 +55,7 @@ -- 81 candidates of size 7 -- 36 candidates of size 8 -- tested 136 candidates-cannot conjure+gps3  =  undefined  -- search exhausted  gps4 :: [Char] -> [Char] -> [Char] -> Bool -- testing 9 combinations of argument values@@ -84,7 +84,7 @@ -- 4 candidates of size 5 -- 0 candidates of size 6 -- tested 8 candidates-cannot conjure+gps5  =  undefined  -- search exhausted  gps6 :: Int -> Int -- testing 9 combinations of argument values@@ -96,7 +96,7 @@ -- 186 candidates of size 5 -- 165 candidates of size 6 -- tested 385 candidates-cannot conjure+gps6  =  undefined  -- search exhausted  gps7 :: [Char] -> ([Char],Int) -- testing 4 combinations of argument values@@ -123,7 +123,7 @@ -- 0 candidates of size 3 -- 0 candidates of size 4 -- tested 0 candidates-cannot conjure+gps8  =  undefined  -- search exhausted  gps9 :: Int -> [Int] -- testing 3 combinations of argument values@@ -309,7 +309,7 @@ -- 1048 candidates of size 9 -- tested 466 candidates gps17 0  =  0-gps17 x  =  gps17 (x - 1) + x * x+gps17 x  =  x * x + gps17 (x - 1)  gps18 :: [Int] -> [Int] -> [Int] -- testing 3 combinations of argument values@@ -344,7 +344,7 @@ -- 1 candidates of size 1 -- 0 candidates of size 2 -- tested 1 candidates-cannot conjure+gps19  =  undefined  -- search exhausted  isVowel :: Char -> Bool -- testing 12 combinations of argument values@@ -439,14 +439,10 @@ -- 3 candidates of size 6 -- tested 4 candidates gps22 ""  =  0-gps22 (c:cs)  =  gps22 cs + scrabble1 c+gps22 (c:cs)  =  scrabble1 c + gps22 cs  gps23 :: [Char] -> ([(Int,Int)],Int,Double)--- pruning with 0/0 rules--- 0 candidates of size 1--- 0 candidates of size 2--- tested 0 candidates-cannot conjure+gps23  =  error "could not reify specification, suggestion: conjureFromSpec"  gps24 :: [Char] -> Char -- testing 4 combinations of argument values@@ -469,7 +465,7 @@ -- pruning with 0/0 rules -- 0 candidates of size 1 -- tested 0 candidates-cannot conjure+gps25  =  undefined  -- search exhausted  gps26 :: Int -> Int -> Int -> Int -> Int -> Char -- testing 5 combinations of argument values@@ -477,7 +473,7 @@ -- 5 candidates of size 1 -- 0 candidates of size 2 -- tested 5 candidates-cannot conjure+gps26  =  undefined  -- search exhausted  gps27 :: Int -> Int -> Int -> Int -- testing 3 combinations of argument values@@ -535,5 +531,5 @@ -- 24 candidates of size 9 -- tested 36 candidates gps29 ""  =  0-gps29 (c:cs)  =  gps29 cs + (if isVowel c then 1 else 0)+gps29 (c:cs)  =  (if isVowel c then 1 else 0) + gps29 cs 
bench/gps2.hs view
@@ -42,36 +42,38 @@ gps1c :: IO () gps1c  =  do   conjure "gps1" gps1p-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim ">" ((>) :: Int -> Int -> Bool)-    , prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)-    , prim "sum" (sum :: [Int] -> Int)-    , prim "findIndex" (findIndex :: (Int -> Bool) -> [Int] -> Maybe Int)-    , prim "map" (map :: ([Int] -> Int) -> [[Int]] -> [Int])-    , prim "inits" (inits :: [Int] -> [[Int]])-    , prim "tail" (tail :: [[Int]] -> [[Int]])+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun ">" ((>) :: Int -> Int -> Bool)+    , fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+    , fun "sum" (sum :: [Int] -> Int)+    , fun "findIndex" (findIndex :: (Int -> Bool) -> [Int] -> Maybe Int)+    , fun "map" (map :: ([Int] -> Int) -> [[Int]] -> [Int])+    , fun "inits" (inits :: [Int] -> [[Int]])+    , fun "tail" (tail :: [[Int]] -> [[Int]])     ]    conjure "gps1" gps1p-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim ">" ((>) :: Int -> Int -> Bool)-    , prim "sum" (sum :: [Int] -> Int)-    , prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)-    , prim "findIndex" (findIndex :: (Int -> Bool) -> [Int] -> Maybe Int)-    , prim "map" (map :: ([Int] -> Int) -> [[Int]] -> [Int])-    , prim "inits" (inits :: [Int] -> [[Int]])-    , prim "tail" (tail :: [[Int]] -> [[Int]])+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun ">" ((>) :: Int -> Int -> Bool)+    , fun "sum" (sum :: [Int] -> Int)+    , fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+    , fun "findIndex" (findIndex :: (Int -> Bool) -> [Int] -> Maybe Int)+    , fun "map" (map :: ([Int] -> Int) -> [[Int]] -> [Int])+    , fun "inits" (inits :: [Int] -> [[Int]])+    , fun "tail" (tail :: [[Int]] -> [[Int]])     ] -  conjureWithMaxSize 4 "gps1" gps1p2-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "<" ((<) :: Int -> Int -> Bool)-    , prif (undefined :: Int)-    , prim "undefined" (undefined :: Int)+  conjure "gps1" gps1p2+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "<" ((<) :: Int -> Int -> Bool)+    , iif (undefined :: Int)+    , fun "undefined" (undefined :: Int)+    , maxSize 4+    , maxEquationSize 4     ]  @@ -90,13 +92,14 @@  gps2c :: IO () gps2c  =  do-  conjureWithMaxSize 6 "gps2" gps2p-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "*" ((*) :: Double -> Double -> Double)-    , prim "/" ((/) :: Double -> Double -> Double)-    , prim "+" ((+) :: Double -> Double -> Double)-    , prim "-" ((-) :: Double -> Double -> Double)+  conjure "gps2" gps2p+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "*" ((*) :: Double -> Double -> Double)+    , fun "/" ((/) :: Double -> Double -> Double)+    , fun "+" ((+) :: Double -> Double -> Double)+    , fun "-" ((-) :: Double -> Double -> Double)+    , maxSize 6     ]  @@ -133,16 +136,17 @@  gps4c :: IO () gps4c  =  do-  conjureFromSpecWith args{maxSize=6} "gps4" gps4s-    [ pr '-'-    , pr ("" :: String)-    , prim ":" ((:) :: Char -> String -> String)-    , prim "==" ((==) :: Char -> Char -> Bool)-    , prim "head" (head :: String -> Char)-    , prim "tail" (tail :: String -> String)-    , prif (undefined :: Char)-    , prif (undefined :: String)-    , prim "toUpper" (toUpper :: Char -> Char)+  conjureFromSpec "gps4" gps4s+    [ con '-'+    , con ("" :: String)+    , fun ":" ((:) :: Char -> String -> String)+    , fun "==" ((==) :: Char -> Char -> Bool)+    , fun "head" (head :: String -> Char)+    , fun "tail" (tail :: String -> String)+    , iif (undefined :: Char)+    , iif (undefined :: String)+    , fun "toUpper" (toUpper :: Char -> Char)+    , maxSize 6     ]  @@ -192,25 +196,26 @@     ]    conjureFromSpec "tell" gps5s-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "`div`" (div :: Int -> Int -> Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "`div`" (div :: Int -> Int -> Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)     ]    conjure "gps5" gps5p-    [ pr coins-    , prim "tell" tell+    [ con coins+    , fun "tell" tell     ] -  conjureWith args{target=50400} "gps5" gps5p-    [ pr (1 :: Int)-    , pr (5 :: Int)-    , pr (10 :: Int)-    , pr (25 :: Int)-    , pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "tell" tell+  conjure "gps5" gps5p+    [ con (1 :: Int)+    , con (5 :: Int)+    , con (10 :: Int)+    , con (25 :: Int)+    , con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "tell" tell+    , target 50400     ]  @@ -249,17 +254,18 @@ -- out of reach performance-wise gps7c :: IO () gps7c  =  do-  conjureWith args{maxSize=6} "gps7" gps7p $ take 0-    [ pr (0 :: Integer)-    , pr (1 :: Integer)-    , prim "%" ((%) :: Integer -> Integer -> Rational)-    , prim "+" ((+) :: Integer -> Integer -> Integer)-    , prim "-" ((-) :: Integer -> Integer -> Integer)-    , prim "*" ((*) :: Integer -> Integer -> Integer)-    , prim "min" (min :: Integer -> Integer -> Integer)-    , prim ".." (enumFromTo :: Integer -> Integer -> [Integer])-    , prim "map" (map :: (Integer -> Integer) -> [Integer] -> [Integer])-    , prim "sum" (sum :: [Integer] -> Integer)+  conjure "gps7" gps7p $ take 0+    [ con (0 :: Integer)+    , con (1 :: Integer)+    , fun "%" ((%) :: Integer -> Integer -> Rational)+    , fun "+" ((+) :: Integer -> Integer -> Integer)+    , fun "-" ((-) :: Integer -> Integer -> Integer)+    , fun "*" ((*) :: Integer -> Integer -> Integer)+    , fun "min" (min :: Integer -> Integer -> Integer)+    , fun ".." (enumFromTo :: Integer -> Integer -> [Integer])+    , fun "map" (map :: (Integer -> Integer) -> [Integer] -> [Integer])+    , fun "sum" (sum :: [Integer] -> Integer)+    , maxSize 6     ]  @@ -319,14 +325,15 @@  -- unreachable due to lambda gps10c :: IO ()-gps10c  =  conjureWith args{target=50400} "gps10" gps10p-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , pr (2 :: Int)-  , pr (3 :: Int)-  , prim "`div`" (div :: Int -> Int -> Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "-" ((-) :: Int -> Int -> Int)+gps10c  =  conjure "gps10" gps10p+  [ con (0 :: Int)+  , con (1 :: Int)+  , con (2 :: Int)+  , con (3 :: Int)+  , fun "`div`" (div :: Int -> Int -> Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "-" ((-) :: Int -> Int -> Int)+  , target 50400   ]  @@ -348,8 +355,8 @@  gps11c :: IO () gps11c  =  conjure "gcd a b" gps11p-  [ pr (0::Int)-  , prim "`mod`" (mod :: Int -> Int -> Int)+  [ con (0::Int)+  , fun "`mod`" (mod :: Int -> Int -> Int)   ]   -- generated function:   -- gcd x 0  =  x@@ -368,9 +375,9 @@  gps12c :: IO () gps12c  =  conjure "gps12" gps12p-  [ prim "findIndices" (findIndices :: (String -> Bool) -> [String] -> [Int])-  , prim "`isPrefixOf`" (isPrefixOf :: String -> String -> Bool)-  , prim "tails" (tails :: String -> [String])+  [ fun "findIndices" (findIndices :: (String -> Bool) -> [String] -> [Int])+  , fun "`isPrefixOf`" (isPrefixOf :: String -> String -> Bool)+  , fun "tails" (tails :: String -> [String])   ]  @@ -390,11 +397,11 @@  gps13c :: IO () gps13c  =  conjure "gps13_leaders" gps13p-  [ pr ([] :: [Int])-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prim ">" ((>) :: Int -> Int -> Bool)-  , prim "all" (all :: (Int -> Bool) -> [Int] -> Bool)-  , prif (undefined :: [Int])+  [ con ([] :: [Int])+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , fun ">" ((>) :: Int -> Int -> Bool)+  , fun "all" (all :: (Int -> Bool) -> [Int] -> Bool)+  , iif (undefined :: [Int])   ]  @@ -460,13 +467,13 @@  gps16c :: IO () gps16c  =  conjure "gps16_middle" gps16p-  [ pr ""-  , pr (1 :: Int)-  , prim "<=" ((<=) :: Int -> Int -> Bool)-  , prim ":" ((:) :: Char -> String -> String)-  , prim "length" (length :: String -> Int)-  , prim "init" (init :: String -> String)-  , prif (undefined :: String)+  [ con ""+  , con (1 :: Int)+  , fun "<=" ((<=) :: Int -> Int -> Bool)+  , fun ":" ((:) :: Char -> String -> String)+  , fun "length" (length :: String -> Int)+  , fun "init" (init :: String -> String)+  , iif (undefined :: String)   ]  @@ -493,15 +500,16 @@ -- setting limit of 5 for faster automated tests -- BENCHMARK: increase maxSize from 5 to 18 gps17c :: IO ()-gps17c  =  conjureWith args{maxSize=5} "gps17_pds" gps17p-  [ pr (0 :: Int)-  , prif (undefined :: Int)-  , prim "not" not-  , prim "null" (null :: [Int] -> Bool)-  , prim "==" ((==) :: Int -> Int -> Bool)-  , prim "head" (head :: [Int] -> Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "&&" (&&)+gps17c  =  conjure "gps17_pds" gps17p+  [ con (0 :: Int)+  , iif (undefined :: Int)+  , fun "not" not+  , fun "null" (null :: [Int] -> Bool)+  , fun "==" ((==) :: Int -> Int -> Bool)+  , fun "head" (head :: [Int] -> Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "&&" (&&)+  , maxSize 5   ]  @@ -516,15 +524,16 @@  -- this was OOM'd gps18c :: IO ()-gps18c  =  conjureWithMaxSize 6 "gps18_price" gps18p-  [ pr (0 :: Double)-  , pr (1 :: Double)-  , prim "+" ((+) :: Double -> Double -> Double)-  , prim "*" ((*) :: Double -> Double -> Double)-  , prim "-" ((-) :: Double -> Double -> Double)---  , prim "foldr" (foldr :: (Double -> Double -> Double) -> Double -> [Double] -> Double)---   , prim "zipWith" (zipWith :: (Double -> Double -> Double) -> [Double] -> [Double] -> [Double])---  , prim "map" (map :: (Double -> Double) -> [Double] -> [Double])+gps18c  =  conjure "gps18_price" gps18p+  [ con (0 :: Double)+  , con (1 :: Double)+  , fun "+" ((+) :: Double -> Double -> Double)+  , fun "*" ((*) :: Double -> Double -> Double)+  , fun "-" ((-) :: Double -> Double -> Double)+--  , fun "foldr" (foldr :: (Double -> Double -> Double) -> Double -> [Double] -> Double)+--   , fun "zipWith" (zipWith :: (Double -> Double -> Double) -> [Double] -> [Double] -> [Double])+--  , fun "map" (map :: (Double -> Double) -> [Double] -> [Double])+  , maxSize 6   ]  @@ -543,12 +552,13 @@ -- size 14, out of reach performance wise.  gps19c :: IO ()-gps19c  =  conjureWithMaxSize 6 "gps19_snowday" gps19p-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , prim "max" (max :: Double -> Double -> Double)-  , prim "+" ((+) :: Double -> Double -> Double)-  , prim "-" ((-) :: Double -> Double -> Double)+gps19c  =  conjure "gps19_snowday" gps19p+  [ con (0 :: Int)+  , con (1 :: Int)+  , fun "max" (max :: Double -> Double -> Double)+  , fun "+" ((+) :: Double -> Double -> Double)+  , fun "-" ((-) :: Double -> Double -> Double)+  , maxSize 6   ]  @@ -587,23 +597,23 @@ gps21c :: IO () gps21c  =  do   conjureFromSpec "spin" spinSpec-    [ prim "length"  (length :: String -> Int)-    , prim "reverse" (reverse :: String -> String)-    , prif (undefined :: String)-    , prim ">="      ((>=) :: Int -> Int -> Bool)-    , pr (5 :: Int)+    [ fun "length"  (length :: String -> Int)+    , fun "reverse" (reverse :: String -> String)+    , iif (undefined :: String)+    , fun ">="      ((>=) :: Int -> Int -> Bool)+    , con (5 :: Int)     ]    conjureFromSpec "gps21_spinwords" gps21s-    [ prim "words"   words-    , prim "unwords" unwords-    , prim "spin"    (spin :: String -> String)-    , prim "map"     (map :: (String -> String) -> [String] -> [String])-    , prim "length"  (length :: String -> Int)-    , prim "reverse" (reverse :: String -> String)-    , prif (undefined :: String)-    , prim ">="      ((>=) :: Int -> Int -> Bool)-    , pr (5 :: Int)+    [ fun "words"   words+    , fun "unwords" unwords+    , fun "spin"    (spin :: String -> String)+    , fun "map"     (map :: (String -> String) -> [String] -> [String])+    , fun "length"  (length :: String -> Int)+    , fun "reverse" (reverse :: String -> String)+    , iif (undefined :: String)+    , fun ">="      ((>=) :: Int -> Int -> Bool)+    , con (5 :: Int)     ]  @@ -624,13 +634,14 @@ gps22c :: IO () gps22c  =  do   -- cannot conjure at size 13, maybe beyond?-  conjureWith args{target=10080} "digits" digits'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "`div`" (div :: Int -> Int -> Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)-    , prim "div10" ((`div` 10) :: Int -> Int)-    , pr (10 :: Int)+  conjure "digits" digits'+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "`div`" (div :: Int -> Int -> Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)+    , fun "div10" ((`div` 10) :: Int -> Int)+    , con (10 :: Int)+    , target 10080     ]    conjure "gps22" gps22p@@ -684,16 +695,16 @@  gps24c :: IO () gps24c  =  do-  conjureFromSpecWith args{maxTests=360} "gps24" gps24s_twitter-    [ pr Empty-    , pr TooMany-    , prim "Tweet" Tweet-    , prif (undefined :: Twitter)-    , pr ""-    , prim ":" ((:) :: Char -> String -> String)-    , prim "length" (length :: String -> Int)-    , pr (140 :: Int)-    , prim ">" ((>) :: Int -> Int -> Bool)+  conjureFromSpec "gps24" gps24s_twitter+    [ con Empty+    , con TooMany+    , fun "Tweet" Tweet+    , iif (undefined :: Twitter)+    , con ""+    , fun ":" ((:) :: Char -> String -> String)+    , fun "length" (length :: String -> Int)+    , con (140 :: Int)+    , fun ">" ((>) :: Int -> Int -> Bool)     ]  @@ -711,15 +722,16 @@  -- out of reach performance-wise gps25c :: IO ()-gps25c  =  conjureWith args{maxSize=6} "gps25" gps25p-  [ pr (0 :: Double)-  , pr (2 :: Double)-  , prim "+" ((+) :: Double -> Double -> Double)-  , prim "-" ((-) :: Double -> Double -> Double)-  , prim "**" ((**) :: Double -> Double -> Double)-  , prim "zipWith" (zipWith :: (Double -> Double -> Double) -> [Double] -> [Double] -> [Double])-  , prim "map" (map :: (Double -> Double) -> [Double] -> [Double])-  , prim "sqrt" (sqrt :: Double -> Double)+gps25c  =  conjure "gps25" gps25p+  [ con (0 :: Double)+  , con (2 :: Double)+  , fun "+" ((+) :: Double -> Double -> Double)+  , fun "-" ((-) :: Double -> Double -> Double)+  , fun "**" ((**) :: Double -> Double -> Double)+  , fun "zipWith" (zipWith :: (Double -> Double -> Double) -> [Double] -> [Double] -> [Double])+  , fun "map" (map :: (Double -> Double) -> [Double] -> [Double])+  , fun "sqrt" (sqrt :: Double -> Double)+  , maxSize 6   ]  
bench/gps2.txt view
@@ -36,7 +36,7 @@ -- 11 candidates of size 3 -- 29 candidates of size 4 -- tested 44 candidates-cannot conjure+gps1  =  undefined  -- search exhausted  gps2 :: Double -> Double -> Int -> Double -- testing 5 combinations of argument values@@ -48,14 +48,10 @@ -- 256 candidates of size 5 -- 1252 candidates of size 6 -- tested 1592 candidates-cannot conjure+gps2  =  undefined  -- search exhausted  gps3 :: [Char] -> Int--- pruning with 0/0 rules--- 0 candidates of size 1--- 0 candidates of size 2--- tested 0 candidates-cannot conjure+gps3  =  error "could not reify specification, suggestion: conjureFromSpec"  gps4 :: [Char] -> [Char] -- pruning with 13/21 rules@@ -66,14 +62,14 @@ -- 51 candidates of size 5 -- 119 candidates of size 6 -- tested 203 candidates-cannot conjure+gps4  =  undefined  -- search exhausted  gps5 :: Int -> [Int] -- testing 6 combinations of argument values -- pruning with 0/0 rules -- 0 candidates of size 1 -- tested 0 candidates-cannot conjure+gps5  =  undefined  -- search exhausted  tell :: [Int] -> Int -> [Int] -- pruning with 0/0 rules@@ -123,14 +119,14 @@ -- 0 candidates of size 1 -- 0 candidates of size 2 -- tested 0 candidates-cannot conjure+gps6  =  undefined  -- search exhausted  gps7 :: Integer -> Integer -> Ratio Integer -- testing 6 combinations of argument values -- pruning with 0/0 rules -- 0 candidates of size 1 -- tested 0 candidates-cannot conjure+gps7  =  undefined  -- search exhausted  gps8 :: Int -> [Int] -> (Int,Int) -- testing 3 combinations of argument values@@ -138,14 +134,14 @@ -- 0 candidates of size 1 -- 0 candidates of size 2 -- tested 0 candidates-cannot conjure+gps8  =  undefined  -- search exhausted  gps9 :: Int -> [Char] -- testing 7 combinations of argument values -- pruning with 0/0 rules -- 0 candidates of size 1 -- tested 0 candidates-cannot conjure+gps9  =  undefined  -- search exhausted  gps10 :: [Int] -> Int -- testing 7 combinations of argument values@@ -161,7 +157,7 @@ -- 30712 candidates of size 9 -- tested 7064 candidates gps10 []  =  0-gps10 (x:xs)  =  gps10 xs + (x `div` 3 - 2)+gps10 (x:xs)  =  (x `div` 3 - 2) + gps10 xs  gcd :: Int -> Int -> Int -- testing 11 combinations of argument values@@ -209,17 +205,10 @@                          else gps13_leaders xs  gps14_luhn :: [Int] -> Int--- pruning with 0/0 rules--- 0 candidates of size 1--- 0 candidates of size 2--- tested 0 candidates-cannot conjure+gps14_luhn  =  error "could not reify specification, suggestion: conjureFromSpec"  gps15_mastermind :: () -> ()--- pruning with 0/1 rules--- 1 candidates of size 1--- tested 1 candidates-gps15_mastermind u  =  u+gps15_mastermind  =  error "could not reify specification, suggestion: conjureFromSpec"  gps16_middle :: [Char] -> [Char] -- testing 7 combinations of argument values@@ -251,7 +240,7 @@ -- 0 candidates of size 4 -- 2 candidates of size 5 -- tested 4 candidates-cannot conjure+gps17_pds  =  undefined  -- search exhausted  gps18_price :: [Double] -> [Double] -> Double -- testing 4 combinations of argument values@@ -263,7 +252,7 @@ -- 33 candidates of size 5 -- 176 candidates of size 6 -- tested 213 candidates-cannot conjure+gps18_price  =  undefined  -- search exhausted  gps19_snowday :: Int -> Double -> Double -> Double -> Double -- testing 7 combinations of argument values@@ -275,14 +264,10 @@ -- 312 candidates of size 5 -- 659 candidates of size 6 -- tested 1036 candidates-cannot conjure+gps19_snowday  =  undefined  -- search exhausted  gps20 :: [Char] -> Bool--- pruning with 0/0 rules--- 0 candidates of size 1--- 0 candidates of size 2--- tested 0 candidates-cannot conjure+gps20  =  error "could not reify specification, suggestion: conjureFromSpec"  spin :: [Char] -> [Char] -- pruning with 6/6 rules@@ -326,13 +311,10 @@ -- 923 candidates of size 10 -- 8902 candidates of size 11 -- tested 10900 candidates-cannot conjure+digits  =  undefined  -- search exhausted  gps22 :: Int -> [Char]--- pruning with 0/0 rules--- 0 candidates of size 1--- tested 0 candidates-cannot conjure+gps22  =  error "could not reify specification, suggestion: conjureFromSpec"  gps23 :: [Char] -> [Char] -> [Char] -> [Char] -- pruning with 0/0 rules@@ -348,7 +330,7 @@ -- 2722 candidates of size 10 -- 5292 candidates of size 11 -- tested 10955 candidates-cannot conjure+gps23  =  undefined  -- search exhausted  gps24 :: [Char] -> Twitter -- pruning with 4/8 rules@@ -381,5 +363,5 @@ -- 76 candidates of size 5 -- 438 candidates of size 6 -- tested 532 candidates-cannot conjure+gps25  =  undefined  -- search exhausted 
bench/ill-hit.hs view
@@ -24,19 +24,23 @@  main :: IO () main  =  do+  -- the following conjures from an "empty" spec+  -- we should get a proper error message+  conjure "sum" (undefined :: [Int] -> Int) ingredients+   -- the following does not hit all 6 defined prims, only 4-  conjure "sum" (sum' :: [Int] -> Int) primitives+  conjure "sum" (sum' :: [Int] -> Int) ingredients    -- the following conjures from a spec-  conjureFromSpec "sum" sumSpec primitives+  conjureFromSpec "sum" sumSpec ingredients -primitives :: [Prim]-primitives =-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "null" (null :: [Int] -> Bool)-  , prim "head" (head :: [Int] -> Int)-  , prim "tail" (tail :: [Int] -> [Int])+ingredients :: [Ingredient]+ingredients =+  [ con (0 :: Int)+  , con (1 :: Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "null" (null :: [Int] -> Bool)+  , fun "head" (head :: [Int] -> Int)+  , fun "tail" (tail :: [Int] -> [Int])   ]
bench/ill-hit.txt view
@@ -1,4 +1,7 @@ sum :: [Int] -> Int+sum  =  error "could not reify specification, suggestion: conjureFromSpec"++sum :: [Int] -> Int -- testing 4 combinations of argument values -- pruning with 14/25 rules -- 2 candidates of size 1
bench/lowtests.hs view
@@ -54,33 +54,42 @@ replicates' [a,b]   3  =  [a,a,a,b,b,b] replicates' [a,b,c] 3  =  [a,a,a,b,b,b,c,c,c] -as :: Args-as  =  args{showTheory = True, maxSize = 18}- main :: IO () main = do   -- low number of tests, cannot conjure due to incorrect property-  conjureWith as{maxTests=60} "subset" (subset')-    [ prim "sort" (sort :: [Int] -> [Int])-    , prim "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)+  conjure "subset" subset'+    [ fun "sort" (sort :: [Int] -> [Int])+    , fun "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)+    , showTheory+    , maxSize 18+    , maxTests 60     ]    -- subset xs ys  =  sort xs `isSubsequenceOf` sort ys-  conjureWith as{maxTests=360} "subset" (subset')-    [ prim "sort" (sort :: [Int] -> [Int])-    , prim "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)+  conjure "subset" (subset')+    [ fun "sort" (sort :: [Int] -> [Int])+    , fun "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)+    , showTheory+    , maxSize 18+    , maxTests 360     ]    -- low number of tests, cannot conjure due to incorrect property-  conjureWith as{maxTests=60} "replicates" replicates'-    [ prim "replicate" (replicate :: Int -> String -> [String])-    , prim "transpose" (transpose :: [[Char]] -> [[Char]])-    , prim "concat"    (concat :: [String] -> String)+  conjure "replicates" replicates'+    [ fun "replicate" (replicate :: Int -> String -> [String])+    , fun "transpose" (transpose :: [[Char]] -> [[Char]])+    , fun "concat"    (concat :: [String] -> String)+    , showTheory+    , maxSize 18+    , maxTests 60     ]    -- emulates how MagicHaskeller generates "replicates"-  conjureWith as{maxTests=360} "replicates" replicates'-    [ prim "replicate" (replicate :: Int -> String -> [String])-    , prim "transpose" (transpose :: [[Char]] -> [[Char]])-    , prim "concat"    (concat :: [String] -> String)+  conjure "replicates" replicates'+    [ fun "replicate" (replicate :: Int -> String -> [String])+    , fun "transpose" (transpose :: [[Char]] -> [[Char]])+    , fun "concat"    (concat :: [String] -> String)+    , showTheory+    , maxSize 18+    , maxTests 360     ]
bench/lowtests.txt view
@@ -32,7 +32,7 @@ -- 0 candidates of size 17 -- 0 candidates of size 18 -- tested 27 candidates-cannot conjure+subset  =  undefined  -- search exhausted  subset :: [Int] -> [Int] -> Bool -- testing 44 combinations of argument values@@ -80,7 +80,7 @@ -- 0 candidates of size 17 -- 0 candidates of size 18 -- tested 6 candidates-cannot conjure+replicates  =  undefined  -- search exhausted  replicates :: [Char] -> Int -> [Char] -- testing 360 combinations of argument values
bench/p12.hs view
@@ -1,13 +1,10 @@--- 12 background primitives+-- 12 background ingredients -- -- Copyright (C) 2021-2025 Rudy Matela -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Conjure import System.Environment -conjureT :: Conjurable f => String -> f -> [Prim] -> IO ()-conjureT  =  conjureWith args{maxSize=1}- factorial :: Int -> Int factorial 0  =  1 factorial 1  =  1@@ -33,42 +30,42 @@  main :: IO () main  =  do-  putStrLn $ "running with " ++ show (length primitives) ++ " primitives"+  putStrLn $ "running with " ++ show (length ingredients) ++ " ingredients"   as <- getArgs   case as of-    ["factorial"]     -> conjure  "factorial n" factorial primitives-    ["factorial","t"] -> conjureT "factorial n" factorial primitives-    ["sum"]           -> conjure  "sum"     (sum     :: [Int] -> Int) primitives-    ["sum","t"]       -> conjureT "sum"     (sum     :: [Int] -> Int) primitives-    ["product"]       -> conjure  "product" (product :: [Int] -> Int) primitives-    ["product","t"]   -> conjureT "product" (product :: [Int] -> Int) primitives-    ["length"]        -> conjure  "length"  (length  :: [Int] -> Int) primitives-    ["length","t"]    -> conjureT "length"  (length  :: [Int] -> Int) primitives-    ["count"]         -> conjure  "count"   count' $ primitives ++ primsCount-    ["count","t"]     -> conjureT "count"   count' $ primitives ++ primsCount-    _                 -> conjure  "factorial n" factorial primitives+    ["factorial"]     -> conjure "factorial n" factorial   ingredients+    ["factorial","t"] -> conjure "factorial n" factorial $ ingredients ++ [maxSize 1]+    ["sum"]           -> conjure "sum"     (sum     :: [Int] -> Int)   ingredients+    ["sum","t"]       -> conjure "sum"     (sum     :: [Int] -> Int) $ ingredients ++ [maxSize 1]+    ["product"]       -> conjure "product" (product :: [Int] -> Int)   ingredients+    ["product","t"]   -> conjure "product" (product :: [Int] -> Int) $ ingredients ++ [maxSize 1]+    ["length"]        -> conjure "length"  (length  :: [Int] -> Int)   ingredients+    ["length","t"]    -> conjure "length"  (length  :: [Int] -> Int) $ ingredients ++ [maxSize 1]+    ["count"]         -> conjure "count"   count' $ ingredients ++ primsCount+    ["count","t"]     -> conjure "count"   count' $ ingredients ++ primsCount ++ [maxSize 1]+    _                 -> conjure "factorial n" factorial ingredients -primitives :: [Prim]-primitives  =-  [ pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "dec" (subtract 1 :: Int -> Int)+ingredients :: [Ingredient]+ingredients  =+  [ con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "dec" (subtract 1 :: Int -> Int) -  , prim "==" ((==) :: Int -> Int -> Bool)+  , fun "==" ((==) :: Int -> Int -> Bool) -  , pr ([] :: [Int])-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prim "head" (head :: [Int] -> Int)-  , prim "tail" (tail :: [Int] -> [Int])-  , prim "null" (null :: [Int] -> Bool)-  , prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)-  , prim ".." (enumFromTo :: Int -> Int -> [Int])+  , con ([] :: [Int])+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , fun "head" (head :: [Int] -> Int)+  , fun "tail" (tail :: [Int] -> [Int])+  , fun "null" (null :: [Int] -> Bool)+  , fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+  , fun ".." (enumFromTo :: Int -> Int -> [Int])   ] -primsCount :: [Prim]+primsCount :: [Ingredient] primsCount  =-  [ prim "length" (length :: [Int] -> Int)-  , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+  [ fun "length" (length :: [Int] -> Int)+  , fun "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])   ]
bench/p12.txt view
@@ -1,4 +1,4 @@-running with 13 primitives+running with 13 ingredients factorial :: Int -> Int -- testing 6 combinations of argument values -- pruning with 67/101 rules
bench/p30.hs view
@@ -1,13 +1,10 @@--- 30 background primitives, does Conjure scale?+-- 30 background ingredients, does Conjure scale? -- -- Copyright (C) 2021-2025 Rudy Matela -- Distributed under the 3-Clause BSD licence (see the file LICENSE). import Conjure import System.Environment -conjureT :: Conjurable f => String -> f -> [Prim] -> IO ()-conjureT  =  conjureWith args{maxSize=1}- factorial :: Int -> Int factorial 0  =  1 factorial 1  =  1@@ -33,58 +30,58 @@  main :: IO () main  =  do-  putStrLn $ "running with " ++ show (length primitives) ++ " primitives"+  putStrLn $ "running with " ++ show (length ingredients) ++ " ingredients"   as <- getArgs   case as of-    ["factorial"]     -> conjure  "factorial n" factorial primitives-    ["factorial","t"] -> conjureT "factorial n" factorial primitives-    ["sum"]           -> conjure  "sum"     (sum     :: [Int] -> Int) primitives-    ["sum","t"]       -> conjureT "sum"     (sum     :: [Int] -> Int) primitives-    ["product"]       -> conjure  "product" (product :: [Int] -> Int) primitives-    ["product","t"]   -> conjureT "product" (product :: [Int] -> Int) primitives-    ["length"]        -> conjure  "length"  (length  :: [Int] -> Int) primitives-    ["length","t"]    -> conjureT "length"  (length  :: [Int] -> Int) primitives-    ["count"]         -> conjure  "count"   count' $ primitives ++ primsLength-    ["count","t"]     -> conjureT "count"   count' $ primitives ++ primsLength+    ["factorial"]     -> conjure "factorial n" factorial   ingredients+    ["factorial","t"] -> conjure "factorial n" factorial $ ingredients ++ [maxSize 1]+    ["sum"]           -> conjure "sum"     (sum     :: [Int] -> Int)   ingredients+    ["sum","t"]       -> conjure "sum"     (sum     :: [Int] -> Int) $ ingredients ++ [maxSize 1]+    ["product"]       -> conjure "product" (product :: [Int] -> Int)   ingredients+    ["product","t"]   -> conjure "product" (product :: [Int] -> Int) $ ingredients ++ [maxSize 1]+    ["length"]        -> conjure "length"  (length  :: [Int] -> Int)   ingredients+    ["length","t"]    -> conjure "length"  (length  :: [Int] -> Int) $ ingredients ++ [maxSize 1]+    ["count"]         -> conjure "count"   count' $ ingredients ++ primsLength+    ["count","t"]     -> conjure "count"   count' $ ingredients ++ primsLength ++ [maxSize 1]     _                 -> putStrLn "usage: p30 <factorial|sum|product|length|count> [t]" -primitives :: [Prim]-primitives  =-  [ pr False-  , pr True-  , prim "&&" (&&)-  , prim "||" (||)-  , prim "not" not+ingredients :: [Ingredient]+ingredients  =+  [ con False+  , con True+  , fun "&&" (&&)+  , fun "||" (||)+  , fun "not" not -  , pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "dec" (subtract 1 :: Int -> Int)-  , prim "-" ((-) :: Int -> Int -> Int)+  , con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "dec" (subtract 1 :: Int -> Int)+  , fun "-" ((-) :: Int -> Int -> Int) -  , prim "==" ((==) :: Int -> Int -> Bool)-  , prim "<=" ((<=) :: Int -> Int -> Bool)-  , prim "<"  ((<) :: Int -> Int -> Bool)+  , fun "==" ((==) :: Int -> Int -> Bool)+  , fun "<=" ((<=) :: Int -> Int -> Bool)+  , fun "<"  ((<) :: Int -> Int -> Bool) -  , prim "const" (const :: Int -> Int -> Int)+  , fun "const" (const :: Int -> Int -> Int) -  , pr ([] :: [Int])-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prim "head" (head :: [Int] -> Int)-  , prim "tail" (tail :: [Int] -> [Int])-  , prim "null" (null :: [Int] -> Bool)-  , prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+  , con ([] :: [Int])+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , fun "head" (head :: [Int] -> Int)+  , fun "tail" (tail :: [Int] -> [Int])+  , fun "null" (null :: [Int] -> Bool)+  , fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int) -  , prim "map" (map :: (Int -> Int) -> [Int] -> [Int])-  , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])-  , prim ".." (enumFromTo :: Int -> Int -> [Int])+  , fun "map" (map :: (Int -> Int) -> [Int] -> [Int])+  , fun "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+  , fun ".." (enumFromTo :: Int -> Int -> [Int]) -  , prim "++" ((++) :: [Int] -> [Int] -> [Int])-  , prim "elem" (elem :: Int -> [Int] -> Bool)+  , fun "++" ((++) :: [Int] -> [Int] -> [Int])+  , fun "elem" (elem :: Int -> [Int] -> Bool)   ] -primsLength :: [Prim]+primsLength :: [Ingredient] primsLength =-  [ prim "length" (length :: [Int] -> Int)+  [ fun "length" (length :: [Int] -> Int)   ]
bench/p30.txt view
@@ -1,2 +1,2 @@-running with 26 primitives+running with 26 ingredients usage: p30 <factorial|sum|product|length|count> [t]
bench/redundants.hs view
@@ -20,8 +20,8 @@ -- * maximum candidate size (5 = few seconds, 7 = few minutes); -- * function name (for pretty-printing purposes); -- * proxy value to indicate the type of functions to generate;--- * list of primitives, in Conjure-compatible form.-printRedundantCandidates :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()+-- * list of ingredients, in Conjure-compatible form.+printRedundantCandidates :: Conjurable f => Int -> String -> f -> [Ingredient] -> IO () printRedundantCandidates n nm f ps  =  do   putStrLn $ "Redundant candidates for: " ++ nm ++ " :: " ++ show (typeOf f)   putStrLn $ "  pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"@@ -40,7 +40,7 @@   css            =  take n                  .  discardT isRedundantByIntroduction -- additional pruning rule                  $  css'-  (css', thy, _, _) =  candidateDefnsC args nm f ps  -- Conjure uses this for listing candidates+  (css', thy, _, _) =  candidateDefns nm f ps  -- Conjure uses this for listing candidates   nRules         =  length (rules thy)   nREs           =  length (equations thy) + nRules   maxTests       =  60 -- a hardcoded value probably will not hurt in this simple benchmark@@ -66,46 +66,46 @@   -- We can also customize the n per-function below:    printRedundantCandidates (n+1) "foo" (undefined :: Int -> Int)-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]    printRedundantCandidates n "?" (undefined :: Int -> Int -> Int)-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "dec" (subtract 1 :: Int -> Int)+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "dec" (subtract 1 :: Int -> Int)     ]    printRedundantCandidates (n+1) "goo" (undefined :: [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printRedundantCandidates n "??" (undefined :: [Int] -> [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printRedundantCandidates (n+1) "ton" (undefined :: Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]    printRedundantCandidates n "&|" (undefined :: Bool -> Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]    -- Degenerate case:@@ -115,7 +115,7 @@   -- through other means   {-   printRedundantCandidates n "gcd" (undefined :: Int -> Int -> Int)-    [ pr (0::Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)+    [ con (0::Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)     ]   -}
bench/runtime/lapmatrud/bench/candidates.runtime view
@@ -1,1 +1,1 @@-9.2+10.0
bench/runtime/lapmatrud/bench/carry-on.runtime view
@@ -1,1 +1,1 @@-2.4+2.6
bench/runtime/lapmatrud/bench/erroneous.runtime view
@@ -1,1 +1,1 @@-2.9+3.1
bench/runtime/lapmatrud/bench/gps.runtime view
@@ -1,1 +1,1 @@-14.7+15.8
bench/runtime/lapmatrud/bench/gps2.runtime view
@@ -1,1 +1,1 @@-11.8+12.7
bench/runtime/lapmatrud/bench/ill-hit.runtime view
@@ -1,1 +1,1 @@-0.5+0.7
bench/runtime/lapmatrud/bench/lowtests.runtime view
@@ -1,1 +1,1 @@-0.4+0.5
bench/runtime/lapmatrud/bench/p12.runtime view
@@ -1,1 +1,1 @@-1.6+1.7
bench/runtime/lapmatrud/bench/redundants.runtime view
@@ -1,1 +1,1 @@-3.0+3.2
bench/runtime/lapmatrud/bench/strategies.runtime view
@@ -1,1 +1,1 @@-4.6+6.0
bench/runtime/lapmatrud/bench/terpret.runtime view
@@ -1,1 +1,1 @@-7.3+7.7
bench/runtime/lapmatrud/bench/unique.runtime view
@@ -1,1 +1,1 @@-2.4+2.5
bench/runtime/lapmatrud/bench/weird.runtime view
@@ -1,1 +1,1 @@-2.5+2.6
bench/runtime/lapmatrud/eg/arith.runtime view
@@ -1,1 +1,1 @@-0.9+1.0
bench/runtime/lapmatrud/eg/bits.runtime view
@@ -1,1 +1,1 @@-3.0+3.2
bench/runtime/lapmatrud/eg/bools.runtime view
@@ -1,1 +1,1 @@-1.6+1.9
bench/runtime/lapmatrud/eg/bst.runtime view
@@ -1,1 +1,1 @@-4.3+4.8
bench/runtime/lapmatrud/eg/count.runtime view
@@ -1,1 +1,1 @@-0.5+0.8
bench/runtime/lapmatrud/eg/dupos.runtime view
@@ -1,1 +1,1 @@-1.9+2.2
bench/runtime/lapmatrud/eg/either.runtime view
@@ -1,1 +1,1 @@-0.1+0.2
bench/runtime/lapmatrud/eg/factorial.runtime view
@@ -1,1 +1,1 @@-1.4+1.6
bench/runtime/lapmatrud/eg/fib01.runtime view
@@ -1,1 +1,1 @@-0.5+0.6
bench/runtime/lapmatrud/eg/fibonacci.runtime view
@@ -1,1 +1,1 @@-3.2+3.5
bench/runtime/lapmatrud/eg/higher.runtime view
@@ -1,1 +1,1 @@-0.8+1.4
bench/runtime/lapmatrud/eg/ints.runtime view
@@ -1,1 +1,1 @@-0.5+1.2
bench/runtime/lapmatrud/eg/maybe.runtime view
@@ -1,1 +1,1 @@-0.3+0.4
bench/runtime/lapmatrud/eg/oddeven.runtime view
@@ -1,1 +1,1 @@-1.5+1.6
bench/runtime/lapmatrud/eg/pow.runtime view
@@ -1,1 +1,1 @@-2.8+3.0
bench/runtime/lapmatrud/eg/sort.runtime view
@@ -1,1 +1,1 @@-3.1+3.4
bench/runtime/lapmatrud/eg/these.runtime view
@@ -1,1 +1,1 @@-1.7+1.9
bench/runtime/lapmatrud/eg/tree.runtime view
@@ -1,1 +1,1 @@-1.4+1.5
bench/runtime/lapmatrud/eg/tri.runtime view
@@ -1,1 +1,1 @@-0.2+0.3
bench/runtime/lapmatrud/eg/tuple.runtime view
@@ -1,1 +1,1 @@-0.5+0.8
bench/runtime/lapmatrud/versions view
@@ -1,4 +1,4 @@-GHC 9.2.8+GHC 9.4.8 leancheck-1.0.2 express-1.0.18 speculate-0.4.20
bench/runtime/zero/bench/candidates.runtime view
@@ -1,1 +1,1 @@-17.8+17.4
bench/runtime/zero/bench/carry-on.runtime view
@@ -1,1 +1,1 @@-4.6+4.8
bench/runtime/zero/bench/erroneous.runtime view
@@ -1,1 +1,1 @@-5.7+5.6
bench/runtime/zero/bench/gps.runtime view
@@ -1,1 +1,1 @@-28.7+27.9
bench/runtime/zero/bench/gps2.runtime view
@@ -1,1 +1,1 @@-23.6+22.8
bench/runtime/zero/bench/ill-hit.runtime view
@@ -1,1 +1,1 @@-1.0+1.1
bench/runtime/zero/bench/longshot.runtime view
@@ -1,1 +1,1 @@-0.0+0.1
bench/runtime/zero/bench/p30.runtime view
@@ -1,1 +1,1 @@-0.0+0.1
bench/runtime/zero/bench/redundants.runtime view
@@ -1,1 +1,1 @@-6.3+6.2
bench/runtime/zero/bench/strategies.runtime view
@@ -1,1 +1,1 @@-8.9+9.1
bench/runtime/zero/bench/weird.runtime view
@@ -1,1 +1,1 @@-4.9+4.7
bench/runtime/zero/eg/arith.runtime view
@@ -1,1 +1,1 @@-2.0+1.9
bench/runtime/zero/eg/bits.runtime view
@@ -1,1 +1,1 @@-5.9+5.8
bench/runtime/zero/eg/bools.runtime view
@@ -1,1 +1,1 @@-3.3+3.2
bench/runtime/zero/eg/bst.runtime view
@@ -1,1 +1,1 @@-8.6+8.5
bench/runtime/zero/eg/dupos.runtime view
@@ -1,1 +1,1 @@-3.8+3.6
bench/runtime/zero/eg/fibonacci.runtime view
@@ -1,1 +1,1 @@-6.3+6.2
bench/runtime/zero/eg/ints.runtime view
@@ -1,1 +1,1 @@-1.1+1.0
bench/runtime/zero/eg/oddeven.runtime view
@@ -1,1 +1,1 @@-2.9+3.0
bench/runtime/zero/eg/setelem.runtime view
@@ -1,1 +1,1 @@-1.5+1.4
bench/runtime/zero/eg/sort.runtime view
@@ -1,1 +1,1 @@-5.9+6.0
bench/runtime/zero/eg/spec.runtime view
@@ -1,1 +1,1 @@-1.6+1.5
bench/runtime/zero/eg/these.runtime view
@@ -1,1 +1,1 @@-3.5+3.4
bench/runtime/zero/eg/tree.runtime view
@@ -1,1 +1,1 @@-2.7+2.6
bench/runtime/zero/eg/tuple.runtime view
@@ -1,1 +1,1 @@-0.9+1.4
bench/runtime/zero/versions view
@@ -1,4 +1,4 @@-GHC 9.2.8+GHC 9.4.8 leancheck-1.0.2 express-1.0.18 speculate-0.4.20
bench/self.hs view
@@ -6,19 +6,17 @@  main :: IO () main = do-  cj "?" ((+) :: Int -> Int -> Int)   primitives-  cj "?" ((*) :: Int -> Int -> Int)   primitives-  cj "i" ((+1) :: Int -> Int)         primitives-  cj "d" ((subtract 1) :: Int -> Int) primitives-  where-  -- the monomorphism restriction strikes again-  cj :: Conjurable f => String -> f -> [Prim] -> IO ()-  cj  =  conjureWith args{maxSize=3,maxEquationSize=0}+  conjure "?" ((+) :: Int -> Int -> Int)   ingredients+  conjure "?" ((*) :: Int -> Int -> Int)   ingredients+  conjure "i" ((+1) :: Int -> Int)         ingredients+  conjure "d" ((subtract 1) :: Int -> Int) ingredients -primitives :: [Prim]-primitives =-  [ pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)+ingredients :: [Ingredient]+ingredients =+  [ con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , maxSize 3+  , maxEquationSize 0   ]
bench/self.txt view
@@ -32,5 +32,5 @@ -- 3 candidates of size 2 -- 12 candidates of size 3 -- tested 18 candidates-cannot conjure+d  =  undefined  -- search exhausted 
bench/strategies.hs view
@@ -11,16 +11,13 @@ factorial 4  =  24  -mkStrategy :: String -> Args-mkStrategy s  =  args-  { rewriting         =  r-  , requireDescent    =  d-  , adHocRedundancy   =  a-  , copyBindings      =  a -- previously c-  , uniqueCandidates  =  u---, carryOn  =  True---, maxSize  =  10-  }+-- TODO: simplify and refactor+mkStrategy :: String -> [Ingredient]+mkStrategy s  =  [ dontRewrite | not r ]+              ++ [ dontRequireDescent | not d ]+              ++ [ omitAssortedPruning | not a ]+              ++ [ dontCopyBindings | not a ]+              ++ [ uniqueCandidates | u]   where   itob 0  =  False   itob _  =  True@@ -37,10 +34,10 @@     "only typed"        -> [0,0,0,0]     _                   -> error "unknown strategy" -conjureStrategy :: Conjurable f => String -> String -> f -> [Prim] -> IO ()-conjureStrategy name nm f prims  =  do+conjureStrategy :: Conjurable f => String -> String -> f -> [Ingredient] -> IO ()+conjureStrategy name nm f ingrs =  do   putStrLn $ "-- strategy: " ++ name-  conjureWith (mkStrategy name) nm f prims+  conjure nm f $ ingrs ++ mkStrategy name  strategies :: [String] strategies  =  @@ -58,15 +55,15 @@ main :: IO () main  =  do   sequence_-    [ conjureStrategy s "factorial n" factorial primitives+    [ conjureStrategy s "factorial n" factorial ingredients     | s <- strategies     ] -primitives :: [Prim]-primitives = -    [ pr (0::Int)-    , pr (1::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+ingredients :: [Ingredient]+ingredients = +    [ con (0::Int)+    , con (1::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]
bench/terpret.hs view
@@ -28,20 +28,20 @@ t1c  =  do   putStrLn "TerpreT benchmark #1: invert\n" -  conjure "invert" t1p primitives123+  conjure "invert" t1p ingredients123 --- the same primitives are used for TerpreT #1, #2 and #3-primitives123 :: [Prim]-primitives123  =-  [ pr False-  , pr True-  , prim "not" not-  , prim "&&" (&&)-  , prim "||" (||)-  , pr ([] :: [Bool])-  , prim ":" ((:) :: Bool -> [Bool] -> [Bool])---, prim "map" (map :: (Bool -> Bool) -> [Bool] -> [Bool])-  , prif (undefined :: [Bool])+-- the same ingredients are used for TerpreT #1, #2 and #3+ingredients123 :: [Ingredient]+ingredients123  =+  [ con False+  , con True+  , fun "not" not+  , fun "&&" (&&)+  , fun "||" (||)+  , con ([] :: [Bool])+  , fun ":" ((:) :: Bool -> [Bool] -> [Bool])+--, fun "map" (map :: (Bool -> Bool) -> [Bool] -> [Bool])+  , iif (undefined :: [Bool])   ]  @@ -58,7 +58,7 @@ t2c  =  do   putStrLn "TerpreT benchmark #2: prepend zero\n" -  conjure "prependZero" t2p primitives123+  conjure "prependZero" t2p ingredients123   -- TerpreT #3 -- binary decrement --@@ -83,7 +83,7 @@ t3c  =  do   putStrLn "TerpreT benchmark #3: binary decrement\n" -  conjure "decrement" t3p primitives123+  conjure "decrement" t3p ingredients123   -- TerpreT #4 -- 2-bit controlled shift register --@@ -108,14 +108,15 @@ t4c  =  do   putStrLn "TerpreT benchmark #4: controlled shift\n" -  conjureWith args{target = 50400} "cshift" t4p1 $ primitives123 ++-    [ prim ",," ((,,) :: Bool -> Bool -> Bool -> (Bool,Bool,Bool))-    , prif (undefined :: (Bool,Bool,Bool))+  conjure "cshift" t4p1 $ ingredients123 +++    [ fun ",," ((,,) :: Bool -> Bool -> Bool -> (Bool,Bool,Bool))+    , iif (undefined :: (Bool,Bool,Bool))+    , target 50400     ] -  conjure "cshift" t4p2 $ primitives123 ++-    [ prim ",," ((,,) :: Bool -> Bool -> Bool -> (Bool,Bool,Bool))-    , prif (undefined :: (Bool,Bool,Bool))+  conjure "cshift" t4p2 $ ingredients123 +++    [ fun ",," ((,,) :: Bool -> Bool -> Bool -> (Bool,Bool,Bool))+    , iif (undefined :: (Bool,Bool,Bool))     ]  @@ -135,15 +136,15 @@ t5c  =  do   putStrLn "TerpreT benchmark #5: full adder\n" -  -- using primitives123 below works, but increases the runtime to 18 seconds+  -- using ingredients123 below works, but increases the runtime to 18 seconds   -- let's leave it commented out so runtime is faster when running automated tests-  -- BENCHMARK: uncomment primitives123-  conjure "fadder" t5p $ -- primitives123 ++-    [ prim "not" not-    , prim "," ((,) :: Bool -> Bool -> (Bool,Bool))-    , prim "==" ((==) :: Bool -> Bool -> Bool)---  , prim "^^" ((/=) :: Bool -> Bool -> Bool) -- poor man's xor-    , prif (undefined :: (Bool,Bool))+  -- BENCHMARK: uncomment ingredients123+  conjure "fadder" t5p $ -- ingredients123 +++    [ fun "not" not+    , fun "," ((,) :: Bool -> Bool -> (Bool,Bool))+    , fun "==" ((==) :: Bool -> Bool -> Bool)+--  , fun "^^" ((/=) :: Bool -> Bool -> Bool) -- poor man's xor+    , iif (undefined :: (Bool,Bool))     ] -- the printed function is weird, but correct -- fadder p q r  =  if p == q then (p,r) else (r,not r)@@ -160,11 +161,12 @@ t6c :: IO () t6c  =  do   putStrLn "TerpreT benchmark #6: 2-bit adder\n"-  conjureWith args{maxSize=6} "adder2" t6p $ primitives123 ++-    [ prim ",," ((,,) :: Bool -> Bool -> Bool -> (Bool,Bool,Bool))-    , prim "==" ((==) :: Bool -> Bool -> Bool)-    , prim "^^" ((/=) :: Bool -> Bool -> Bool) -- poor man's xor-    , prif (undefined :: (Bool,Bool,Bool))+  conjure "adder2" t6p $ ingredients123 +++    [ fun ",," ((,,) :: Bool -> Bool -> Bool -> (Bool,Bool,Bool))+    , fun "==" ((==) :: Bool -> Bool -> Bool)+    , fun "^^" ((/=) :: Bool -> Bool -> Bool) -- poor man's xor+    , iif (undefined :: (Bool,Bool,Bool))+    , maxSize 6     ]  @@ -186,16 +188,16 @@   putStrLn "TerpreT benchmark #7: access\n"   -- yes, one can implement index with index...   conjure "`access`" t7p-    [ prim "!!" ((!!) :: [A] -> Int -> A)+    [ fun "!!" ((!!) :: [A] -> Int -> A)     ]    conjure "`access`" t7p-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr ([] :: [A])-    , prim ":" ((:) :: A -> [A] -> [A])-    , prim "-" ((-) :: Int -> Int -> Int)-    , prim "undefined" (undefined :: A)+    [ con (0 :: Int)+    , con (1 :: Int)+    , con ([] :: [A])+    , fun ":" ((:) :: A -> [A] -> [A])+    , fun "-" ((-) :: Int -> Int -> Int)+    , fun "undefined" (undefined :: A)     ]  @@ -210,22 +212,22 @@   putStrLn "TerpreT benchmark #8: decrement elements\n"    conjure "decrelements" t8p-    [ pr (1 :: Int)-    , pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "-" ((-) :: Int -> Int -> Int)-    , prim "map" (map :: (Int -> Int) -> [Int] -> [Int])+    [ con (1 :: Int)+    , con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "-" ((-) :: Int -> Int -> Int)+    , fun "map" (map :: (Int -> Int) -> [Int] -> [Int])     ]   -- above, even though map is provided, Conjure cannot use it as it cannot   -- introduce lambdas    conjure "decrelements" t8p-    [ pr (1 :: Int)-    , pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "-" ((-) :: Int -> Int -> Int)-    , prim "map" (map :: (Int -> Int) -> [Int] -> [Int])-    , prim "subtract" (subtract :: Int -> Int -> Int)+    [ con (1 :: Int)+    , con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "-" ((-) :: Int -> Int -> Int)+    , fun "map" (map :: (Int -> Int) -> [Int] -> [Int])+    , fun "subtract" (subtract :: Int -> Int -> Int)     ]   -- now above, the story changes because of subtract, map is used 
bench/terpret.txt view
@@ -116,7 +116,7 @@ -- 0 candidates of size 5 -- 0 candidates of size 6 -- tested 8 candidates-cannot conjure+adder2  =  undefined  -- search exhausted  TerpreT benchmark #7: access 
bench/unique.hs view
@@ -23,8 +23,8 @@ -- * maximum candidate size (5 = few seconds, 7 = few minutes); -- * function name (for pretty-printing purposes); -- * proxy value to indicate the type of functions to generate;--- * list of primitives, in Conjure-compatible form.-printUniqueCandidates :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()+-- * list of ingredients, in Conjure-compatible form.+printUniqueCandidates :: Conjurable f => Int -> String -> f -> [Ingredient] -> IO () printUniqueCandidates n nm f ps  =  do   putStrLn $ "Unique candidates for: " ++ nm ++ " :: " ++ show (typeOf f)   putStrLn $ "  pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"@@ -46,7 +46,7 @@   css            =  take n                  $  discardT isRedundantByIntroduction -- additional pruning rule                  $  css'-  (css', thy, _, _) =  candidateDefnsC args nm f ps  -- Conjure uses this for listing candidates+  (css', thy, _, _) =  candidateDefns nm f ps  -- Conjure uses this for listing candidates   nRules         =  length (rules thy)   nREs           =  length (equations thy) + nRules   maxTests       =  60 -- a hardcoded value probably will not hurt in this simple benchmark@@ -64,44 +64,44 @@   let n = 5    printUniqueCandidates (n+2) "foo" (undefined :: Int -> Int)-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]    printUniqueCandidates n "?" (undefined :: Int -> Int -> Int)-    [ pr (0 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "dec" (subtract 1 :: Int -> Int)+    [ con (0 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "dec" (subtract 1 :: Int -> Int)     ]    printUniqueCandidates (n+2) "goo" (undefined :: [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printUniqueCandidates n "??" (undefined :: [Int] -> [Int] -> [Int])-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    printUniqueCandidates (n+2) "ton" (undefined :: Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]    printUniqueCandidates n "&|" (undefined :: Bool -> Bool -> Bool)-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not     ]
bench/weird.hs view
@@ -21,24 +21,24 @@  main :: IO () main  =  do-  conjure "^^^" (^^^) primitives-  conjureWith args{usePatterns = False} "^^^" (^^^) primitives+  conjure "^^^" (^^^)   ingredients+  conjure "^^^" (^^^) $ ingredients ++ [singlePattern]    -- This example is quite the degenerate case,-  -- it takes a while to conjure even with just 2 primitives.+  -- it takes a while to conjure even with just 2 ingredients.   -- I am leaving it commented-out for now...-  -- conjure "thirty" thirty [pr (0::Int), prim "+" ((+) :: Int -> Int -> Int)]+  -- conjure "thirty" thirty [pr (0::Int), fun "+" ((+) :: Int -> Int -> Int)] -primitives :: [Prim]-primitives  =-  [ pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "==" ((==) :: Int -> Int -> Bool)-  , prim "&&" (&&)-  , prim "||" (||)-  , prif (undefined :: Int)+ingredients :: [Ingredient]+ingredients  =+  [ con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "==" ((==) :: Int -> Int -> Bool)+  , fun "&&" (&&)+  , fun "||" (||)+  , iif (undefined :: Int)   -- guard does not play well with usePatterns = False yet   ] 
changelog.md view
@@ -2,6 +2,25 @@ ============================  +v0.7.0 (May 2025)+-----------------++* Several breaking API changes;+* `Prim` is now `Ingredient`;+* `pr` and `prim` are now `con` and `fun`;+* `prif` is now `iif`;+* `primOrdCaseFor` is now `ordcase`;+* `Prim`, `pr`, `prim`, `prif`, `primOrdCaseFor` are deprecated;+* `Args` and `args` were replaced by ingredient settings:+  `maxTests`, `target`, `maxSize`, etc;+* display `search exhausted` when a suitable candidate is not found+  (instead of `cannot conjure`);+* display warning when the specification cannot be reified;+* lightly improve internal testing of `conjure`;+* try to place recursive calls last in commutative operators+  before showing a resulting function.++ v0.6.10 (February 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.6.10+version:             0.7.0 synopsis:            synthesize Haskell functions out of partial definitions description:   Conjure is a tool that synthesizes Haskell functions out of partial definitions.@@ -69,7 +69,7 @@ source-repository this   type:            git   location:        https://github.com/rudymatela/conjure-  tag:             v0.6.10+  tag:             v0.7.0  library   exposed-modules: Conjure@@ -77,13 +77,14 @@                  , Conjure.Conjurable.Derive                  , Conjure.Engine                  , Conjure.Expr-                 , Conjure.Prim+                 , Conjure.Ingredient                  , Conjure.Utils                  , Conjure.Defn                  , Conjure.Defn.Redundancy                  , Conjure.Defn.Test                  , Conjure.Red                  , Conjure.Reason+                 , Conjure.Settings   other-extensions: TemplateHaskell, CPP   build-depends: base >= 4 && < 5                , leancheck >= 1.0.0@@ -136,6 +137,14 @@ test-suite red   type:                exitcode-stdio-1.0   main-is:             red.hs+  other-modules:       Test, Test.ListableExpr+  hs-source-dirs:      test+  build-depends:       base >= 4 && < 5, leancheck, express, speculate, code-conjure+  default-language:    Haskell2010++test-suite factorial+  type:                exitcode-stdio-1.0+  main-is:             factorial.hs   other-modules:       Test, Test.ListableExpr   hs-source-dirs:      test   build-depends:       base >= 4 && < 5, leancheck, express, speculate, code-conjure
eg/arith.hs view
@@ -39,17 +39,17 @@  main :: IO () main = do-  conjure "double" double primitives-  conjure "triple" triple primitives-  conjure "add"    add    primitives-  conjure "square" square primitives-  conjure "cube"   cube   primitives-  conjure "tnpo"   tnpo   primitives+  conjure "double" double ingredients+  conjure "triple" triple ingredients+  conjure "add"    add    ingredients+  conjure "square" square ingredients+  conjure "cube"   cube   ingredients+  conjure "tnpo"   tnpo   ingredients -primitives :: [Prim]-primitives =-  [ pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)+ingredients :: [Ingredient]+ingredients =+  [ con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)   ]
eg/bits.hs view
@@ -19,22 +19,22 @@ main :: IO () main  =  do   conjure "bitsum" bitsum-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "halve" ((`div` 2) :: Int -> Int)-    , prim "parity" ((`mod` 2) :: Int -> Int)-    , prim "+" ((+) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "halve" ((`div` 2) :: Int -> Int)+    , fun "parity" ((`mod` 2) :: Int -> Int)+    , fun "+" ((+) :: Int -> Int -> Int)     ]   -- bitsum 0  =  0   -- bitsum n  =  parity n + bitsum (halve n)    conjure "bitsum" bitsum-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr (2 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "`div`" (div :: Int -> Int -> Int)-    , prim "`mod`" (mod :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , con (2 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "`div`" (div :: Int -> Int -> Int)+    , fun "`mod`" (mod :: Int -> Int -> Int)     ]   -- bitsum 0  =  0   -- bitsum n  =  n `mod` 2 + bitsum (n `div` 2)
eg/bits.txt view
@@ -10,7 +10,7 @@ -- 182 candidates of size 7 -- tested 145 candidates bitsum 0  =  0-bitsum x  =  bitsum (halve x) + parity x+bitsum x  =  parity x + bitsum (halve x)  bitsum :: Int -> Int -- testing 8 combinations of argument values@@ -26,5 +26,5 @@ -- 89215 candidates of size 9 -- tested 10191 candidates bitsum 0  =  0-bitsum x  =  bitsum (x `div` 2) + x `mod` 2+bitsum x  =  x `mod` 2 + bitsum (x `div` 2) 
eg/bools.hs view
@@ -16,23 +16,23 @@  main :: IO () main = do-  conjure "and" (and' :: [Bool] -> Bool) primitives-  conjure "or"  (or'  :: [Bool] -> Bool) primitives+  conjure "and" (and' :: [Bool] -> Bool) ingredients+  conjure "or"  (or'  :: [Bool] -> Bool) ingredients    -- conjure can use fold as well-  conjure "and" (and' :: [Bool] -> Bool) primitivesWithFold-  conjure "or"  (or'  :: [Bool] -> Bool) primitivesWithFold+  conjure "and" (and' :: [Bool] -> Bool) ingredientsWithFold+  conjure "or"  (or'  :: [Bool] -> Bool) ingredientsWithFold -primitives :: [Prim]-primitives =-  [ pr False-  , pr True-  , prim "not" not-  , prim "||" (||)-  , prim "&&" (&&)+ingredients :: [Ingredient]+ingredients =+  [ con False+  , con True+  , fun "not" not+  , fun "||" (||)+  , fun "&&" (&&)   ] -primitivesWithFold :: [Prim]-primitivesWithFold  =-    prim "foldr" (foldr :: (Bool -> Bool -> Bool) -> Bool -> [Bool] -> Bool)-  : primitives+ingredientsWithFold :: [Ingredient]+ingredientsWithFold  =+    fun "foldr" (foldr :: (Bool -> Bool -> Bool) -> Bool -> [Bool] -> Bool)+  : ingredients
eg/bst.hs view
@@ -123,74 +123,81 @@ main :: IO () main = do   conjure "mem" mem-    [ pr False-    , prim "||" (||)-    , prim "==" ((==) :: Int -> Int -> Bool)-    , prim "<" ((<) :: Int -> Int -> Bool)+    [ con False+    , fun "||" (||)+    , fun "==" ((==) :: Int -> Int -> Bool)+    , fun "<" ((<) :: Int -> Int -> Bool)     , guard     ]    conjure "mem" mem-    [ pr False-    , pr True-    , prim "`compare`" (compare :: Int -> Int -> Ordering)-    , primOrdCaseFor (undefined :: Bool)+    [ con False+    , con True+    , fun "`compare`" (compare :: Int -> Int -> Ordering)+    , ordcase (undefined :: Bool)     ]    -- simply out of reach performance-wise (reaching 16 but need size 22)-  conjureWithMaxSize 12 "insert" insert-    [ pr Leaf-    , prim "Node" Node-    , prim "unit" unit-    , prim "`compare`" (compare :: Int -> Int -> Ordering)-    , primOrdCaseFor (undefined :: Tree)+  conjure "insert" insert+    [ con Leaf+    , fun "Node" Node+    , fun "unit" unit+    , fun "`compare`" (compare :: Int -> Int -> Ordering)+    , ordcase (undefined :: Tree)+    , maxSize 12     ]    -- reachable in 15s, candidate #32878 at size 14.   -- increase target to 50400 to reach...-  conjureFromSpecWith args{target=5040} "before" beforeSpec-    [ pr Leaf-    , prim "Node" Node-    , prim "==" ((==) :: Int -> Int -> Bool)-    , prim "<" ((<) :: Int -> Int -> Bool)+  conjureFromSpec "before" beforeSpec+    [ con Leaf+    , fun "Node" Node+    , fun "==" ((==) :: Int -> Int -> Bool)+    , fun "<" ((<) :: Int -> Int -> Bool)     , guard+    , target 5040     ]    -- reachable in 14s, candidate #32747 at size 14.   -- increase target to 50400 to reach...-  conjureFromSpecWith args{target=5040} "beyond" beyondSpec-    [ pr Leaf-    , prim "Node" Node-    , prim "==" ((==) :: Int -> Int -> Bool)-    , prim "<=" ((<) :: Int -> Int -> Bool)+  conjureFromSpec "beyond" beyondSpec+    [ con Leaf+    , fun "Node" Node+    , fun "==" ((==) :: Int -> Int -> Bool)+    , fun "<=" ((<) :: Int -> Int -> Bool)     , guard+    , target 5040     ]    -- with 15, this reaches the solution, using 12 for shorter runtime   -- using maxEquationSize = 7 reduces runtime from 13s to 11s-  conjureFromSpecWith args{maxSize = 12, maxEquationSize = 7} "before" beforeSpec-    [ pr Leaf-    , prim "Node" Node-    , prim "`compare`" (compare :: Int -> Int -> Ordering)-    , primOrdCaseFor (undefined :: Tree)+  conjureFromSpec "before" beforeSpec+    [ con Leaf+    , fun "Node" Node+    , fun "`compare`" (compare :: Int -> Int -> Ordering)+    , ordcase (undefined :: Tree)+    , maxSize 12+    , maxEquationSize 7     ]    -- with 15, this reaches the solution, using 12 for shorter runtime   -- using maxEquationSize = 7 reduces runtime from 13s to 11s-  conjureFromSpecWith args{maxSize = 12, maxEquationSize = 7} "beyond" beyondSpec-    [ pr Leaf-    , prim "Node" Node-    , prim "`compare`" (compare :: Int -> Int -> Ordering)-    , primOrdCaseFor (undefined :: Tree)+  conjureFromSpec "beyond" beyondSpec+    [ con Leaf+    , fun "Node" Node+    , fun "`compare`" (compare :: Int -> Int -> Ordering)+    , ordcase (undefined :: Tree)+    , maxSize 12+    , maxEquationSize 7     ]    -- reachable in 55s, candidate #173109 at size 13.-  -- increase to 554400 to reach-  conjureWith args{target=5544} "union" union-    [ pr Leaf-    , prim "Node" Node-    , prim "before" before-    , prim "beyond" beyond+  conjure "union" union+    [ con Leaf+    , fun "Node" Node+    , fun "before" before+    , fun "beyond" beyond+    , target 5544 -- increase to 554400 to reach     ]   -- maybe with invariant following test data there will be more pruning   -- properties?
eg/bst.txt view
@@ -15,7 +15,7 @@ -- 96 candidates of size 12 -- tested 362 candidates mem x Leaf  =  False-mem x (Node t1 y t2)  =  mem x t1 || (mem x t2 || x == y)+mem x (Node t1 y t2)  =  mem x t1 || (x == y || mem x t2)  mem :: Int -> Tree -> Bool -- testing 360 combinations of argument values@@ -55,7 +55,7 @@ -- 0 candidates of size 11 -- 32 candidates of size 12 -- tested 264 candidates-cannot conjure+insert  =  undefined  -- search exhausted  before :: Int -> Tree -> Tree -- pruning with 5/6 rules@@ -71,7 +71,7 @@ -- 1342 candidates of size 10 -- 3543 candidates of size 11 -- tested 5343 candidates-cannot conjure+before  =  undefined  -- search exhausted  beyond :: Int -> Tree -> Tree -- pruning with 5/6 rules@@ -87,7 +87,7 @@ -- 1342 candidates of size 10 -- 3543 candidates of size 11 -- tested 5343 candidates-cannot conjure+beyond  =  undefined  -- search exhausted  before :: Int -> Tree -> Tree -- pruning with 2/4 rules@@ -104,7 +104,7 @@ -- 5103 candidates of size 11 -- 1472 candidates of size 12 -- tested 8207 candidates-cannot conjure+before  =  undefined  -- search exhausted  beyond :: Int -> Tree -> Tree -- pruning with 2/4 rules@@ -121,7 +121,7 @@ -- 5103 candidates of size 11 -- 1472 candidates of size 12 -- tested 8207 candidates-cannot conjure+beyond  =  undefined  -- search exhausted  union :: Tree -> Tree -> Tree -- testing 360 combinations of argument values@@ -137,5 +137,5 @@ -- 3018 candidates of size 9 -- 8098 candidates of size 10 -- tested 11531 candidates-cannot conjure+union  =  undefined  -- search exhausted 
eg/colin/IntFuns.hs view
@@ -12,12 +12,12 @@ -- hoping for something like -- tri x = if x==1 then 1 else x + tri (dec x) -triPrimitives :: [Prim]-triPrimitives =-  [ prim "==" ((==) :: Int -> Int -> Bool)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "dec" ((\x -> x-1) :: Int -> Int)+triIngredients :: [Ingredient]+triIngredients =+  [ fun "==" ((==) :: Int -> Int -> Bool)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "dec" ((\x -> x-1) :: Int -> Int)   ]  -- looking through 3039 candidates, 25% match, 1/4 assignments@@ -34,13 +34,13 @@ -- hoping for something like -- fib x = if x <= 1 then 1 else fib (dec (dec x)) + fib (dec x) --         1  2 3  4      5      6    7    8   9   10 11  12  13-fibPrimitives :: [Prim]-fibPrimitives =-  [ prim "<=" ((<=) :: Int -> Int -> Bool)-  , pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "dec" ((\x -> x-1) :: Int -> Int)+fibIngredients :: [Ingredient]+fibIngredients =+  [ fun "<=" ((<=) :: Int -> Int -> Bool)+  , con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "dec" ((\x -> x-1) :: Int -> Int)   ]  -- looking through 23418 candidates@@ -54,10 +54,10 @@  -- hoping for -- exp x = product (replicate x x)-expPrimitives :: [Prim]-expPrimitives =-  [ prim "replicate" (replicate :: Int -> Int -> [Int])-  , prim "product" (product :: [Int] -> Int)+expIngredients :: [Ingredient]+expIngredients =+  [ fun "replicate" (replicate :: Int -> Int -> [Int])+  , fun "product" (product :: [Int] -> Int)   ]  -- looking through 18 candidates@@ -74,12 +74,12 @@  -- hoping for something like -- pri p = factors p == list2 1 p-priPrimitives :: [Prim]-priPrimitives =-  [ prim "==" ((==) :: [Int] -> [Int] -> Bool)-  , prim "factors" ((\n -> filter (\k -> n `mod` k == 0) [1..n]) :: Int -> [Int])-  , prim "list2" ((\i j -> [i,j]) :: Int -> Int -> [Int])-  , pr (1 :: Int)+priIngredients :: [Ingredient]+priIngredients =+  [ fun "==" ((==) :: [Int] -> [Int] -> Bool)+  , fun "factors" ((\n -> filter (\k -> n `mod` k == 0) [1..n]) :: Int -> [Int])+  , fun "list2" ((\i j -> [i,j]) :: Int -> Int -> [Int])+  , con (1 :: Int)   ]  -- looking through 38 candidates, 100% match, 7/7 assignments@@ -88,8 +88,8 @@  main :: IO () main = do-  conjureWithMaxSize 10 "tri" tri triPrimitives-  conjureWith args{maxSize=13} "fib" fib fibPrimitives-  conjure "exp" exp expPrimitives-  conjure "pri" pri priPrimitives+  conjureWithMaxSize 10 "tri" tri triIngredients+  conjureWith args{maxSize=13} "fib" fib fibIngredients+  conjure "exp" exp expIngredients+  conjure "pri" pri priIngredients 
eg/colin/ListFuns.hs view
@@ -11,10 +11,10 @@ -- sum []      =  0 -- sum (x:xs)  =  x + sum xs -sumBackground :: [Prim]+sumBackground :: [Ingredient] sumBackground =-  [ pr (0::Int)-  , prim "+" ((+) :: Int -> Int -> Int)+  [ con (0::Int)+  , fun "+" ((+) :: Int -> Int -> Int)   ]  app :: [Int] -> [Int] -> [Int]@@ -26,9 +26,9 @@ -- app []     ys  =  ys -- app (x:xs) ys  =  x : app xs ys -appBackground :: [Prim]+appBackground :: [Ingredient] appBackground =-  [ prim ":" ((:) :: Int -> [Int] -> [Int])  +  [ fun ":" ((:) :: Int -> [Int] -> [Int])     ]  mem :: Int -> [Int] -> Bool@@ -42,12 +42,12 @@ -- mem x []      =  False -- mem x (y:ys)  =  x == y || mem x ys -memBackground :: [Prim]+memBackground :: [Ingredient] memBackground =-  [ pr False-  , prim "==" ((==) :: Int -> Int -> Bool)-  , prim "&&" ((&&) :: Bool -> Bool -> Bool)-  , prim "||" ((||) :: Bool -> Bool -> Bool)+  [ con False+  , fun "==" ((==) :: Int -> Int -> Bool)+  , fun "&&" ((&&) :: Bool -> Bool -> Bool)+  , fun "||" ((||) :: Bool -> Bool -> Bool)   ]  sub :: [Int] -> [Int] -> Bool@@ -67,13 +67,13 @@ -- sub _      []      =  False -- sub (x:xs) (y:ys)  =  if x == y then sub xs ys else sub (x:xs) ys -subBackground :: [Prim]+subBackground :: [Ingredient] subBackground  =-  [ pr True-  , pr False-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prim "==" ((==) :: Int -> Int -> Bool)-  , prif (undefined :: Bool)+  [ con True+  , con False+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , fun "==" ((==) :: Int -> Int -> Bool)+  , iif (undefined :: Bool)   ]  set :: [Int] -> Bool@@ -90,11 +90,11 @@ -- set []      =  True -- set (x:xs)  =  not (elem x xs) && set xs -setBackground :: [Prim]+setBackground :: [Ingredient] setBackground =-  [ prim "not" (not :: Bool -> Bool)-  , prim "&&" ((&&) :: Bool -> Bool -> Bool)-  , prim "elem" (elem :: Int -> [Int] -> Bool)+  [ fun "not" (not :: Bool -> Bool)+  , fun "&&" ((&&) :: Bool -> Bool -> Bool)+  , fun "elem" (elem :: Int -> [Int] -> Bool)   ]  take :: Int -> [A] -> [A]@@ -110,13 +110,13 @@ -- take x []      =  [] -- take x (y:ys)  =  y : take (x-1) ys -takeBackground :: [Prim]+takeBackground :: [Ingredient] takeBackground  =-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , pr ([] :: [A])-  , prim "-" ((-) :: Int -> Int -> Int)-  , prim ":" ((:) :: A -> [A] -> [A])+  [ con (0 :: Int)+  , con (1 :: Int)+  , con ([] :: [A])+  , fun "-" ((-) :: Int -> Int -> Int)+  , fun ":" ((:) :: A -> [A] -> [A])   ]  drop :: Int -> [A] -> [A]@@ -132,12 +132,12 @@ -- drop x []  =  [] -- drop x (y:ys)  =  drop (x-1) ys -dropBackground :: [Prim]+dropBackground :: [Ingredient] dropBackground  =-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , pr ([] :: [A])-  , prim "-" ((-) :: Int -> Int -> Int)+  [ con (0 :: Int)+  , con (1 :: Int)+  , con ([] :: [A])+  , fun "-" ((-) :: Int -> Int -> Int)   ]  ord :: [Int] -> Bool@@ -153,14 +153,14 @@ -- ord [x]  =  True -- ord (x:y:ys)  =  x <= y && ord (y:ys) -ordBackground :: [Prim]+ordBackground :: [Ingredient] ordBackground  =-  [ pr True-  , prim "null" (null :: [Int] -> Bool)-  , prim "head" (head :: [Int] -> Int)-  , prim "<=" ((<=) :: Int -> Int -> Bool)-  , prim "&&" (&&)-  , prim "||" (||)+  [ con True+  , fun "null" (null :: [Int] -> Bool)+  , fun "head" (head :: [Int] -> Int)+  , fun "<=" ((<=) :: Int -> Int -> Bool)+  , fun "&&" (&&)+  , fun "||" (||)   ]  merge :: [Int] -> [Int] -> [Int]@@ -176,12 +176,12 @@                         then x : merge xs (y:ys)                         else y : merge (x:xs) ys -mergeBackground :: [Prim]+mergeBackground :: [Ingredient] mergeBackground  =-  [ prim "<=" ((<=) :: Int -> Int -> Bool)-  , pr ([] :: [Int])-  , prim ":" ((:) :: Int -> [Int] -> [Int])-  , prif (undefined :: [Int])+  [ fun "<=" ((<=) :: Int -> Int -> Bool)+  , con ([] :: [Int])+  , fun ":" ((:) :: Int -> [Int] -> [Int])+  , iif (undefined :: [Int])   ]  zip :: [A] -> [B] -> [(A,B)]@@ -195,11 +195,11 @@ -- zip (x:xs) []      =  [] -- zip (x:xs) (y:ys)  =  (x,y) : zip xs ys -zipBackground :: [Prim]+zipBackground :: [Ingredient] zipBackground  =-  [ pr ([] :: [(A,B)])-  , prim "(,)" ((,) :: A -> B -> (A,B))-  , prim ":" ((:) :: (A,B) -> [(A,B)] -> [(A,B)])+  [ con ([] :: [(A,B)])+  , fun "(,)" ((,) :: A -> B -> (A,B))+  , fun ":" ((:) :: (A,B) -> [(A,B)] -> [(A,B)])   ]  assocs :: Int -> [(Int,A)] -> [A]@@ -212,14 +212,14 @@ -- assocs _ []      =  [] -- assocs n (x:xs)  =  if fst x == n then snd x : assocs n xs else assocs n xs -assocsBackground :: [Prim]+assocsBackground :: [Ingredient] assocsBackground  =-  [ pr ([] :: [A])-  , prim "==" ((==) :: Int -> Int -> Bool)-  , prim ":" ((:) :: A -> [A] -> [A])-  , prim "fst" (fst :: (Int,A) -> Int)-  , prim "snd" (snd :: (Int,A) -> A)-  , prif (undefined :: [A])+  [ con ([] :: [A])+  , fun "==" ((==) :: Int -> Int -> Bool)+  , fun ":" ((:) :: A -> [A] -> [A])+  , fun "fst" (fst :: (Int,A) -> Int)+  , fun "snd" (snd :: (Int,A) -> A)+  , iif (undefined :: [A])   ]  main :: IO ()
eg/count.hs view
@@ -30,27 +30,27 @@   -- count x xs  =  length (filter (== x) xs)   --                1       2       3  4  5   conjure "count" count'-    [ prim "length" (length :: [A] -> Int)-    , prim "filter" (filter :: (A -> Bool) -> [A] -> [A])-    , prim "==" ((==) :: A -> A -> Bool)+    [ fun "length" (length :: [A] -> Int)+    , fun "filter" (filter :: (A -> Bool) -> [A] -> [A])+    , fun "==" ((==) :: A -> A -> Bool)     ]    -- count x []  =  0   -- count x (y:xs)  =  count x xs + (if x == y then 1 else 0)   conjure "count" count'-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "==" ((==) :: A -> A -> Bool)-    , prif (undefined :: Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "==" ((==) :: A -> A -> Bool)+    , iif (undefined :: Int)     ]    -- a little bit larger, guards are only allowed at the root   -- so there is a need to repeat the recursive call twice   conjure "count" count'-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "==" ((==) :: A -> A -> Bool)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "==" ((==) :: A -> A -> Bool)     , guard     ]
eg/count.txt view
@@ -25,7 +25,7 @@ -- 44 candidates of size 11 -- tested 65 candidates count x []  =  0-count x (y:xs)  =  count x xs + (if x == y then 1 else 0)+count x (y:xs)  =  (if x == y then 1 else 0) + count x xs  count :: A -> [A] -> Int -- testing 13 combinations of argument values@@ -46,6 +46,6 @@ -- tested 127 candidates count x []  =  0 count x (y:xs)-  | x == y  =  count x xs + 1+  | x == y  =  1 + count x xs   | otherwise  =  count x xs 
eg/dupos.hs view
@@ -53,32 +53,32 @@   --                       else duplicates xs                              -- 17   -- within reach performance wise.   conjure "duplicates" duplicates'-    [ pr ([] :: [Int])-    , prim "not" not-    , prim "&&" (&&)-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "elem" (elem :: Int -> [Int] -> Bool)+    [ con ([] :: [Int])+    , fun "not" not+    , fun "&&" (&&)+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "elem" (elem :: Int -> [Int] -> Bool)     , guard     ]    conjureFromSpec "duplicates" duplicatesSpec-    [ pr ([] :: [Int])-    , prim "not" not-    , prim "&&" (&&)-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "elem" (elem :: Int -> [Int] -> Bool)+    [ con ([] :: [Int])+    , fun "not" not+    , fun "&&" (&&)+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "elem" (elem :: Int -> [Int] -> Bool)     , guard     ]    conjure "positionsFrom" positionsFrom'-    [ pr ([] :: [Int])-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "==" ((==) :: A -> A -> Bool)+    [ con ([] :: [Int])+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "==" ((==) :: A -> A -> Bool) ---  , prif (undefined :: [Int])+--  , iif (undefined :: [Int])     -- cheat codes:-    , prim "id" (id :: [Int] -> [Int])-    , prif (undefined :: [Int] -> [Int])+    , fun "id" (id :: [Int] -> [Int])+    , iif (undefined :: [Int] -> [Int])     ]
eg/either.hs view
@@ -47,21 +47,21 @@  main :: IO () main = do-  conjure "isLeft" isLeft' primitives-  conjure "isRight" isRight' primitives-  conjure "fromLeft" fromLeft' primitives-  conjure "fromLeft" fromRight' primitives-  conjureFromSpec "either" eitherSpec primitives-  conjure "lefts" lefts' primitives+  conjure "isLeft" isLeft' ingredients+  conjure "isRight" isRight' ingredients+  conjure "fromLeft" fromLeft' ingredients+  conjure "fromLeft" fromRight' ingredients+  conjureFromSpec "either" eitherSpec ingredients+  conjure "lefts" lefts' ingredients -primitives :: [Prim]-primitives  =-  [ prim "Left"  (Left :: A -> Either A A)-  , prim "Right" (Right :: A -> Either A A)+ingredients :: [Ingredient]+ingredients  =+  [ fun "Left"  (Left :: A -> Either A A)+  , fun "Right" (Right :: A -> Either A A) -  , pr False-  , pr True+  , con False+  , con True -  , pr ([] :: [A])-  , prim ":" ((:) :: A -> [A] -> [A])+  , con ([] :: [A])+  , fun ":" ((:) :: A -> [A] -> [A])   ]
eg/either.txt view
@@ -50,5 +50,5 @@ -- 1 candidates of size 1 -- 0 candidates of size 2 -- tested 1 candidates-cannot conjure+lefts  =  undefined  -- search exhausted 
eg/factorial.hs view
@@ -15,11 +15,11 @@ main  =  do   -- explicit recursion   conjure "factorial n" factorial-    [ pr (0::Int)-    , pr (1::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0::Int)+    , con (1::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]   -- should produce:   -- factorial 0  =  1@@ -27,13 +27,13 @@    -- using foldr and enumFromTo   conjure "factorial n" factorial-    [ pr (0::Int)-    , pr (1::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)-    , prim ".." (enumFromTo :: Int -> Int -> [Int])-    , prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+    [ con (0::Int)+    , con (1::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)+    , fun ".." (enumFromTo :: Int -> Int -> [Int])+    , fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)     ]   -- should produce:   -- factorial x  =  foldr (*) 1 [1..x]
eg/fib01.hs view
@@ -30,20 +30,26 @@    -- Found!  It takes about 12 seconds to run with maxSize=8   -- running with maxSize = 5 for faster runtime-  conjureWith args{maxSize=5, maxConstantSize=1} "fib01" fib01-    [ pr (0::Int)-    , prim "dec" (subtract 1 :: Int -> Int)-    , prim "+" ((+) :: Int -> Int -> Int)+  conjure "fib01" fib01+    [ con (0::Int)+    , fun "dec" (subtract 1 :: Int -> Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , maxSize 5+    , maxConstantSize 1     ]    -- It takes about 27 seconds to run with maxSize=12   -- running with maxSize = 9 for faster runtime-  conjureWith args{usePatterns = False, maxSize = 1, maxConstantSize=1} "fib01" fib01-    [ pr (0::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "dec" (subtract 1 :: Int -> Int)-    , prim "<=" ((<=) :: Int -> Int -> Bool)-    , prif (undefined :: Int)+  conjure "fib01" fib01+    [ con (0::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "dec" (subtract 1 :: Int -> Int)+    , fun "<=" ((<=) :: Int -> Int -> Bool)+    , iif (undefined :: Int)++    , singlePattern+    , maxSize 1+    , maxConstantSize 1     ]   -- expected function:   -- fib01 x y z  =  if z <= 0                     -- 4
eg/fib01.txt view
@@ -7,12 +7,12 @@ -- 111 candidates of size 4 -- 255 candidates of size 5 -- tested 422 candidates-cannot conjure+fib01  =  undefined  -- search exhausted  fib01 :: Int -> Int -> Int -> Int -- testing 8 combinations of argument values -- pruning with 21/41 rules -- 4 candidates of size 1 -- tested 4 candidates-cannot conjure+fib01  =  undefined  -- search exhausted 
eg/fibonacci.hs view
@@ -16,11 +16,11 @@ main :: IO () main  =  do   conjure "fibonacci n" fibonacci-    [ pr (0::Int)-    , pr (1::Int)-    , pr (2::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0::Int)+    , con (1::Int)+    , con (2::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ] -- expected function: -- fibonacci 0  =  1
eg/gcd.hs view
@@ -19,8 +19,8 @@  main :: IO () main = conjure "gcd a b" gcd'-  [ pr (0::Int)-  , prim "`mod`" (mod :: Int -> Int -> Int)+  [ con (0::Int)+  , fun "`mod`" (mod :: Int -> Int -> Int)   ]   -- desired function:   -- gcd x 0  =  x
eg/higher.hs view
@@ -37,17 +37,17 @@  main :: IO () main = do-  conjureFromSpec "$"      appSpec     primitives-  conjureFromSpec "."      composeSpec primitives-  conjureFromSpec "flip"   flipSpec    primitives-  conjureFromSpec "map"    mapSpec     primitives-  conjureFromSpec "fold"   foldSpec    primitives-  conjureFromSpec "filter" filterSpec  primitives+  conjureFromSpec "$"      appSpec     ingredients+  conjureFromSpec "."      composeSpec ingredients+  conjureFromSpec "flip"   flipSpec    ingredients+  conjureFromSpec "map"    mapSpec     ingredients+  conjureFromSpec "fold"   foldSpec    ingredients+  conjureFromSpec "filter" filterSpec  ingredients  -primitives :: [Prim]-primitives  =-  [ pr ([] :: [Int])-  , prim ":" ((:) :: Int -> [Int] -> [Int])+ingredients :: [Ingredient]+ingredients  =+  [ con ([] :: [Int])+  , fun ":" ((:) :: Int -> [Int] -> [Int])   , guard   ]
eg/id.hs view
@@ -6,7 +6,7 @@  main :: IO () main = do-  -- conjure needs no primitives+  -- conjure needs no ingredients   -- to figure out the implementation of id and const   conjure "id"    (id :: Int -> Int)           []   conjure "const" (const :: Int -> Int -> Int) []
eg/ints.hs view
@@ -26,43 +26,43 @@ main :: IO () main = do   conjure "second"  (second :: [Int] -> Int)-    [ prim "null" (null :: [Int] -> Bool)-    , prim "head" (head :: [Int] -> Int)-    , prim "tail" (tail :: [Int] -> [Int])+    [ fun "null" (null :: [Int] -> Bool)+    , fun "head" (head :: [Int] -> Int)+    , fun "tail" (tail :: [Int] -> [Int])     ]    conjure "third"   (third :: [Int] -> Int)-    [ prim "null" (null :: [Int] -> Bool)-    , prim "head" (head :: [Int] -> Int)-    , prim "tail" (tail :: [Int] -> [Int])+    [ fun "null" (null :: [Int] -> Bool)+    , fun "head" (head :: [Int] -> Int)+    , fun "tail" (tail :: [Int] -> [Int])     ]    conjure "sum"     (sum' :: [Int] -> Int)-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)     ]    conjure "product" (product' :: [Int] -> Int)-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "*" ((*) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)     ] -  conjure "sum"     (sum' :: [Int] -> Int) primitivesWithFold-  conjure "product" (product' :: [Int] -> Int) primitivesWithFold+  conjure "sum"     (sum' :: [Int] -> Int) ingredientsWithFold+  conjure "product" (product' :: [Int] -> Int) ingredientsWithFold -primitives :: [Prim]-primitives =-  [ pr (0 :: Int)-  , pr (1 :: Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)+ingredients :: [Ingredient]+ingredients =+  [ con (0 :: Int)+  , con (1 :: Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)   ] -primitivesWithFold :: [Prim]-primitivesWithFold  =-    prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)-  : primitives+ingredientsWithFold :: [Ingredient]+ingredientsWithFold  =+    fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+  : ingredients
eg/list.hs view
@@ -56,62 +56,63 @@ main :: IO () main = do   conjure "length" length'-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)     ]    conjure "reverse" reverse'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]    conjure "++" (+++)-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])     ]    conjure "++" (+++)-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])     ]    conjure "last" last'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "null" (null :: [Int] -> Bool)+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "null" (null :: [Int] -> Bool)     , guard-    , prim "undefined" (undefined :: Int)+    , fun "undefined" (undefined :: Int)     ] -  conjureWith args{maxPatternDepth=2} "last" last'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "undefined" (undefined :: Int)+  conjure "last" last'+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "undefined" (undefined :: Int)+    , maxPatternDepth 2     ]    conjure "zip" (zip')-    [ pr ([] :: [(Int,Int)])-    , prim ":" ((:) :: (Int,Int) -> [(Int,Int)] -> [(Int,Int)])-    , prim "," ((,) :: Int -> Int -> (Int,Int))+    [ con ([] :: [(Int,Int)])+    , fun ":" ((:) :: (Int,Int) -> [(Int,Int)] -> [(Int,Int)])+    , fun "," ((,) :: Int -> Int -> (Int,Int))     ]    conjure "\\/" (\/)-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])     ]    conjure "ordered" ordered'-    [ pr False-    , pr True-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "<=" ((<=) :: Int -> Int -> Bool)-    , prim "null" (null :: [Int] -> Bool)-    , prim "head" (head :: [Int] -> Int)-    , prim "tail" (tail :: [Int] -> [Int])+    [ con False+    , con True+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "<=" ((<=) :: Int -> Int -> Bool)+    , fun "null" (null :: [Int] -> Bool)+    , fun "head" (head :: [Int] -> Int)+    , fun "tail" (tail :: [Int] -> [Int])     ]    -- for elem, please see eg/setelem.hs
eg/list.txt view
@@ -8,7 +8,7 @@ -- 2 candidates of size 5 -- tested 4 candidates length []  =  0-length (x:xs)  =  length xs + 1+length (x:xs)  =  1 + length xs  reverse :: [Int] -> [Int] -- testing 360 combinations of argument values@@ -123,5 +123,5 @@ -- 115 candidates of size 11 -- tested 172 candidates ordered []  =  True-ordered (x:xs)  =  ordered xs && (null xs || x <= head xs)+ordered (x:xs)  =  (null xs || x <= head xs) && ordered xs 
eg/maybe.hs view
@@ -48,37 +48,37 @@  main :: IO () main = do-  conjure "isNothing"     isNothing'   primitives-  conjure "isJust"        isJust'      primitives-  conjure "fromMaybe"     fromMaybe'   primitives-  conjureFromSpec "maybe" maybeSpec    primitives-  conjure "listToMaybe"   listToMaybe' primitives-  conjure "maybeToList"   maybeToList' primitives+  conjure "isNothing"     isNothing'   ingredients+  conjure "isJust"        isJust'      ingredients+  conjure "fromMaybe"     fromMaybe'   ingredients+  conjureFromSpec "maybe" maybeSpec    ingredients+  conjure "listToMaybe"   listToMaybe' ingredients+  conjure "maybeToList"   maybeToList' ingredients -  -- only top-level break downs, so would need morePrimitives-  conjureWith args{maxPatternDepth=2} "catMaybes"     catMaybes'   primitives-  -- conjure "mapMaybe" mapMaybe' primitives  -- same+  -- only top-level break downs, so would need moreIngredients+  conjure "catMaybes"     catMaybes'   (maxPatternDepth 2 : ingredients)+  -- conjure "mapMaybe" mapMaybe' ingredients  -- same -primitives :: [Prim]-primitives  =-  [ pr (Nothing :: Maybe A)-  , prim "Just" (Just :: A -> Maybe A)+ingredients :: [Ingredient]+ingredients  =+  [ con (Nothing :: Maybe A)+  , fun "Just" (Just :: A -> Maybe A) -  , pr False-  , pr True+  , con False+  , con True -  , pr ([] :: [A])-  , prim ":" ((:) :: A -> [A] -> [A])+  , con ([] :: [A])+  , fun ":" ((:) :: A -> [A] -> [A])   ]  {--morePrimitives :: [Prim]-morePrimitives  =  primitives ++-  [ prim "isNothing" (isNothing :: Maybe A -> Bool)-  , prim "isJust"    (isJust    :: Maybe A -> Bool)-  , prim "fromJust"  (fromJust :: Maybe A -> A)-  , prif (undefined :: A)-  , prif (undefined :: Maybe A)-  , prif (undefined :: [A])+moreIngredients :: [Ingredient]+moreIngredients  =  ingredients +++  [ fun "isNothing" (isNothing :: Maybe A -> Bool)+  , fun "isJust"    (isJust    :: Maybe A -> Bool)+  , fun "fromJust"  (fromJust :: Maybe A -> A)+  , iif (undefined :: A)+  , iif (undefined :: Maybe A)+  , iif (undefined :: [A])   ] -}
eg/oddeven.hs view
@@ -1,4 +1,4 @@--- oddeven.hs: conjuring even and odd from two sets of primitives+-- oddeven.hs: conjuring even and odd from two sets of ingredients -- -- Copyright (C) 2025 Rudy Matela -- Distributed under the 3-Clause BSD licence (see the file LICENSE).@@ -23,30 +23,30 @@  main :: IO () main = do-  conjure "odd"  odd  primitives1-  conjure "even" even primitives1-  conjure "odd"  odd  primitives2-  conjure "even" even primitives2+  conjure "odd"  odd  ingredients1+  conjure "even" even ingredients1+  conjure "odd"  odd  ingredients2+  conjure "even" even ingredients2 -primitives1 :: [Prim]-primitives1 =-  [ pr (0::Int)-  , pr (1::Int)-  , pr (2::Int)-  , prim "+" ((+) :: Int -> Int -> Int)+ingredients1 :: [Ingredient]+ingredients1 =+  [ con (0::Int)+  , con (1::Int)+  , con (2::Int)+  , fun "+" ((+) :: Int -> Int -> Int) -  , prim "-" ((-) :: Int -> Int -> Int)-  , pr False-  , pr True+  , fun "-" ((-) :: Int -> Int -> Int)+  , con False+  , con True   ] -primitives2 :: [Prim]-primitives2 =-  [ pr (0::Int)-  , pr (1::Int)-  , pr (2::Int)-  , prim "+" ((+) :: Int -> Int -> Int)+ingredients2 :: [Ingredient]+ingredients2 =+  [ con (0::Int)+  , con (1::Int)+  , con (2::Int)+  , fun "+" ((+) :: Int -> Int -> Int) -  , prim "`mod`" (mod :: Int -> Int -> Int)-  , prim "==" ((==) :: Int -> Int -> Bool)+  , fun "`mod`" (mod :: Int -> Int -> Int)+  , fun "==" ((==) :: Int -> Int -> Bool)   ]
eg/peano.hs view
@@ -27,16 +27,16 @@ main :: IO () main  =  do   conjure "+" plus-    [ pr Z-    , prim "S" S+    [ con Z+    , fun "S" S     ]    -- use + to conjure *   conjure "*" times-    [ pr Z-    , prim "S" S-    , prim "+" (let p + Z    =  p-                    p + S q  =  S p + q+    [ con Z+    , fun "S" S+    , fun "+" (let p + Z    =  p+                   p + S q  =  S p + q                 in (+))     ] 
eg/pow.hs view
@@ -15,22 +15,23 @@ main  =  do   -- pow x 0  =  1   -- pow x y  =  x * pow x (y - 1)-  conjureWithMaxSize 8 "pow" pow-    [ pr (0::Int)-    , pr (1::Int)-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+  conjure "pow" pow+    [ con (0::Int)+    , con (1::Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]    -- pow b 0  =  1   -- pow b e  =  pow b (halve e) * pow b (halve e) * if odd e then b else 1   --             2   3  4     5  6 7   8  9    10 11 12 13 14     15     16   -- out of reach performance wise, OOM at size 9-  conjureWithMaxSize 6 "pow" pow-    [ pr (0::Int)-    , pr (1::Int)---  , prim "sq" ((\x -> x*x) :: Int -> Int) -- cheat! OOM still-    , prim "*" ((*) :: Int -> Int -> Int)-    , prim "halve" ((`div` 2) :: Int -> Int)-    , prif (undefined :: Int)+  conjure "pow" pow+    [ con (0::Int)+    , con (1::Int)+--  , fun "sq" ((\x -> x*x) :: Int -> Int) -- cheat! OOM still+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "halve" ((`div` 2) :: Int -> Int)+    , iif (undefined :: Int)+    , maxSize 6 -- OOM at size 9     ]
eg/pow.txt view
@@ -23,5 +23,5 @@ -- 259 candidates of size 5 -- 750 candidates of size 6 -- tested 1169 candidates-cannot conjure+pow  =  undefined  -- search exhausted 
eg/replicate.hs view
@@ -26,33 +26,33 @@ main :: IO () main = do   conjure "replicate" replicate'-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "-" ((-) :: Int -> Int -> Int)-    , pr ""-    , prim ":" ((:) :: Char -> String -> String)+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "-" ((-) :: Int -> Int -> Int)+    , con ""+    , fun ":" ((:) :: Char -> String -> String)     ]    -- emulates how MagicHaskeller generates "replicates"   conjure "replicates" replicates'-    [ prim "replicate" (replicate :: Int -> String -> [String])-    , prim "transpose" (transpose :: [[Char]] -> [[Char]])-    , prim "concat"    (concat :: [String] -> String)+    [ fun "replicate" (replicate :: Int -> String -> [String])+    , fun "transpose" (transpose :: [[Char]] -> [[Char]])+    , fun "concat"    (concat :: [String] -> String)     ]    -- emulates an alternative generation that works on MagicHaskeller   conjure "replicates" replicates'-    [ prim "replicate" (replicate :: Int -> Char -> String)-    , prim "map"       (map :: (Char -> String) -> String -> [String])-    , prim "concat"    (concat :: [String] -> String)+    [ fun "replicate" (replicate :: Int -> Char -> String)+    , fun "map"       (map :: (Char -> String) -> String -> [String])+    , fun "concat"    (concat :: [String] -> String)     ]    -- alternative generation using recursion   conjure "replicates" replicates'-    [ pr ""-    , prim ":" ((:) :: Char -> String -> String)-    , prim "++" ((++) :: String -> String -> String)-    , prim "replicate" (replicate :: Int -> Char -> String)+    [ con ""+    , fun ":" ((:) :: Char -> String -> String)+    , fun "++" ((++) :: String -> String -> String)+    , fun "replicate" (replicate :: Int -> Char -> String)     ]  replicates n []  =  []
eg/setelem.hs view
@@ -18,23 +18,23 @@ main :: IO () main = do   conjure "elem" (elem')-    [ pr ([] :: [Int])-    , pr True-    , pr False-    , prim "||" (||)-    , prim "&&" (&&)-    , prim "not" not-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "==" ((==) :: Int -> Int -> Bool)+    [ con ([] :: [Int])+    , con True+    , con False+    , fun "||" (||)+    , fun "&&" (&&)+    , fun "not" not+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "==" ((==) :: Int -> Int -> Bool)     ]    conjure "set" (set')-    [ pr ([] :: [Int])-    , pr True-    , pr False-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "not" not-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "elem" (elem :: Int -> [Int] -> Bool)+    [ con ([] :: [Int])+    , con True+    , con False+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "not" not+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "elem" (elem :: Int -> [Int] -> Bool)     ]
eg/setelem.txt view
@@ -11,7 +11,7 @@ -- 16 candidates of size 8 -- tested 19 candidates elem x []  =  False-elem x (y:xs)  =  elem x xs || x == y+elem x (y:xs)  =  x == y || elem x xs  set :: [Int] -> Bool -- testing 360 combinations of argument values@@ -26,5 +26,5 @@ -- 4 candidates of size 8 -- tested 6 candidates set []  =  True-set (x:xs)  =  set xs && not (elem x xs)+set (x:xs)  =  not (elem x xs) && set xs 
eg/sort.hs view
@@ -47,27 +47,28 @@   -- sort []  =  []   -- sort (x:xs)  =  insert x (sort xs)   conjure "sort" sort'-    [ pr ([] :: [Int])-    , prim "insert" (insert :: Int -> [Int] -> [Int])-    , prim "head" (head :: [Int] -> Int)-    , prim "tail" (tail :: [Int] -> [Int])-    , prim "null" (null :: [Int] -> Bool)+    [ con ([] :: [Int])+    , fun "insert" (insert :: Int -> [Int] -> [Int])+    , fun "head" (head :: [Int] -> Int)+    , fun "tail" (tail :: [Int] -> [Int])+    , fun "null" (null :: [Int] -> Bool)     ]    -- now through fold   -- sort xs  =  foldr insert [] xs   conjure "sort" sort'-    [ pr ([] :: [Int])-    , prim "insert" (insert :: Int -> [Int] -> [Int])-    , prim "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun "insert" (insert :: Int -> [Int] -> [Int])+    , fun "foldr" (foldr :: (Int -> [Int] -> [Int]) -> [Int] -> [Int] -> [Int])     ]    -- an insert function-  conjureWith args{target=50400} "insert" insert'-    [ prim "[]" ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "<=" ((<=) :: Int -> Int -> Bool)+  conjure "insert" insert'+    [ fun "[]" ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "<=" ((<=) :: Int -> Int -> Bool)     , guard+    , target 50400     ]    -- qsort []  =  []                           -- 1@@ -77,23 +78,24 @@   -- but is not generated because of the deconstruction restriction.   -- The following does generate a correct but inneficient version of qsort.   conjure "qsort" sort'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])-    , prim "<=" ((<=) :: Int -> Int -> Bool)-    , prim ">"  ((>)  :: Int -> Int -> Bool)-    , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])+    , fun "<=" ((<=) :: Int -> Int -> Bool)+    , fun ">"  ((>)  :: Int -> Int -> Bool)+    , fun "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])     ]    -- if we disable the descent requirement, we get the efficient qsort   -- though with a larger search space-  conjureWith args{requireDescent=False} "qsort" sort'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])-    , prim "<=" ((<=) :: Int -> Int -> Bool)-    , prim ">"  ((>)  :: Int -> Int -> Bool)-    , prim "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+  conjure "qsort" sort'+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])+    , fun "<=" ((<=) :: Int -> Int -> Bool)+    , fun ">"  ((>)  :: Int -> Int -> Bool)+    , fun "filter" (filter :: (Int -> Bool) -> [Int] -> [Int])+    , dontRequireDescent     ]    -- found!  candidate #1703311 @ size 22@@ -103,16 +105,19 @@   --   | x <= y  =  x:merge xs (y:ys)   --   | otherwise  =  merge (y:x:xs) ys   -- set target to 2 000 000 to reach it-  conjureWith args{target=10080, maxTests=1080} "merge" merge'-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "<=" ((<=) :: Int -> Int -> Bool)+  conjure "merge" merge'+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "<=" ((<=) :: Int -> Int -> Bool)     , guard+    , maxTests 1080+    , target 10080 -- set to 2 000 000 to reach solution     ]    -- unreachable: needs about 26, but can only reach 16-  conjureWith args{target=1080} "merge" merge'-    [ prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "compare" (compare :: Int -> Int -> Ordering)-    , primOrdCaseFor (undefined :: [Int])+  conjure "merge" merge'+    [ fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "compare" (compare :: Int -> Int -> Ordering)+    , ordcase (undefined :: [Int])+    , target 1080     ]
eg/sort.txt view
@@ -107,7 +107,7 @@ -- 4204 candidates of size 14 -- 5426 candidates of size 15 -- tested 12326 candidates-cannot conjure+merge  =  undefined  -- search exhausted  merge :: [Int] -> [Int] -> [Int] -- testing 360 combinations of argument values@@ -126,5 +126,5 @@ -- 588 candidates of size 12 -- 958 candidates of size 13 -- tested 1876 candidates-cannot conjure+merge  =  undefined  -- search exhausted 
eg/spec.hs view
@@ -11,12 +11,12 @@                    && square 1 == 1                    && square 2 == 4 -squarePrimitives :: [Prim]-squarePrimitives  =-  [ pr (0::Int)-  , pr (1::Int)-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)+squareIngredients :: [Ingredient]+squareIngredients  =+  [ con (0::Int)+  , con (1::Int)+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)   ]  squarePropertySpec :: (Int -> Int) -> Bool@@ -32,13 +32,13 @@              && sum [1,2]   == 3              && sum [3,4,5] == 12 -sumPrimitives :: [Prim]-sumPrimitives  =-  [ prim "null" (null :: [Int] -> Bool)-  , pr (0::Int)-  , prim "+"    ((+) :: Int -> Int -> Int)-  , prim "head" (head :: [Int] -> Int)-  , prim "tail" (tail :: [Int] -> [Int])+sumIngredients :: [Ingredient]+sumIngredients  =+  [ fun "null" (null :: [Int] -> Bool)+  , con (0::Int)+  , fun "+"    ((+) :: Int -> Int -> Int)+  , fun "head" (head :: [Int] -> Int)+  , fun "tail" (tail :: [Int] -> [Int])   ]  @@ -47,18 +47,18 @@               && [2,3]   ++ []      == [2,3]               && [4,5,6] ++ [7,8,9] == [4,5,6,7,8,9] -appPrimitives :: [Prim]-appPrimitives =-  [ prim "null" (null :: [Int] -> Bool)-  , prim ":"    ((:) :: Int -> [Int] -> [Int])-  , prim "head" (head :: [Int] -> Int)-  , prim "tail" (tail :: [Int] -> [Int])+appIngredients :: [Ingredient]+appIngredients =+  [ fun "null" (null :: [Int] -> Bool)+  , fun ":"    ((:) :: Int -> [Int] -> [Int])+  , fun "head" (head :: [Int] -> Int)+  , fun "tail" (tail :: [Int] -> [Int])   ]   main :: IO () main = do-  conjureFromSpec "square" squareSpec squarePrimitives-  conjureFromSpec "square" squarePropertySpec squarePrimitives-  conjureFromSpec "sum" sumSpec sumPrimitives-  conjureFromSpec "++"  appSpec appPrimitives+  conjureFromSpec "square" squareSpec squareIngredients+  conjureFromSpec "square" squarePropertySpec squareIngredients+  conjureFromSpec "sum" sumSpec sumIngredients+  conjureFromSpec "++"  appSpec appIngredients
eg/subset.hs view
@@ -44,16 +44,16 @@   -- subset [] ys  =  True   -- subset (x:xs) ys  =  elem x ys && subset xs ys   conjure "subset" (subset')-    [ pr ([] :: [Int])-    , pr True-    , pr False-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "elem" (elem :: Int -> [Int] -> Bool)+    [ con ([] :: [Int])+    , con True+    , con False+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "elem" (elem :: Int -> [Int] -> Bool)     ]    -- subset xs ys  =  sort xs `isSubsequenceOf` sort ys   conjure "subset" (subset')-    [ prim "sort" (sort :: [Int] -> [Int])-    , prim "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)+    [ fun "sort" (sort :: [Int] -> [Int])+    , fun "`isSubsequenceOf`" (isSubsequenceOf :: [Int] -> [Int] -> Bool)     ]
eg/subset.txt view
@@ -11,7 +11,7 @@ -- 176 candidates of size 8 -- tested 176 candidates subset [] xs  =  True-subset (x:xs) ys  =  subset xs ys && elem x ys+subset (x:xs) ys  =  elem x ys && subset xs ys  subset :: [Int] -> [Int] -> Bool -- testing 44 combinations of argument values
eg/take-drop.hs view
@@ -27,20 +27,20 @@   -- drop x []  =  []                   -- 2   -- drop x (y:xs)  =  drop (x - 1) xs  -- 7   conjure "drop" (drop' :: Int -> [A] -> [A])-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr ([] :: [A])-    , prim ":" ((:) :: A -> [A] -> [A])-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (0 :: Int)+    , con (1 :: Int)+    , con ([] :: [A])+    , fun ":" ((:) :: A -> [A] -> [A])+    , fun "-" ((-) :: Int -> Int -> Int)     ]    -- take 0 xs  =  []                     -- 1   -- take x []  =  []                     -- 2   -- take x (y:xs)  =  y:take (x - 1) xs  -- 9   conjure "take" (take' :: Int -> [A] -> [A])-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr ([] :: [A])-    , prim "-" ((-) :: Int -> Int -> Int)-    , prim ":" ((:) :: A -> [A] -> [A])+    [ con (0 :: Int)+    , con (1 :: Int)+    , con ([] :: [A])+    , fun "-" ((-) :: Int -> Int -> Int)+    , fun ":" ((:) :: A -> [A] -> [A])     ]
eg/tapps.hs view
@@ -21,45 +21,45 @@  main :: IO () main = do-  conjure "third"   third    primitives-  conjure "product" product' primitives-  conjure "product" product' primitivesWithFold+  conjure "third"   third    ingredients+  conjure "product" product' ingredients+  conjure "product" product' ingredientsWithFold -primitives :: [Prim]-primitives =-  [ pr (0 :: Int)-  , pr (1 :: Int)+ingredients :: [Ingredient]+ingredients =+  [ con (0 :: Int)+  , con (1 :: Int) #if __GLASGOW_HASKELL__ < 800-  , prim "+" ((+) :: Int -> Int -> Int)-  , prim "*" ((*) :: Int -> Int -> Int)-  , prim "null" (null :: [Int] -> Bool)-  , prim "head" (head :: [Int] -> Int)-  , prim "tail" (tail :: [Int] -> [Int])+  , fun "+" ((+) :: Int -> Int -> Int)+  , fun "*" ((*) :: Int -> Int -> Int)+  , fun "null" (null :: [Int] -> Bool)+  , fun "head" (head :: [Int] -> Int)+  , fun "tail" (tail :: [Int] -> [Int]) #else-  , prim "+" ((+) @Int)-  , prim "*" ((*) @Int)+  , fun "+" ((+) @Int)+  , fun "*" ((*) @Int) -- the following #if was added just for dramatic effect (see notes below) #if __GLASGOW_HASKELL__ < 710-  , prim "null" (null @Int)+  , fun "null" (null @Int) #else-  , prim "null" (null @[] @Int)+  , fun "null" (null @[] @Int) #endif-  , prim "head" (head @Int)-  , prim "tail" (tail @Int)+  , fun "head" (head @Int)+  , fun "tail" (tail @Int) #endif   ] -primitivesWithFold :: [Prim]+ingredientsWithFold :: [Ingredient] #if __GLASGOW_HASKELL__ < 800-primitivesWithFold  =-    prim "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)-  : primitives+ingredientsWithFold  =+    fun "foldr" (foldr :: (Int -> Int -> Int) -> Int -> [Int] -> Int)+  : ingredients #else -- the following #if was added just for dramatic effect (see notes below) #if __GLASGOW_HASKELL__ < 710-primitivesWithFold  =  prim "foldr" (foldr @Int @Int) : primitives+ingredientsWithFold  =  fun "foldr" (foldr @Int @Int) : ingredients #else-primitivesWithFold  =  prim "foldr" (foldr @[] @Int @Int) : primitives+ingredientsWithFold  =  fun "foldr" (foldr @[] @Int @Int) : ingredients #endif #endif 
eg/these.hs view
@@ -74,43 +74,46 @@ main :: IO () main  =  do   conjure "fromThese" fromThese'-    [ prim "," ((,) :: A -> B -> (A,B))+    [ fun "," ((,) :: A -> B -> (A,B))     ]    conjure "listhese" listhese'-    [ pr ([] :: [A])-    , prim ":" ((:) :: A -> [A] -> [A])+    [ con ([] :: [A])+    , fun ":" ((:) :: A -> [A] -> [A])     ]    conjure "cathis" cathis'-    [ pr ([] :: [A])-    , prim ":" ((:) :: A -> [A] -> [A])-    , prim "isThis" (isThis :: These A B -> Bool)-    , prim "fromThis" (fromThis :: These A B -> A)+    [ con ([] :: [A])+    , fun ":" ((:) :: A -> [A] -> [A])+    , fun "isThis" (isThis :: These A B -> Bool)+    , fun "fromThis" (fromThis :: These A B -> A)     , guard     ]    conjure "cathat" cathat'-    [ pr ([] :: [B])-    , prim ":" ((:) :: B -> [B] -> [B])-    , prim "isThat" (isThat :: These A B -> Bool)-    , prim "fromThat" (fromThat :: These A B -> B)+    [ con ([] :: [B])+    , fun ":" ((:) :: B -> [B] -> [B])+    , fun "isThat" (isThat :: These A B -> Bool)+    , fun "fromThat" (fromThat :: These A B -> B)     , guard     ] -  conjureWith args{maxPatternDepth = 2} "cathis" cathis'-    [ pr ([] :: [A])-    , prim ":" ((:) :: A -> [A] -> [A])+  conjure "cathis" cathis'+    [ con ([] :: [A])+    , fun ":" ((:) :: A -> [A] -> [A])+    , maxPatternDepth 2     ] -  conjureWith args{maxPatternDepth = 2} "cathat" cathat'-    [ pr ([] :: [B])-    , prim ":" ((:) :: B -> [B] -> [B])+  conjure "cathat" cathat'+    [ con ([] :: [B])+    , fun ":" ((:) :: B -> [B] -> [B])+    , maxPatternDepth 2     ] -  conjureWith args{maxPatternDepth = 2} "cathese" cathese'-    [ pr ([] :: [A])-    , prim ":" ((:) :: A -> [A] -> [A])+  conjure "cathese" cathese'+    [ con ([] :: [A])+    , fun ":" ((:) :: A -> [A] -> [A])+    , maxPatternDepth 2     ]   -- cathese []  =  []   -- cathese (Neither : ts)  =  cathese ts
eg/tree.hs view
@@ -97,72 +97,73 @@ main :: IO () main = do   conjure "leftmost" leftmost-    [ prim "undefined" (undefined :: Int)-    , prif (undefined :: Int)-    , prim "nil" nil+    [ fun "undefined" (undefined :: Int)+    , iif (undefined :: Int)+    , fun "nil" nil     ]    conjure "rightmost" rightmost-    [ prim "undefined" (undefined :: Int)-    , prif (undefined :: Int)-    , prim "nil" nil+    [ fun "undefined" (undefined :: Int)+    , iif (undefined :: Int)+    , fun "nil" nil     ]    conjure "size" size-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "nil" nil+    [ con (0 :: Int)+    , con (1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "nil" nil     ]    conjure "height" height-    [ pr (0 :: Int)-    , pr (1 :: Int)-    , pr (-1 :: Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "max" (max :: Int -> Int -> Int)-    , prim "nil" nil+    [ con (0 :: Int)+    , con (1 :: Int)+    , con (-1 :: Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "max" (max :: Int -> Int -> Int)+    , fun "nil" nil     ]    conjure "mem" mem-    [ pr False-    , prim "||" (||)-    , prim "==" ((==) :: Int -> Int -> Bool)+    [ con False+    , fun "||" (||)+    , fun "==" ((==) :: Int -> Int -> Bool)     ]    -- unreachable: needs size 22 but OOMs at 19/20 (v0.5.16)-  conjureWithMaxSize 12 "ordered" ordered-    [ pr True-    , pr False-    , prim "&&" (&&)-    , prim "||" (||)-    , prim "<" ((<) :: Int -> Int -> Bool)-    , prim "rightmost" rightmost-    , prim "leftmost" leftmost-    , prim "nil" nil+  conjure "ordered" ordered+    [ con True+    , con False+    , fun "&&" (&&)+    , fun "||" (||)+    , fun "<" ((<) :: Int -> Int -> Bool)+    , fun "rightmost" rightmost+    , fun "leftmost" leftmost+    , fun "nil" nil+    , maxSize 12     ]    conjure "ordered" ordered-    [ prim "strictlyOrdered" (strictlyOrdered :: [Int] -> Bool)-    , prim "inorder" inorder+    [ fun "strictlyOrdered" (strictlyOrdered :: [Int] -> Bool)+    , fun "inorder" inorder     ] -  conjureWithMaxSize 12 "preorder" preorder-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+  conjure "preorder" preorder+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ] -  conjureWithMaxSize 12 "inorder" inorder-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+  conjure "inorder" inorder+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ] -  conjureWithMaxSize 12 "posorder" posorder-    [ pr ([] :: [Int])-    , prim ":" ((:) :: Int -> [Int] -> [Int])-    , prim "++" ((++) :: [Int] -> [Int] -> [Int])+  conjure "posorder" posorder+    [ con ([] :: [Int])+    , fun ":" ((:) :: Int -> [Int] -> [Int])+    , fun "++" ((++) :: [Int] -> [Int] -> [Int])     ]  
eg/tree.txt view
@@ -43,7 +43,7 @@ -- 16 candidates of size 8 -- tested 32 candidates size Leaf  =  0-size (Node t1 x t2)  =  size t1 + (size t2 + 1)+size (Node t1 x t2)  =  size t1 + (1 + size t2)  height :: Tree -> Int -- testing 360 combinations of argument values@@ -77,7 +77,7 @@ -- 36 candidates of size 12 -- tested 42 candidates mem x Leaf  =  False-mem x (Node t1 y t2)  =  mem x t1 || (mem x t2 || x == y)+mem x (Node t1 y t2)  =  mem x t1 || (x == y || mem x t2)  ordered :: Tree -> Bool -- testing 360 combinations of argument values@@ -95,7 +95,7 @@ -- 418 candidates of size 11 -- 1064 candidates of size 12 -- tested 1639 candidates-cannot conjure+ordered  =  undefined  -- search exhausted  ordered :: Tree -> Bool -- testing 360 combinations of argument values
eg/tri.hs view
@@ -12,7 +12,7 @@ main :: IO () main  =  do   conjure "tri" tri-    [ pr (1::Int)-    , prim "+" ((+) :: Int -> Int -> Int)-    , prim "-" ((-) :: Int -> Int -> Int)+    [ con (1::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)     ]
eg/tuple.hs view
@@ -9,7 +9,7 @@ -- First, all functions from Data.Tuple -- Though their types have been simplified to (A, A), -- they might as well have had (A, B), (B, A), etc in types.--- This makes it to use a single background primitives list for everything.+-- This makes it to easier to use a list of ingredients for everything.  fst' :: (A,A) -> A fst' (0,1)  =  0@@ -54,15 +54,13 @@ -- now two functions that are a bit more interesting:  pairwise :: [A] -> [(A,A)]-pairwise []  =  []--- pairwise [x]  =  []-pairwise [x,y]  =  [(x,y)]--- pairwise [x,y,z]  =  [] -- TODO: why this does not work-pairwise [x,y,z,w]  =  [(x,y), (z,w)]--- pairwise [0,1,2,3]  =  [(0,1), (2,3)]--- pairwise [0,1,0,1]  =  [(0,1), (0,1)]--- pairwise [0,0,0,0,0]  =  [(0,0), (0,0)]--- pairwise [0,0,0,0,0,0]  =  [(0,0), (0,0), (0,0)]+pairwise [0,1,2,3]  =  [(0,1), (2,3)]+pairwise [0,1,0,1]  =  [(0,1), (0,1)]+pairwise [0,0,0,0,0,0]  =  [(0,0), (0,0), (0,0)]+-- alt:+-- pairwise [x,y]  =  [(x,y)]+-- pairwise [x,y,z,w]  =  [(x,y), (z,w)]+-- notice above even lists are required for the shallow-pattern solution  catpairs :: [(A,A)] -> [A] catpairs [(x,y)]  =  [x,y]@@ -73,35 +71,35 @@   -- the following 5 are pretty easy to Conjure:   conjure "fst"  fst'   []   conjure "snd"  snd'   []-  conjure "swap" swap'  primitives-  conjureFromSpec "curry"     currySpec primitives-  conjureFromSpec "uncurry" uncurrySpec primitives+  conjure "swap" swap'  ingredients+  conjureFromSpec "curry"     currySpec ingredients+  conjureFromSpec "uncurry" uncurrySpec ingredients    -- these are more interesting:-  conjure "pairwise" pairwise primitives-  conjure "catpairs" catpairs primitives+  conjure "pairwise" pairwise ingredients+  conjure "catpairs" catpairs ingredients    -- by increasing the pattern depth, we find shorter versions:-  conjureWith args{maxPatternDepth=2} "pairwise" pairwise primitives-  conjureWith args{maxPatternDepth=2} "catpairs" catpairs primitives+  conjure "pairwise" pairwise (maxPatternDepth 2:ingredients)+  conjure "catpairs" catpairs (maxPatternDepth 2:ingredients) -primitives :: [Prim]-primitives  =+ingredients :: [Ingredient]+ingredients  =   -- pairs-  [ prim "," ((,) :: A -> A -> (A,A))-  , prim "fst" (fst :: (A,A) -> A)-  , prim "snd" (snd :: (A,A) -> A)+  [ fun "," ((,) :: A -> A -> (A,A))+  , fun "fst" (fst :: (A,A) -> A)+  , fun "snd" (snd :: (A,A) -> A)    -- lists-  , prim "[]" ([] :: [A])-  , prim ":" ((:) :: A -> [A] -> [A])-  , prim "null" (null :: [A] -> Bool)-  , prim "head" (head :: [A] -> A)-  , prim "tail" (tail :: [A] -> [A])+  , fun "[]" ([] :: [A])+  , fun ":" ((:) :: A -> [A] -> [A])+  , fun "null" (null :: [A] -> Bool)+  , fun "head" (head :: [A] -> A)+  , fun "tail" (tail :: [A] -> [A])    -- lists of pairs-  , prim "[]" ([] :: [(A,A)])-  , prim ":" ((:) :: (A,A) -> [(A,A)] -> [(A,A)])+  , fun "[]" ([] :: [(A,A)])+  , fun ":" ((:) :: (A,A) -> [(A,A)] -> [(A,A)])    -- allow guards   , guard
eg/tuple.txt view
@@ -43,7 +43,7 @@ uncurry f (x,y)  =  f x y  pairwise :: [A] -> [(A,A)]--- testing 360 combinations of argument values+-- testing 3 combinations of argument values -- pruning with 10/10 rules -- 1 candidates of size 1 -- 0 candidates of size 2@@ -75,7 +75,7 @@ catpairs (xy:xys)  =  fst xy:snd xy:catpairs xys  pairwise :: [A] -> [(A,A)]--- testing 360 combinations of argument values+-- testing 3 combinations of argument values -- pruning with 10/10 rules -- 1 candidates of size 1 -- 0 candidates of size 2
mk/depend.mk view
@@ -8,10 +8,11 @@   mk/toplibs bench/candidates.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -25,10 +26,11 @@   mk/toplibs bench/carry-on.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -42,10 +44,11 @@   mk/toplibs bench/erroneous.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -59,10 +62,11 @@   mk/toplibs bench/gps2.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -76,10 +80,11 @@   mk/toplibs bench/gps.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -93,10 +98,11 @@   mk/toplibs bench/ill-hit.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -110,10 +116,11 @@   mk/toplibs bench/longshot.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -127,10 +134,11 @@   mk/toplibs bench/lowtests.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -144,10 +152,11 @@   mk/toplibs bench/p12.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -161,10 +170,11 @@   mk/toplibs bench/p30.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -178,10 +188,11 @@   mk/toplibs bench/redundants.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -195,10 +206,11 @@   mk/toplibs bench/self.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -212,10 +224,11 @@   mk/toplibs bench/strategies.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -229,10 +242,11 @@   mk/toplibs bench/terpret.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -246,10 +260,11 @@   mk/toplibs bench/unique.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -263,10 +278,11 @@   mk/toplibs bench/weird.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -280,10 +296,11 @@   mk/toplibs eg/arith.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -297,10 +314,11 @@   mk/toplibs eg/bits.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -314,10 +332,11 @@   mk/toplibs eg/bools.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -331,10 +350,11 @@   mk/toplibs eg/bst.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -348,10 +368,11 @@   mk/toplibs eg/colin/IntFuns.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -365,10 +386,11 @@   mk/toplibs eg/colin/ListFuns.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -382,10 +404,11 @@   mk/toplibs eg/count.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -399,10 +422,11 @@   mk/toplibs eg/dupos.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -416,10 +440,11 @@   mk/toplibs eg/either.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -433,10 +458,11 @@   mk/toplibs eg/factorial.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -450,10 +476,11 @@   mk/toplibs eg/fib01.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -467,10 +494,11 @@   mk/toplibs eg/fibonacci.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -484,10 +512,11 @@   mk/toplibs eg/gcd.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -501,10 +530,11 @@   mk/toplibs eg/higher.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -518,10 +548,11 @@   mk/toplibs eg/id.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -535,10 +566,11 @@   mk/toplibs eg/ints.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -552,10 +584,11 @@   mk/toplibs eg/list.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -569,10 +602,11 @@   mk/toplibs eg/maybe.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -586,10 +620,11 @@   mk/toplibs eg/oddeven.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -603,10 +638,11 @@   mk/toplibs eg/peano.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -620,10 +656,11 @@   mk/toplibs eg/pow.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -637,10 +674,11 @@   mk/toplibs eg/replicate.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -654,10 +692,11 @@   mk/toplibs eg/setelem.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -671,10 +710,11 @@   mk/toplibs eg/sort.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -688,10 +728,11 @@   mk/toplibs eg/spec.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -705,10 +746,11 @@   mk/toplibs eg/subset.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -722,10 +764,11 @@   mk/toplibs eg/take-drop.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -739,10 +782,11 @@   mk/toplibs eg/tapps.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -756,10 +800,11 @@   mk/toplibs eg/these.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -773,10 +818,11 @@   mk/toplibs eg/tree.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -790,10 +836,11 @@   mk/toplibs eg/tri.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -807,10 +854,11 @@   mk/toplibs eg/tuple.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -821,10 +869,11 @@   eg/tuple.hs mk/All.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -837,10 +886,11 @@   test/Test.hs \   test/Test/ListableExpr.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -884,9 +934,10 @@   mk/toplibs src/Conjure/Engine.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -896,12 +947,19 @@ src/Conjure/Expr.o: \   src/Conjure/Utils.hs \   src/Conjure/Expr.hs+src/Conjure/Ingredient.o: \+  src/Conjure/Utils.hs \+  src/Conjure/Ingredient.hs \+  src/Conjure/Expr.hs \+  src/Conjure/Defn.hs \+  src/Conjure/Conjurable.hs src/Conjure.o: \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -909,12 +967,6 @@   src/Conjure/Defn.hs \   src/Conjure/Conjurable.hs \   src/Conjure/Conjurable/Derive.hs-src/Conjure/Prim.o: \-  src/Conjure/Utils.hs \-  src/Conjure/Prim.hs \-  src/Conjure/Expr.hs \-  src/Conjure/Defn.hs \-  src/Conjure/Conjurable.hs src/Conjure/Reason.o: \   src/Conjure/Utils.hs \   src/Conjure/Reason.hs \@@ -925,6 +977,8 @@   src/Conjure/Expr.hs \   src/Conjure/Defn.hs \   src/Conjure/Conjurable.hs+src/Conjure/Settings.o: \+  src/Conjure/Settings.hs src/Conjure/Utils.o: \   src/Conjure/Utils.hs test/conjurable.o: \@@ -932,10 +986,11 @@   test/Test/ListableExpr.hs \   test/conjurable.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -953,10 +1008,11 @@   test/Test/ListableExpr.hs \   test/defn.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -974,10 +1030,11 @@   test/Test/ListableExpr.hs \   test/derive.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -995,10 +1052,11 @@   test/Test/ListableExpr.hs \   test/expr.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -1011,15 +1069,34 @@   test/Test/ListableExpr.hs \   test/expr.hs \   mk/toplibs+test/factorial.o: \+  test/factorial.hs \+  src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \+  src/Conjure/Red.hs \+  src/Conjure/Reason.hs \+  src/Conjure.hs \+  src/Conjure/Ingredient.hs \+  src/Conjure/Expr.hs \+  src/Conjure/Engine.hs \+  src/Conjure/Defn/Test.hs \+  src/Conjure/Defn/Redundancy.hs \+  src/Conjure/Defn.hs \+  src/Conjure/Conjurable.hs \+  src/Conjure/Conjurable/Derive.hs+test/factorial: \+  test/factorial.hs \+  mk/toplibs test/red.o: \   test/Test.hs \   test/Test/ListableExpr.hs \   test/red.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -1038,10 +1115,11 @@   test/Test.hs \   test/Test/ListableExpr.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \@@ -1058,10 +1136,11 @@   test/Test.hs \   test/Test/ListableExpr.hs \   src/Conjure/Utils.hs \+  src/Conjure/Settings.hs \   src/Conjure/Red.hs \   src/Conjure/Reason.hs \-  src/Conjure/Prim.hs \   src/Conjure.hs \+  src/Conjure/Ingredient.hs \   src/Conjure/Expr.hs \   src/Conjure/Engine.hs \   src/Conjure/Defn/Test.hs \
mk/haddock-i view
@@ -2,35 +2,46 @@ # # haddock-i: list haddock's -i parameters. #-# Copyright (c) 2015-2024 Rudy Matela.+# Copyright (c) 2015-2025 Rudy Matela. # Distributed under the 3-Clause BSD licence. #-# $ haddock-i <package1> <package2> ... <packageN>+# $ haddock-i # # will print -i parameters necessary for haddock to link to Haddock # documentation installed on your system, so you can: #-# $ haddock-i base template-haskell | xargs haddock <files>-err() {-	echo "$@" > /dev/stderr-}+# $ haddock-i | xargs haddock <files> -errxit() {-	err "$@"-	exit 1+# This is a grep/sed/bash hack.+# It works for all my packages,+# but it isn't foolproof,+# use with care.+list-deps() {+	cat *.cabal |+	sed -e 's/  */\n/g' |+	grep -A 999 build-depends: |+	tail -n +2 |+	grep -v '^$' |+	while read tok+	do+		echo $tok | grep -q :$ && break+		# TODO: make this slightly more efficient+		echo $tok | grep -q '^[a-zA-Z-]*$' || continue+		[ "$tok" == "if" ] && continue+		echo "$tok"+	done } -iface-for() {-	ghc-pkg field $1 haddock-interfaces | sort -rV | head -1 | sed "s/.*: //"+find-find-args() {+	echo '-name this-should-not-match-anything.haddock'+	list-deps |+	sed -e 's/^/-o -name /;s/$/.haddock/' } -html-for() {-	ghc-pkg field $1 haddock-html       | sort -rV | head -1 | sed "s/.*: //"-}+realghc=$(basename $(readlink -f /usr/bin/ghc)) -for pkg in "$@"-do-	iface=$(iface-for $pkg)-	html=$(html-for $pkg)-	[ -d "$html" -a -f "$iface" ] && echo "-i$html,$iface" || err "haddock-i: warning: could not find interface file for $pkg"-done+find \+	/usr/share/doc/ghc/html/libraries \+	~/.cabal/store/$realghc \+	$(find-find-args) |+sed -e 's/^/-i /'
mk/haskell.mk view
@@ -117,7 +117,7 @@ 	@echo "(on Arch Linux, use: cabal haddock --for-hackage --haddock-options=--optghc=-dynamic)"  doc/index.html: $(LIB_HSS)-	./mk/haddock-i $(LIB_DEPS) | xargs \+	./mk/haddock-i | xargs \ 	$(HADDOCK) --html -odoc $(LIB_HSS) \ 	  --title=$(PKGNAME) \ 	  $(shell $(HADDOCK_HAS) --package-name          && echo "--package-name=$(PKGNAME)" ) \
src/Conjure.hs view
@@ -17,18 +17,18 @@ -- -- Step 2: declare a list with the potential building blocks: ----- > primitives :: [Prim]--- > primitives =--- >   [ pr (0::Int)--- >   , pr (1::Int)--- >   , prim "+" ((+) :: Int -> Int -> Int)--- >   , prim "*" ((*) :: Int -> Int -> Int)--- >   , prim "-" ((-) :: Int -> Int -> Int)+-- > ingredients :: [Ingredient]+-- > ingredients =+-- >   [ con (0::Int)+-- >   , con (1::Int)+-- >   , fun "+" ((+) :: Int -> Int -> Int)+-- >   , fun "*" ((*) :: Int -> Int -> Int)+-- >   , fun "-" ((-) :: Int -> Int -> Int) -- >   ] -- -- Step 3: call 'conjure' and see your generated function: ----- > > conjure "factorial" factorial primitives+-- > > conjure "factorial" factorial ingredients -- > factorial :: Int -> Int -- > -- 0.1s, testing 4 combinations of argument values -- > -- 0.8s, pruning with 27/65 rules@@ -62,11 +62,11 @@ -- > take' 3 [x,y]  =  [x,y] -- -- > > conjure "take" (take' :: Int -> [A] -> [A])--- > >   [ pr (0 :: Int)--- > >   , pr (1 :: Int)--- > >   , pr ([] :: [A])--- > >   , prim ":" ((:) :: A -> [A] -> [A])--- > >   , prim "-" ((-) :: Int -> Int -> Int)+-- > >   [ con (0 :: Int)+-- > >   , con (1 :: Int)+-- > >   , con ([] :: [A])+-- > >   , fun ":" ((:) :: A -> [A] -> [A])+-- > >   , fun "-" ((-) :: Int -> Int -> Int) -- > >   ] -- > take :: Int -> [A] -> [A] -- > -- testing 153 combinations of argument values@@ -80,9 +80,9 @@ -- > take x (y:xs)  =  y:take (x - 1) xs -- -- The above example also takes less than a second to run in a modern laptop.--- The selection of functions in the list of primitives was minimized+-- The selection of functions in the list of ingredients was minimized -- to what was absolutely needed here.--- With a larger collection as primitives YMMV.+-- With a larger collection as ingredients YMMV. -- -- Conjure works for user-defined algebraic data types too, -- given that they are made instances of the 'Conjurable' typeclass.@@ -94,22 +94,20 @@   ( -- * Basic use     conjure-  , Prim-  , pr-  , prim+  , Ingredient+  , con+  , fun   , guard-  , prif-  , primOrdCaseFor+  , iif+  , ordcase --- * Advanced use-  , conjureWithMaxSize-  , conjureWith-  , Args(..)-  , args+-- * Basic configuration parameters+  , maxTests+  , target+  , maxSize  -- * Conjuring from a specification   , conjureFromSpec-  , conjureFromSpecWith  -- * When using custom types   , Conjurable (conjureExpress, conjureEquality, conjureTiers, conjureCases, conjureSubTypes, conjureSize)@@ -129,14 +127,46 @@ -- * Pure interfaces   , Results (..)   , conjpure-  , conjpureWith  -- * Helper test types   , A, B, C, D, E, F++-- * Advanced options+  , maxRecursions+  , maxEquationSize+  , maxSearchTests+  , maxDeconstructionSize+  , maxConstantSize+  , maxPatternSize+  , maxPatternDepth++-- * Debug options+  , showCandidates+  , showTheory+  , singlePattern+  , showTests+  , showPatterns+  , showDeconstructions+  , carryOn++-- * Advanced pruning options+  , dontRewrite+  , dontRequireDescent+  , omitAssortedPruning+  , omitEarlyTests+  , dontCopyBindings+  , nonAtomicNumbers+  , uniqueCandidates++-- * Deprecated functions+  , Prim+  , pr+  , prim   ) where  import Conjure.Engine import Conjure.Conjurable-import Conjure.Prim+import Conjure.Ingredient import Conjure.Conjurable.Derive+import Conjure.Settings
src/Conjure/Conjurable.hs view
@@ -269,7 +269,7 @@ -- | Computes a list of holes encoded as 'Expr's --   from a 'Conjurable' functional value. ----- (cf. 'Conjure.Prim.cjHoles')+-- (cf. 'Conjure.Ingredient.cjHoles') conjureHoles :: Conjurable f => f -> [Expr] conjureHoles f  =  [eh | (eh,_,Just _,_,_,_) <- conjureReification f] 
src/Conjure/Engine.hs view
@@ -11,27 +11,48 @@ {-# LANGUAGE CPP, RecordWildCards, TupleSections #-} module Conjure.Engine   ( conjure-  , conjureWithMaxSize-  , Args(..)-  , args-  , conjureWith   , conjureFromSpec-  , conjureFromSpecWith   , conjure0-  , conjure0With   , Results(..)   , conjpure-  , conjpureWith   , conjpureFromSpec-  , conjpureFromSpecWith   , conjpure0-  , conjpure0With   , candidateExprs   , candidateDefns-  , candidateDefns1-  , candidateDefnsC-  , conjureTheory-  , conjureTheoryWith++  -- * settings+  , maxTests+  , maxSize+  , target++  -- * Advanced settings+  , maxRecursions+  , maxEquationSize+  , maxSearchTests+  , maxDeconstructionSize+  , maxConstantSize+  , maxPatternSize+  , maxPatternDepth++  -- * Debug options+  , showCandidates+  , showTheory+  , singlePattern+  , showTests+  , showPatterns+  , showDeconstructions+  , carryOn++  -- * Pruning options+  , dontRewrite+  , dontRequireDescent+  , omitAssortedPruning+  , omitEarlyTests+  , dontCopyBindings+  , nonAtomicNumbers+  , uniqueCandidates++  -- * other modules   , module Data.Express   , module Data.Express.Fixtures   , module Conjure.Reason@@ -49,12 +70,13 @@  import Conjure.Expr import Conjure.Conjurable-import Conjure.Prim+import Conjure.Ingredient import Conjure.Defn import Conjure.Defn.Redundancy import Conjure.Defn.Test import Conjure.Red import Conjure.Reason+import Conjure.Settings  import System.CPUTime (getCPUTime) @@ -72,18 +94,18 @@ -- > factorial 3  =  6 -- > factorial 4  =  24 -- >--- > primitives :: [Prim]--- > primitives =--- >   [ pr (0::Int)--- >   , pr (1::Int)--- >   , prim "+" ((+) :: Int -> Int -> Int)--- >   , prim "*" ((*) :: Int -> Int -> Int)--- >   , prim "-" ((-) :: Int -> Int -> Int)+-- > ingredients :: [Ingredient]+-- > ingredients  =+-- >   [ con (0::Int)+-- >   , con (1::Int)+-- >   , fun "+" ((+) :: Int -> Int -> Int)+-- >   , fun "*" ((*) :: Int -> Int -> Int)+-- >   , fun "-" ((-) :: Int -> Int -> Int) -- >   ] ----- The conjure function does the following:+-- The 'conjure' function does the following: ----- > > conjure "factorial" factorial primitives+-- > > conjure "factorial" factorial ingredients -- > factorial :: Int -> Int -- > -- 0.1s, testing 4 combinations of argument values -- > -- 0.8s, pruning with 27/65 rules@@ -94,9 +116,9 @@ -- > factorial 0  =  1 -- > factorial x  =  x * factorial (x - 1) ----- The primitives list is defined with 'pr' and 'prim'.-conjure :: Conjurable f => String -> f -> [Prim] -> IO ()-conjure  =  conjureWith args+-- The ingredients list is defined with 'con' and 'fun'.+conjure :: Conjurable f => String -> f -> [Ingredient] -> IO ()+conjure nm f  =  conjure0 nm f (const True)   -- | Conjures an implementation from a function specification.@@ -113,7 +135,7 @@ -- -- Then: ----- > > conjureFromSpec "square" squareSpec [prim "*" ((*) :: Int -> Int -> Int)]+-- > > conjureFromSpec "square" squareSpec [fun "*" ((*) :: Int -> Int -> Int)] -- > square :: Int -> Int -- > -- 0.1s, pruning with 2/6 rules -- > -- 0.1s, 1 candidates of size 1@@ -133,200 +155,92 @@ -- >   , holds n $ \x -> square x >= 0 -- >   , exists n $ \x -> square x > x -- >   ]  where  n = 60-conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> IO ()-conjureFromSpec  =  conjureFromSpecWith args+conjureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Ingredient] -> IO ()+conjureFromSpec nm p  =  conjure0 nm undefined p   -- | Synthesizes an implementation from both a partial definition and a --   function specification. -- --   This works like the functions 'conjure' and 'conjureFromSpec' combined.-conjure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Prim] -> IO ()-conjure0  =  conjure0With args----- | Like 'conjure' but allows setting the maximum size of considered expressions---   instead of the default value of 24.------ > conjureWithMaxSize 12 "function" function [...]------ This function is a candidate for going away.--- Please set maxSize in Args instead.-conjureWithMaxSize :: Conjurable f => Int -> String -> f -> [Prim] -> IO ()-conjureWithMaxSize sz  =  conjureWith args-                       {  maxSize = sz-                       ,  maxEquationSize = min sz (maxEquationSize args)-                       }----- | Arguments to be passed to 'conjureWith' or 'conjpureWith'.---   See 'args' for the defaults.-data Args = Args-  { maxTests              :: Int  -- ^ maximum number of tests to each candidate-  , maxSize               :: Int  -- ^ maximum size of candidate bodies-  , target                :: Int  -- ^ enumerate further sizes of candidates until this target-  , maxEvalRecursions     :: Int  -- ^ maximum number of recursive evaluations when testing candidates-  , maxEquationSize       :: Int  -- ^ maximum size of equation operands-  , maxSearchTests        :: Int  -- ^ maximum number of tests to search for defined values-  , maxDeconstructionSize :: Int  -- ^ maximum size of deconstructions (e.g.: @_ - 1@)-  , maxConstantSize       :: Int  -- ^ maximum size of constants (0 for no limit)-  , maxPatternSize        :: Int  -- ^ maximum size of patterns (0 for no limit)-  , maxPatternDepth       :: Int  -- ^ maximum depth of patterns--  -- advanced & debug options ---  , carryOn               :: Bool -- ^ whether to carry on after finding a suitable candidate-  , showTheory            :: Bool -- ^ show theory discovered by Speculate used in pruning-  , usePatterns           :: Bool -- ^ use pattern matching to create (recursive) candidates-  , showRuntime           :: Bool -- ^ show runtime-  , showCandidates        :: Bool -- ^ (debug) show candidates -- warning: wall of text-  , showTests             :: Bool -- ^ (debug) show tests-  , showPatterns          :: Bool -- ^ (debug) show possible LHS patterns-  , showDeconstructions   :: Bool -- ^ (debug) show conjectured-and-allowed deconstructions--  -- pruning options ---  , rewriting             :: Bool -- ^ unique-modulo-rewriting candidates-  , requireDescent        :: Bool -- ^ require recursive calls to deconstruct arguments-  , adHocRedundancy       :: Bool -- ^ ad-hoc redundancy checks-  , copyBindings          :: Bool -- ^ copy partial definition bindings in candidates-  , earlyTests            :: Bool -- ^ perform tests early-and-independently on each binding-  , atomicNumbers         :: Bool -- ^ restrict constant/ground numeric expressions to atoms-  , requireZero           :: Bool -- ^ require 0 as base case for Num recursions-  , uniqueCandidates      :: Bool -- ^ unique-modulo-testing candidates-  }----- | Default arguments to conjure.------ * 60 tests--- * functions of up to 24 symbols--- * target testing over 50400 candidates--- * maximum of one recursive call allowed in candidate bodies--- * maximum evaluation of up to 60 recursions--- * pruning with equations up to size 5--- * search for defined applications for up to 100000 combinations--- * require recursive calls to deconstruct arguments--- * don't show the theory used in pruning--- * do not show tested candidates--- * do not make candidates unique module testing-args :: Args-args = Args-  { maxTests               =  360-  , maxSize                =  24-  , target                 =  10080-  , maxEvalRecursions      =  60-  , maxEquationSize        =   5-  , maxSearchTests         =  110880-  , maxDeconstructionSize  =   4-  , maxConstantSize        =   0 -- unlimited-  , maxPatternSize         =   0 -- unlimited-  , maxPatternDepth        =   1--  -- advanced & debug options ---  , carryOn                =  False-  , showTheory             =  False-  , usePatterns            =  True-  , showRuntime            =  True-  , showCandidates         =  False-  , showTests              =  False-  , showDeconstructions    =  False-  , showPatterns           =  False--  -- pruning options ---  , rewriting              =  True-  , requireDescent         =  True-  , adHocRedundancy        =  True-  , copyBindings           =  True-  , earlyTests             =  True-  , atomicNumbers          =  True-  , requireZero            =  False-  , uniqueCandidates       =  False-  }---- TODO: remove the requireZero option from args?----- | Like 'conjure' but allows setting options through 'Args'/'args'.------ > conjureWith args{maxSize = 18} "function" function [...]-conjureWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO ()-conjureWith args nm f  =  conjure0With args nm f (const True)---- | Like 'conjureFromSpec' but allows setting options through 'Args'/'args'.------ > conjureFromSpecWith args{maxSize = 18} "function" spec [...]-conjureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> IO ()-conjureFromSpecWith args nm p  =  conjure0With args nm undefined p---- | Like 'conjure0' but allows setting options through 'Args'/'args'.-conjure0With :: Conjurable f => Args -> String -> f -> (f -> Bool) -> [Prim] -> IO ()-conjure0With args nm f p es  =  do+conjure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Ingredient] -> IO ()+conjure0 nm f p es  =  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-  t0 <- if showRuntime args-        then getCPUTime-        else return (-1)+  t0 <- getCPUTime   print (var (head $ words nm) f)   when (length ts > 0) $ do     putWithTimeSince t0 $ "testing " ++ show (length ts) ++ " combinations of argument values"-    when (showTests args) $ do+    when showTests $ do       putStrLn $ "{-"       putStr $ showDefn ts       putStrLn $ "-}"-  putWithTimeSince t0 $ "pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"-  when (showTheory args) $ do-    putStrLn $ "{-"-    printThy thy-    putStrLn $ "-}"-  when (not . null $ invalid thy) $ do-    putStrLn $ "-- reasoning produced "-            ++ show (length (invalid thy)) ++ " incorrect properties,"-            ++ " please re-run with more tests for faster results"-    when (showTheory args) $ do+  if length ts == 0 && errorToFalse (p undefined)+  then putStrLn $ nm ++ "  =  error \"could not reify specification, suggestion: conjureFromSpec\"\n"+  else do+    putWithTimeSince t0 $ "pruning with " ++ show nRules ++ "/" ++ show nREs ++ " rules"+    when showTheory $ do       putStrLn $ "{-"-      putStrLn $ "invalid:"-      putStr   $ unlines $ map showEq $ invalid thy+      printThy thy       putStrLn $ "-}"-  when (showPatterns args) $ do-    putStr $ unlines-           $ zipWith (\i -> (("-- allowed patterns of size " ++ show i ++ "\n{-\n") ++) . (++ "-}") . unlines) [1..]-           $ mapT showDefn-           $ patternss results-  when (showDeconstructions args) $ do-    putStrLn $ "{- List of allowed deconstructions:"-    putStr   $ unlines $ map show $ deconstructions results-    putStrLn $ "-}"-  pr t0 1 0 rs+    when (not . null $ invalid thy) $ do+      putStrLn $ "-- reasoning produced "+              ++ show (length (invalid thy)) ++ " incorrect properties,"+              ++ " please re-run with more tests for faster results"+      when showTheory $ do+        putStrLn $ "{-"+        putStrLn $ "invalid:"+        putStr   $ unlines $ map showEq $ invalid thy+        putStrLn $ "-}"+    when showPatterns $ do+      putStr $ unlines+             $ zipWith (\i -> (("-- allowed patterns of size " ++ show i ++ "\n{-\n") ++) . (++ "-}") . unlines) [1..]+             $ mapT showDefn+             $ patternss results+    when showDeconstructions $ do+      putStrLn $ "{- List of allowed deconstructions:"+      putStr   $ unlines $ map show $ deconstructions results+      putStrLn $ "-}"+    pr t0 1 0 rs   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 $ "cannot conjure\n"+                      putStrLn $ nm ++ "  =  undefined  -- search exhausted\n"   pr t0 n t ((is,cs):rs)  =  do     let nc  =  length cs     putWithTimeSince t0 $ show nc ++ " candidates of size " ++ show n-    when (showCandidates args) $+    when showCandidates $       putStr $ unlines $ ["{-"] ++ map showDefn cs ++ ["-}"]     case is of       []     ->  pr t0 (n+1) (t+nc) rs       (_:_)  ->  do pr1 t is cs-                    when (carryOn args) $ pr t0 (n+1) (t+nc) rs+                    when carryOn $ pr t0 (n+1) (t+nc) rs     where     pr1 t [] cs  =  return ()     pr1 t (i:is) cs  =  do       let (cs',cs'') = break (i==) cs       let t' = t + length cs' + 1       putWithTimeSince t0 $ "tested " ++ show t' ++ " candidates"-      putStrLn $ showDefn i-      when (carryOn args) $ pr1 t' is (drop 1 cs'')+      putStrLn $ showDefn $ normalizeDefn thy i+      when carryOn $ pr1 t' is (drop 1 cs'')   rs  =  zip iss css-  results  =  conjpure0With args nm f p es+  results  =  conjpure0 nm f p es   iss  =  implementationss results   css  =  candidatess results   ts   =  bindings results   thy  =  theory results   nRules  =  length (rules thy)   nREs  =  length (equations thy) + nRules+  -- 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   -- | Results to the 'conjpure' family of functions.@@ -346,33 +260,19 @@ -- -- The most important part of the result are the tiers of implementations -- however results also include candidates, tests and the underlying theory.-conjpure :: Conjurable f => String -> f -> [Prim] -> Results-conjpure =  conjpureWith args+conjpure :: Conjurable f => String -> f -> [Ingredient] -> Results+conjpure nm f  =  conjpure0 nm f (const True)  -- | Like 'conjureFromSpec' but in the pure world.  (cf. 'conjpure')-conjpureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Prim] -> Results-conjpureFromSpec  =  conjpureFromSpecWith args---- | Like 'conjure0' but in the pure world.  (cf. 'conjpure')-conjpure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Prim] -> Results-conjpure0 =  conjpure0With args---- | Like 'conjpure' but allows setting options through 'Args' and 'args'.-conjpureWith :: Conjurable f => Args -> String -> f -> [Prim] -> Results-conjpureWith args nm f  =  conjpure0With args nm f (const True)---- | Like 'conjureFromSpecWith' but in the pure world.  (cf. 'conjpure')-conjpureFromSpecWith :: Conjurable f => Args -> String -> (f -> Bool) -> [Prim] -> Results-conjpureFromSpecWith args nm p  =  conjpure0With args nm undefined p+conjpureFromSpec :: Conjurable f => String -> (f -> Bool) -> [Ingredient] -> Results+conjpureFromSpec nm p  =  conjpure0 nm undefined p --- | Like 'conjpure0' but allows setting options through 'Args' and 'args'.------ This is where the actual implementation resides.  The functions--- 'conjpure', 'conjpureWith', 'conjpureFromSpec', 'conjpureFromSpecWith',--- 'conjure', 'conjureWith', 'conjureFromSpec', 'conjureFromSpecWith' and--- 'conjure0' all refer to this.-conjpure0With :: Conjurable f => Args -> String -> f -> (f -> Bool) -> [Prim] -> Results-conjpure0With args@(Args{..}) nm f p es  =  Results+-- | This is where the actual implementation resides.+-- The functions+-- 'conjpure', 'conjpureFromSpec', 'conjure' and 'conjureFromSpec'+-- all refer to this.+conjpure0 :: Conjurable f => String -> f -> (f -> Bool) -> [Ingredient] -> Results+conjpure0 nm f p es  =  Results   { implementationss  =  implementationsT   , candidatess  =  candidatesT   , bindings  =  tests@@ -384,33 +284,22 @@   implementationsT  =  filterT implements candidatesT   implements fx  =  defnApparentlyTerminates fx                  && test fx-                 && errorToFalse (p (cevl maxEvalRecursions fx))-  candidatesT  =  (if uniqueCandidates then nubCandidates args nm f else id)+                 && errorToFalse (p (cevl maxRecursions fx))+  candidatesT  =  (if uniqueCandidates then nubCandidates maxTests maxRecursions nm f else id)                $  (if target > 0 then targetiers target else id)                $  (if maxSize > 0 then take maxSize else id)                $  candidatesTT-  (candidatesTT, thy, patternss, deconstructions)  =  candidateDefns args nm f es+  (candidatesTT, thy, patternss, deconstructions)  =  candidateDefns nm f es -  test dfn  =  all (errorToFalse . deval (conjureExpress f) maxEvalRecursions dfn False)+  test dfn  =  all (errorToFalse . deval (conjureExpress f) maxRecursions dfn False)             $  [funToVar lhs -==- rhs | (lhs, rhs) <- tests]   tests  =  conjureTestDefn maxTests maxSearchTests nm f   (-==-)  =  conjureMkEquation f----- | Just prints the underlying theory found by "Test.Speculate"---   without actually synthesizing a function.-conjureTheory :: Conjurable f => String -> f -> [Prim] -> IO ()-conjureTheory  =  conjureTheoryWith args----- | Like 'conjureTheory' but allows setting options through 'Args'/'args'.-conjureTheoryWith :: Conjurable f => Args -> String -> f -> [Prim] -> IO ()-conjureTheoryWith args nm f es  =  do-  putStrLn $ "theory with " ++ (show . length $ rules thy) ++ " rules and "-                            ++ (show . length $ equations thy) ++ " equations"-  printThy thy-  where-  Results {theory = thy}  =  conjpureWith args nm f es+  maxTests  =  maxTestsI es+  (target, maxSize)  =  targetAndMaxSizeI es+  maxRecursions  =  maxRecursionsI es+  maxSearchTests  =  maxSearchTestsI es+  uniqueCandidates  =  uniqueCandidatesI es   -- | Return apparently unique candidate definitions.@@ -420,18 +309,18 @@ -- 1. tiers of candidate definitions -- 2. an equational theory -- 3. a list of allowed deconstructions-candidateDefns :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy, [[Defn]], [Expr])-candidateDefns args  =  candidateDefns' args+candidateDefns :: Conjurable f => String -> f -> [Ingredient] -> ([[Defn]], Thy, [[Defn]], [Expr])+candidateDefns nm f is  =  candidateDefns' nm f is   where-  candidateDefns'  =  if usePatterns args-                      then candidateDefnsC-                      else candidateDefns1+  candidateDefns'  =  if singlePatternI is+                      then candidateDefns1+                      else candidateDefnsC   -- | Return apparently unique candidate definitions --   where there is a single body.-candidateDefns1 :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy, [[Defn]], [Expr])-candidateDefns1 args nm f ps  =  first4 (mapT toDefn) $ candidateExprs args nm f ps+candidateDefns1 :: Conjurable f => String -> f -> [Ingredient] -> ([[Defn]], Thy, [[Defn]], [Expr])+candidateDefns1 nm f ps  =  first4 (mapT toDefn) $ candidateExprs nm f ps   where   efxs  =  conjureVarApplication nm f   toDefn e  =  [(efxs, e)]@@ -439,14 +328,15 @@   -- | Return apparently unique candidate bodies.-candidateExprs :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Expr]], Thy, [[Defn]], [Expr])-candidateExprs Args{..} nm f ps  =+candidateExprs :: Conjurable f => String -> f -> [Ingredient] -> ([[Expr]], Thy, [[Defn]], [Expr])+candidateExprs nm f is  =   ( as \/ concatMapT (`enumerateFillings` recs) ts   , thy   , [[ [(efxs, eh)] ]]   , deconstructions   )   where+  ps  =  actual is  -- extract actual primitives   es  =  map fst ps   ts | typ efxs == boolTy  =  foldAppProducts andE [cs, rs]                            \/ foldAppProducts orE  [cs, rs]@@ -463,7 +353,7 @@   eh  =  holeAsTypeOf efxs   efxs  =  conjureVarApplication nm f   (ef:exs)  =  unfoldApp efxs-  keep | rewriting  =  isRootNormalC thy . fastMostGeneralVariation+  keep | rewrite    =  isRootNormalC thy . fastMostGeneralVariation        | otherwise  =  const True   keepR | requireDescent  =  descends isDecOf efxs         | otherwise       =  const True@@ -487,14 +377,19 @@         $  foldAppProducts ef [forN h | h <- conjureArgumentHoles f]   thy  =  doubleCheck (===)        .  theoryFromAtoms (===) maxEquationSize . (:[]) . nub-       $  cjHoles (prim nm f:ps) ++ [val False, val True] ++ es-  (===)  =  cjAreEqual (prim nm f:ps) maxTests+       $  cjHoles (fun nm f:ps) ++ [val False, val True] ++ es+  (===)  =  cjAreEqual (fun nm f:ps) maxTests+  maxTests               =  maxTestsI is+  maxEquationSize        =  maxEquationSizeI is+  maxDeconstructionSize  =  maxDeconstructionSizeI is+  requireDescent         =  requireDescentI is+  rewrite                =  rewriteI is   -- | Return apparently unique candidate definitions --   using pattern matching.-candidateDefnsC :: Conjurable f => Args -> String -> f -> [Prim] -> ([[Defn]], Thy, [[Defn]], [Expr])-candidateDefnsC Args{..} nm f ps  =+candidateDefnsC :: Conjurable f => String -> f -> [Ingredient] -> ([[Defn]], Thy, [[Defn]], [Expr])+candidateDefnsC nm f is =   ( discardT hasRedundant $ concatMapT fillingsFor fss   , thy   , mapT (map (,eh)) pats@@ -505,6 +400,7 @@        | otherwise           =                        conjurePats maxPatternDepth es nm f   fss  =  concatMapT ps2fss 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]    eh  =  holeAsTypeOf efxs@@ -577,7 +473,6 @@       -- numeric arguments additionally require 0 to be present as a case       -- for recursion       should aes ae  =  length (nub aes) > 1 && hasVar ae && (isApp ae || isUnbreakable ae)-                     && (not requireZero || not (isNumeric ae) || any isZero aes)       aes   =                  (tail . unfoldApp . rehole) pat       aess  =  transpose $ map (tail . unfoldApp . rehole) pats @@ -644,11 +539,25 @@    thy  =  doubleCheck (===)        .  theoryFromAtoms (===) maxEquationSize . (:[]) . nub-       $  cjHoles (prim nm f:ps) ++ [val False, val True] ++ es-  (===)  =  cjAreEqual (prim nm f:ps) maxTests+       $  cjHoles (fun nm f:ps) ++ [val False, val True] ++ es+  (===)  =  cjAreEqual (fun nm f:ps) maxTests   isUnbreakable  =  conjureIsUnbreakable f +  maxTests               =  maxTestsI is+  maxSearchTests         =  maxSearchTestsI is+  maxEquationSize        =  maxEquationSizeI is+  maxConstantSize        =  maxConstantSizeI is+  maxDeconstructionSize  =  maxDeconstructionSizeI is+  maxPatternDepth        =  maxPatternDepthI is+  maxPatternSize         =  maxPatternSizeI is+  requireDescent         =  requireDescentI is+  earlyTests             =  earlyTestsI is+  copyBindings           =  copyBindingsI is+  adHocRedundancy        =  assortedPruningI is -- TODO: rename+  atomicNumbers          =  atomicNumbersI is+  rewriting              =  rewriteI is + -- | Checks if the given pattern is a ground pattern. -- -- A pattern is a ground pattern when its arguments are fully defined@@ -706,9 +615,9 @@  -- equality between candidates -nubCandidates :: Conjurable f => Args -> String -> f -> [[Defn]] -> [[Defn]]-nubCandidates Args{..} nm f  =-  discardLaterT $ equalModuloTesting maxTests maxEvalRecursions nm f+nubCandidates :: Conjurable f => Int -> Int -> String -> f -> [[Defn]] -> [[Defn]]+nubCandidates maxTests maxRecursions nm f  =+  discardLaterT $ equalModuloTesting maxTests maxRecursions nm f   --- tiers utils ---@@ -751,6 +660,26 @@   | n <= 0     =  []   | otherwise  =  case xss of [] -> []                               (xs:xss) -> xs : targetiers (n - length xs) xss++normalizeDefn :: Thy -> Defn -> Defn+normalizeDefn  =  map . normalizeBndn++-- This function is quite expensive to run with bad complexity,+-- but is fine on Conjure: candidates are at most a few dozen symbols long+-- and this function just runs once.+normalizeBndn :: Thy -> Bndn -> Bndn+normalizeBndn thy (lhs, rhs)+  | ef `elem` vars rhs  =  (lhs, mapInnerFirstOuterLast commutsort rhs)+  | otherwise           =  (lhs, rhs)+  where+  ef:_  =  unfoldApp lhs+  -- recursive calls come later in this ordering+  commutsort (eo :$ ex :$ ey)+    | isCommutative thy eo  =  if (ef `elem` vars ex, ex)+                               <= (ef `elem` vars ey, ey)+                               then eo :$ ex :$ ey+                               else eo :$ ey :$ ex+  commutsort e  =  e  boolTy :: TypeRep boolTy  =  typ b_
src/Conjure/Expr.hs view
@@ -39,6 +39,7 @@   , isGuardSymbol   , isGuard   , hasGuard+  , mapInnerFirstOuterLast    , enumerateAppsFor   , enumerateFillings@@ -352,14 +353,15 @@  -- -- Expression enumeration -- -- --- | Enumerate applications between values of the given list of primitives---   and of the given expressions's type.+-- | Enumerate applications between values of+--   the given list of atomic expressions+--   and of the given resulting expressions's type. -- -- __Arguments:__ -- -- 1. an 'Expr' whose type we are interested in -- 2. a filtering function, returning 'True' for the expressions to keep--- 3. a list of primitives to be used in building expression.+-- 3. a list of atomic expressions to be used in building expression. -- -- __Result:__ a potentially infinite list of list of enumerated expressions --@@ -628,6 +630,16 @@ isStrictSubexprOf :: Expr -> Expr -> Bool isStrictSubexprOf e1 e2  =  e1 /= e2                          && e1 `isSubexprOf` e2++-- TODO: move mapInner to Express?+--       of course with a shorter name.+--+-- The long name here is intentional to prevent a future clash.  :-)+mapInnerFirstOuterLast :: (Expr -> Expr) -> Expr -> Expr+mapInnerFirstOuterLast f  =  m+  where+  m (ef :$ ex)  =  f (m ef :$ m ex)+  m e  =  f e  instance Express A where  expr  =  val instance Express B where  expr  =  val
+ src/Conjure/Ingredient.hs view
@@ -0,0 +1,275 @@+-- |+-- Module      : Conjure.Ingredient+-- Copyright   : (c) 2021-2025 Rudy Matela+-- License     : 3-Clause BSD  (see the file LICENSE)+-- Maintainer  : Rudy Matela <rudy@matela.com.br>+--+-- This module is part of "Conjure".+--+-- The 'Ingredient' type and utilities involving it.+--+-- You are probably better off importing "Conjure".+module Conjure.Ingredient+  ( Ingredient+  , con+  , fun+  , iif+  , ordcase+  , guard+  , cjHoles+  , cjTiersFor+  , cjAreEqual+  , cjMkEquation+  , Prim+  , pr+  , prim+  , prif+  , primOrdCaseFor+  )+where++import Conjure.Conjurable+import Conjure.Expr+import Test.LeanCheck.Error (errorToFalse)+import Test.LeanCheck.Utils+++-- | A single functional ingredient in conjuring.+-- Specify conjure ingredients with 'con' and 'fun':+--+-- > conjure "foo" foo [ con False+-- >                   , con True+-- >                   , con (0 :: Int)+-- >                   , con (1 :: Int)+-- >                   , ...+-- >                   , fun "&&" (&&)+-- >                   , fun "||" (||)+-- >                   , fun "+" ((+) :: Int -> Int -> Int)+-- >                   , fun "*" ((*) :: Int -> Int -> Int)+-- >                   , fun "-" ((-) :: Int -> Int -> Int)+-- >                   , ...+-- >                   ]+--+-- Ingredients may include arbitrary+-- constants ('con'),+-- constructors ('con')+-- or functions ('fun').+-- These may be built-in or user defined.+-- Use 'con' on 'Show' instances+-- and 'fun' otherwise.+--+-- This is internally+-- an arbitrary atomic 'Expr'ession+-- paired with+-- a 'Reification' of type information.+type Ingredient  =  (Expr, Reification)+++-- | Provides a constant or constructor as an ingredient to Conjure.+--   To be used on 'Show' instances.+--   (cf. 'fun')+--+-- > conjure "foo" foo [ con False+-- >                   , con True+-- >                   , con (0 :: Int)+-- >                   , con (1 :: Int)+-- >                   , ...+-- >                   ]+--+-- Argument types have to be monomorphized,+-- so use type bindings when applicable.+con :: (Conjurable a, Show a) => a -> Ingredient+con x  =  (val x, conjureType x)+++-- | Provides a functional value as an ingredient to Conjure.+--   To be used on values that are not 'Show' instances+--   such as functions.+--   (cf. 'con')+--+-- > conjure "foo" foo [ ...+-- >                   , fun "&&" (&&)+-- >                   , fun "||" (||)+-- >                   , fun "+" ((+) :: Int -> Int -> Int)+-- >                   , fun "*" ((*) :: Int -> Int -> Int)+-- >                   , fun "-" ((-) :: Int -> Int -> Int)+-- >                   , ...+-- >                   ]+--+-- Argument types have to be monomorphized,+-- so use type bindings when applicable.+fun :: Conjurable a => String -> a -> Ingredient+fun s x  =  (value s x, conjureType x)+++-- | Provides an if condition bound to the given return type+--   as a Conjure ingredient.+--+-- This should be used when one wants Conjure to consider+-- if-expressions at all:+--+-- > last' :: [Int] -> Int+-- > last' [x]  =  x+-- > last' [x,y]  =  y+-- > last' [x,y,z]  =  z+--+-- > > conjure "last" last' [ con ([] :: [Int])+-- > >                      , fun ":" ((:) :: Int -> [Int] -> [Int])+-- > >                      , fun "null" (null :: [Int] -> Bool)+-- > >                      , iif (undefined :: Int)+-- > >                      , fun "undefined" (undefined :: Int)+-- > >                      ]+-- > last :: [Int] -> Int+-- > -- 0.0s, testing 360 combinations of argument values+-- > -- 0.0s, pruning with 5/5 rules+-- > -- ...   ...   ...   ...   ...+-- > -- 0.0s, 4 candidates of size 7+-- > -- 0.0s, tested 2 candidates+-- > last []  =  undefined+-- > last (x:xs)  =  if null xs+-- >                 then x+-- >                 else last xs+iif :: Conjurable a => a -> Ingredient+iif x  =  (ifFor x, conjureType x)+++-- | Provides a guard bound to the conjured function's return type.+--+-- Guards are only alllowed at the root fo the RHS.+--+-- > last' :: [Int] -> Int+-- > last' [x]  =  x+-- > last' [x,y]  =  y+-- > last' [x,y,z]  =  z+--+-- > > conjure "last" last'+-- > >   [ con ([] :: [Int])+-- > >   , fun ":" ((:) :: Int -> [Int] -> [Int])+-- > >   , fun "null" (null :: [Int] -> Bool)+-- > >   , guard+-- > >   , fun "undefined" (undefined :: Int)+-- > >   ]+-- > last :: [Int] -> Int+-- > -- 0.0s, testing 360 combinations of argument values+-- > -- 0.0s, pruning with 5/5 rules+-- > -- 0.0s, 1 candidates of size 1+-- > -- 0.0s, 0 candidates of size 2+-- > -- 0.0s, 0 candidates of size 3+-- > -- 0.0s, 0 candidates of size 4+-- > -- 0.0s, 0 candidates of size 5+-- > -- 0.0s, 0 candidates of size 6+-- > -- 0.0s, 4 candidates of size 7+-- > -- 0.0s, tested 2 candidates+-- > last []  =  undefined+-- > last (x:xs)+-- >   | null xs  =  x+-- >   | 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+++-- | Provides a case condition bound to the given return type.+--+-- This should be used when one wants Conjure to consider ord-case expressions:+--+-- > > conjure "mem" mem+-- > >   [ con False+-- > >   , con True+-- > >   , fun "`compare`" (compare :: Int -> Int -> Ordering)+-- > >   , ordcase (undefined :: Bool)+-- > >   ]+-- > mem :: Int -> Tree -> Bool+-- > -- ...   ...   ...   ...   ...+-- > -- 0.0s, 384 candidates of size 12+-- > -- 0.0s, tested 346 candidates+-- > mem x Leaf  =  False+-- > mem x (Node t1 y t2)  =  case x `compare` y of+-- >                          LT -> mem x t1+-- >                          EQ -> True+-- >                          GT -> mem x t2+ordcase :: Conjurable a => a -> Ingredient+ordcase x  =  (caseForOrd x, conjureType x)+++-- the following functions mirror their "conjure" counterparts from+-- Conjure.Conjurable but need a list of Ingredients instead of a Conjurable+-- representative.++-- | Computes a list of 'Reification1's from a list of 'Ingredient's.+--+-- This function mirrors functionality of 'conjureReification'.+cjReification :: [Ingredient] -> [Reification1]+cjReification ps  =  nubOn (\(eh,_,_,_,_,_) -> eh)+                  $  foldr (.) id (map snd ps) [conjureReification1 bool]++-- | Computes a list of holes encoded as 'Expr's from a list of 'Ingredient's.+--+-- This function mirrors functionality from 'conjureHoles'.+cjHoles :: [Ingredient] -> [Expr]+cjHoles ps  =  [eh | (eh,_,Just _,_,_,_) <- cjReification ps]++-- | Computes a function that equates two 'Expr's from a list of 'Ingredient's.+--+-- This function mirrors functionality from 'conjureMkEquation'.+cjMkEquation :: [Ingredient] -> Expr -> Expr -> Expr+cjMkEquation ps  =  mkEquation [eq | (_,Just eq,_,_,_,_) <- cjReification ps]++-- | Given a list of 'Ingredient's,+--   computes a function that checks whether two 'Expr's are equal+--   up to a given number of tests.+cjAreEqual :: [Ingredient] -> Int -> Expr -> Expr -> Bool+cjAreEqual ps maxTests  =  (===)+  where+  (-==-)  =  cjMkEquation ps+  e1 === e2  =  isTrue $ e1 -==- e2+  isTrue  =  all (errorToFalse . eval False) . gs+  gs  =  take maxTests . cjGrounds ps++-- | Given a list of 'Ingredient's,+--   computes a grounds function that lists+--   ground expressions of an 'Expr'.+cjGrounds :: [Ingredient] -> Expr -> [Expr]+cjGrounds  =  grounds . cjTiersFor++-- | Given a list of 'Ingredient's,+--   returns a function that given an 'Expr'+--   will return tiers of test 'Expr' values.+--+-- This is used in 'cjAreEqual'.+cjTiersFor :: [Ingredient] -> Expr -> [[Expr]]+cjTiersFor ps e  =  tf allTiers+  where+  allTiers :: [ [[Expr]] ]+  allTiers  =  [etiers | (_,_,Just etiers,_,_,_) <- cjReification ps]+  tf []  =  [[e]] -- no tiers found, keep variable+  tf (etiers:etc)  =  case etiers of+                      ((e':_):_) | typ e' == typ e -> etiers+                      _                            -> tf etc+++++-- | __DEPRACATED__.  Please use 'Ingredient' instead+type Prim  =  Ingredient+{-# DEPRECATED Prim "'Prim' is deprecated, please use 'Ingredient' instead" #-}+++-- | __DEPRECATED__.  Please use 'con' instead.+pr :: (Conjurable a, Show a) => a -> Ingredient+pr  =  con+{-# DEPRECATED pr "'pr' is deprecated, please use 'con' instead" #-}++-- | __DEPRECATED__.  Please use 'fun' instead.+prim :: Conjurable a => String -> a -> Ingredient+prim  =  fun+{-# DEPRECATED prim "'prim' is deprecated, please use 'fun' instead" #-}++prif :: Conjurable a => a -> Ingredient+prif  =  iif+{-# DEPRECATED prif "'prif' is deprecated, please use 'iif' instead" #-}++primOrdCaseFor :: Conjurable a => a -> Ingredient+primOrdCaseFor  =  ordcase+{-# DEPRECATED primOrdCaseFor "'primOrdCaseFor' is deprecated, please use 'ordcase' instead" #-}
− src/Conjure/Prim.hs
@@ -1,217 +0,0 @@--- |--- Module      : Conjure.Prim--- Copyright   : (c) 2021-2025 Rudy Matela--- License     : 3-Clause BSD  (see the file LICENSE)--- Maintainer  : Rudy Matela <rudy@matela.com.br>------ This module is part of "Conjure".------ The 'Prim' type and utilities involving it.------ You are probably better off importing "Conjure".-module Conjure.Prim-  ( Prim-  , prim-  , pr-  , prif-  , primOrdCaseFor-  , guard-  , cjHoles-  , cjTiersFor-  , cjAreEqual-  , cjMkEquation-  )-where--import Conjure.Conjurable-import Conjure.Expr-import Test.LeanCheck.Error (errorToFalse)-import Test.LeanCheck.Utils----- | A primitive expression (paired with instance reification).---   Create 'Prim's with 'pr' and 'prim'.-type Prim  =  (Expr, Reification)----- | Provides a primitive value to Conjure.---   To be used on 'Show' instances.---   (cf. 'prim')------ > conjure "fun" fun [ pr False--- >                   , pr True--- >                   , pr (0 :: Int)--- >                   , pr (1 :: Int)--- >                   , ...--- >                   ]------ Argument types have to be monomorphized,--- so use type bindings when applicable.-pr :: (Conjurable a, Show a) => a -> Prim-pr x  =  (val x, conjureType x)----- | Provides a primitive value to Conjure.---   To be used on values that are not 'Show' instances---   such as functions.---   (cf. 'pr')------ > conjure "fun" fun [ ...--- >                   , prim "&&" (&&)--- >                   , prim "||" (||)--- >                   , prim "+" ((+) :: Int -> Int -> Int)--- >                   , prim "*" ((*) :: Int -> Int -> Int)--- >                   , prim "-" ((-) :: Int -> Int -> Int)--- >                   , ...--- >                   ]------ Argument types have to be monomorphized,--- so use type bindings when applicable.-prim :: Conjurable a => String -> a -> Prim-prim s x  =  (value s x, conjureType x)----- | Provides an if condition bound to the given return type.------ This should be used when one wants Conjure to consider--- if-expressions at all:------ > last' :: [Int] -> Int--- > last' [x]  =  x--- > last' [x,y]  =  y--- > last' [x,y,z]  =  z------ > > conjure "last" last' [ pr ([] :: [Int])--- > >                      , prim ":" ((:) :: Int -> [Int] -> [Int])--- > >                      , prim "null" (null :: [Int] -> Bool)--- > >                      , prif (undefined :: Int)--- > >                      , prim "undefined" (undefined :: Int)--- > >                      ]--- > last :: [Int] -> Int--- > -- 0.0s, testing 360 combinations of argument values--- > -- 0.0s, pruning with 5/5 rules--- > -- ...   ...   ...   ...   ...--- > -- 0.0s, 4 candidates of size 7--- > -- 0.0s, tested 2 candidates--- > last []  =  undefined--- > last (x:xs)  =  if null xs--- >                 then x--- >                 else last xs-prif :: Conjurable a => a -> Prim-prif x  =  (ifFor x, conjureType x)----- | Provides an if condition bound to the conjured function's return type.------ Guards are only alllowed at the root fo the RHS.------ > last' :: [Int] -> Int--- > last' [x]  =  x--- > last' [x,y]  =  y--- > last' [x,y,z]  =  z------ > > conjure "last" last'--- > >   [ pr ([] :: [Int])--- > >   , prim ":" ((:) :: Int -> [Int] -> [Int])--- > >   , prim "null" (null :: [Int] -> Bool)--- > >   , guard--- > >   , prim "undefined" (undefined :: Int)--- > >   ]--- > last :: [Int] -> Int--- > -- 0.0s, testing 360 combinations of argument values--- > -- 0.0s, pruning with 5/5 rules--- > -- 0.0s, 1 candidates of size 1--- > -- 0.0s, 0 candidates of size 2--- > -- 0.0s, 0 candidates of size 3--- > -- 0.0s, 0 candidates of size 4--- > -- 0.0s, 0 candidates of size 5--- > -- 0.0s, 0 candidates of size 6--- > -- 0.0s, 4 candidates of size 7--- > -- 0.0s, tested 2 candidates--- > last []  =  undefined--- > last (x:xs)--- >   | null xs  =  x--- >   | otherwise  =  last xs-guard :: Prim-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----- | Provides a case condition bound to the given return type.------ This should be used when one wants Conjure to consider ord-case expressions:------ > > conjure "mem" mem--- > >   [ pr False--- > >   , pr True--- > >   , prim "`compare`" (compare :: Int -> Int -> Ordering)--- > >   , primOrdCaseFor (undefined :: Bool)--- > >   ]--- > mem :: Int -> Tree -> Bool--- > -- ...   ...   ...   ...   ...--- > -- 0.0s, 384 candidates of size 12--- > -- 0.0s, tested 346 candidates--- > mem x Leaf  =  False--- > mem x (Node t1 y t2)  =  case x `compare` y of--- >                          LT -> mem x t1--- >                          EQ -> True--- >                          GT -> mem x t2-primOrdCaseFor :: Conjurable a => a -> Prim-primOrdCaseFor x  =  (caseForOrd x, conjureType x)----- the following functions mirror their "conjure" counterparts from--- Conjure.Conjurable but need a list of Prims instead of a Conjurable--- representative.---- | Computes a list of 'Reification1's from a list of 'Prim's.------ This function mirrors functionality of 'conjureReification'.-cjReification :: [Prim] -> [Reification1]-cjReification ps  =  nubOn (\(eh,_,_,_,_,_) -> eh)-                  $  foldr (.) id (map snd ps) [conjureReification1 bool]---- | Computes a list of holes encoded as 'Expr's from a list of 'Prim's.------ This function mirrors functionality from 'conjureHoles'.-cjHoles :: [Prim] -> [Expr]-cjHoles ps  =  [eh | (eh,_,Just _,_,_,_) <- cjReification ps]---- | Computes a function that equates two 'Expr's from a list of 'Prim's.------ This function mirrors functionality from 'conjureMkEquation'.-cjMkEquation :: [Prim] -> Expr -> Expr -> Expr-cjMkEquation ps  =  mkEquation [eq | (_,Just eq,_,_,_,_) <- cjReification ps]---- | Given a list of 'Prim's,---   computes a function that checks whether two 'Expr's are equal---   up to a given number of tests.-cjAreEqual :: [Prim] -> Int -> Expr -> Expr -> Bool-cjAreEqual ps maxTests  =  (===)-  where-  (-==-)  =  cjMkEquation ps-  e1 === e2  =  isTrue $ e1 -==- e2-  isTrue  =  all (errorToFalse . eval False) . gs-  gs  =  take maxTests . cjGrounds ps---- | Given a list of 'Prim's,---   computes a grounds function that lists---   ground expressions of an 'Expr'.-cjGrounds :: [Prim] -> Expr -> [Expr]-cjGrounds  =  grounds . cjTiersFor---- | Given a list of 'Prim's,---   returns a function that given an 'Expr'---   will return tiers of test 'Expr' values.------ This is used in 'cjAreEqual'.-cjTiersFor :: [Prim] -> Expr -> [[Expr]]-cjTiersFor ps e  =  tf allTiers-  where-  allTiers :: [ [[Expr]] ]-  allTiers  =  [etiers | (_,_,Just etiers,_,_,_) <- cjReification ps]-  tf []  =  [[e]] -- no tiers found, keep variable-  tf (etiers:etc)  =  case etiers of-                      ((e':_):_) | typ e' == typ e -> etiers-                      _                            -> tf etc
+ src/Conjure/Settings.hs view
@@ -0,0 +1,424 @@+-- |+-- Module      : Conjure.Settings+-- Copyright   : (c) 2021-2025 Rudy Matela+-- License     : 3-Clause BSD  (see the file LICENSE)+-- Maintainer  : Rudy Matela <rudy@matela.com.br>+--+-- An internal module of "Conjure",+-- a library for Conjuring function implementations+-- from tests or partial definitions.+-- (a.k.a.: functional inductive programming)+--+-- This contains the settings for functions in "Conjure.Engine".+{-# LANGUAGE CPP, RecordWildCards, TupleSections #-}+module Conjure.Settings+  (+  -- * Basic settings+    maxTests+  , maxSize+  , target++  -- * Advanced settings+  , maxRecursions+  , maxEquationSize+  , maxSearchTests+  , maxDeconstructionSize+  , maxConstantSize+  , maxPatternSize+  , maxPatternDepth++  -- * Debug options+  , showCandidates+  , showTheory+  , singlePattern+  , showTests+  , showPatterns+  , showDeconstructions+  , carryOn++  -- * Pruning options+  , dontRewrite+  , dontRequireDescent+  , omitAssortedPruning+  , omitEarlyTests+  , dontCopyBindings+  , nonAtomicNumbers+  , uniqueCandidates++  -- * Filtering settings+  , actual++  -- * Read basic settings+  , maxTestsI+  , targetAndMaxSizeI++  -- * Read advanced settings+  , maxRecursionsI+  , maxEquationSizeI+  , maxSearchTestsI+  , maxDeconstructionSizeI+  , maxConstantSizeI+  , maxPatternSizeI+  , maxPatternDepthI++  -- * Read debug options+  , showCandidatesI+  , showTheoryI+  , singlePatternI+  , showTestsI+  , showPatternsI+  , showDeconstructionsI+  , carryOnI++  -- * Read pruning options+  , rewriteI+  , requireDescentI+  , assortedPruningI+  , earlyTestsI+  , copyBindingsI+  , atomicNumbersI+  , uniqueCandidatesI+  )+where+++import Conjure.Utils+import Data.Express (val, eval, typ)+import Conjure.Ingredient (Ingredient)+++-- | Arguments to be passed to+--   'Conjure.conjureWith' or 'Conjure.conjpureWith'.+--   You should use smart constructors instead.+data Setting+  = Noop                       -- ^ internal use: no-op setting++  | MaxTests              Int  -- ^ maximum number of tests to each candidate+  | MaxSize               Int  -- ^ maximum size of candidate bodies+  | Target                Int  -- ^ enumerate further sizes of candidates until this target+  | MaxRecursions         Int  -- ^ maximum number of recursive evaluations when testing candidates+  | MaxEquationSize       Int  -- ^ maximum size of equation operands+  | MaxSearchTests        Int  -- ^ maximum number of tests to search for defined values+  | MaxDeconstructionSize Int  -- ^ maximum size of deconstructions (e.g.: @- 1@)+  | MaxConstantSize       Int  -- ^ maximum size of constants (0 for no limit)+  | MaxPatternSize        Int  -- ^ maximum size of patterns (0 for no limit)+  | MaxPatternDepth       Int  -- ^ maximum depth of patterns++  -- advanced & debug options --+  | CarryOn              -- ^ carry on after finding a suitable candidate+  | ShowTheory           -- ^ show theory discovered by Speculate used in pruning+  | SinglePattern        -- ^ restrict candidates to a single pattern+  | ShowCandidates       -- ^ (debug) show candidates -- warning: wall of text+  | ShowTests            -- ^ (debug) show tests+  | ShowPatterns         -- ^ (debug) show possible LHS patterns+  | ShowDeconstructions  -- ^ (debug) show conjectured-and-allowed deconstructions++  -- pruning options --+  | DontRewrite          -- ^ turns off unique-modulo-rewriting candidates+  | DontRequireDescent   -- ^ require recursive calls to deconstruct arguments+  | OmitAssortedPruning  -- ^ omit other assorted pruning rules+  | OmitEarlyTests       -- ^ don't perform tests early-and-independently on each binding+  | DontCopyBindings     -- ^ don't copy partial definition bindings in candidates+  | AtomicNumbers        -- ^ restrict constant/ground numeric expressions to atoms+  | NonAtomicNumbers     -- ^ lift constant/ground numetic expression restrictions+  | UniqueCandidates     -- ^ unique-modulo-testing candidates+  deriving (Eq, Ord, Show, Read)+++-- | Constructs an ingredient from a setting+setting :: Setting -> Ingredient+setting x  =  (val x, error "Conjure.Settings: evaluating reification, this is a bug")+  -- using 'id' instead of 'error' above would work,+  -- but we want to be warned in case we accidentally evaluate the reification++extract :: Ingredient -> Setting+extract  =  eval Noop . fst++-- | Lists actual incredients in the list+actual :: [Ingredient] -> [Ingredient]+actual is  =  [i | i <- is, typ (fst i) /= typeOf Noop]++-- | By default,+-- 'Conjure.conjure' tests candidates up to a maximum of 360 tests.+-- This configures the maximum number of tests to each candidate,+-- when provided in the list of ingredients:+--+-- > conjure "..." ... [ ...+-- >                   , maxTests 1080+-- >                   , ... ]+maxTests :: Int -> Ingredient+maxTests =  setting . MaxTests++-- | Finds the set maximum number of tests or set the default of 360+maxTestsI  :: [Ingredient] -> Int+maxTestsI is  =  headOr 360 [m | MaxTests m <- map extract is]+  -- the use of magic numbers goes well with the theme of Conjure.++-- | By default,+-- 'Conjure.conjure' imposes no limit on the size of candidates.+--+-- This configures a different maximum+-- when provided in the list of ingredients.+--+-- If only one of 'maxSize' and 'target' is defined,+-- it is used.  If none, target is used.+maxSize :: Int -> Ingredient+maxSize =  setting . MaxSize++-- | By default, 'Conjure.conjure' targets testing 10080 candidates.+-- This configures a different target when+-- provided in the list of ingredients:+--+-- > conjure "..." ... [ ...+-- >                   , target 5040+-- >                   , ... ]+target :: Int -> Ingredient+target =  setting . Target++-- | Computes the target and maxSize.+--+-- When none is provided, we default to a target of 10080.+targetAndMaxSizeI :: [Ingredient] -> (Int, Int)+targetAndMaxSizeI is  =+  case (t, m) of+  (0, 0) -> (10080, 0)+  (t, m) -> (t, m)+  where+  t  =  headOr 0 [m | Target m  <- map extract is]+  m  =  headOr 0 [m | MaxSize m <- map extract is]+-- above is a perfect use for the These datatype,+-- one of my favourite non-standard,+-- but I don't want to impose a dependency on my users...++-- | By default,+-- 'Conjure.conjure' evaluates candidates for up to 60 recursive calls.+--+-- This allows overriding the default+-- when provided in the ingredient list.+maxRecursions :: Int -> Ingredient+maxRecursions =  setting . MaxRecursions++maxRecursionsI :: [Ingredient] -> Int+maxRecursionsI is  =  headOr 60 [m | MaxRecursions m <- map extract is]+++-- | By default,+-- 'Conjure.conjure' considers equations of up to 5 symbols+-- for pruning-through-rewriting.+--+-- This allows overriding the default:+-- 6 or 7 are also good values for this depending on the number of ingredients.+--+-- > conjure ... ... [ ...+-- >                 , maxEquationSize 6+-- >                 , ... ]+--+-- Internally, this is the maximum size passed to the Speculate tool.+maxEquationSize :: Int -> Ingredient+maxEquationSize =  setting . MaxEquationSize++maxEquationSizeI :: [Ingredient] -> Int+maxEquationSizeI is  =  headOr 5 [m | MaxEquationSize m <- map extract is]+++-- | By default,+-- 'Conjure.conjure' enumerates up to 110880 argument combinations+-- while reifying the partial definition passed by the user.+--+-- This allows configuring a higher default+-- when provided in the ingredient list.+--+-- Increasing this setting is useful+-- when the partial definition is not exercised enough.+maxSearchTests :: Int -> Ingredient+maxSearchTests =  setting . MaxSearchTests++maxSearchTestsI :: [Ingredient] -> Int+maxSearchTestsI is  =  headOr 110880 [m | MaxSearchTests m <- map extract is]++-- | By default+-- 'Conjure.conjure' allows deconstruction expressions+-- of up to 4 symbols.+--+-- This allows overriding the default+-- when provided in the ingredient list.+maxDeconstructionSize :: Int -> Ingredient+maxDeconstructionSize =  setting . MaxDeconstructionSize++maxDeconstructionSizeI :: [Ingredient] -> Int+maxDeconstructionSizeI is  =  headOr 4 [m | MaxDeconstructionSize m <- map extract is]++-- | Configures a maximum size of constant sub-expressions+-- when provided in the ingredient list+-- of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+maxConstantSize :: Int -> Ingredient+maxConstantSize =  setting . MaxConstantSize++maxConstantSizeI :: [Ingredient] -> Int+maxConstantSizeI is  =  headOr 0 [m | MaxConstantSize m <- map extract is]++-- | By default,+-- 'Conjure.conjure' places no limit in the LHS pattern sizes.+--+-- This allows configuring a limit when provided in the ingredient list+maxPatternSize :: Int -> Ingredient+maxPatternSize =  setting . MaxPatternSize++maxPatternSizeI :: [Ingredient] -> Int+maxPatternSizeI is  =  headOr 0 [m | MaxPatternSize m <- map extract is]++-- | By default,+-- 'Conjure.conjure' enumerates pattern breakdowns of the outernmost constructor+-- of depth 1.+--+-- This allows overriding the default when provided in the ingredient list:+-- a depth of 2 allows breakdowns of the two outernmost constructors;+-- a depth of 3, three outernmost constructors;+-- etc.+maxPatternDepth :: Int -> Ingredient+maxPatternDepth =  setting . MaxPatternDepth++maxPatternDepthI :: [Ingredient] -> Int+maxPatternDepthI is  =  headOr 1 [m | MaxPatternDepth m <- map extract is]++-- | Carry on after finding a suitable candidate.+--   To be provided as a setting in the list of ingredients.+carryOn :: Ingredient+carryOn =  setting CarryOn++carryOnI :: [Ingredient] -> Bool+carryOnI is  =  notNull [True | CarryOn <- map extract is]++-- | (Debug option).+--   Shows the underlying theory used in pruning+--   when this is provided in the ingredient list.+showTheory :: Ingredient+showTheory =  setting ShowTheory++showTheoryI :: [Ingredient] -> Bool+showTheoryI is  =  notNull [True | ShowTheory <- map extract is]++-- | (Debug option)+--   When provided in the ingredient list,+--   this reverts to a legacy enumeration that+--   contains candidates with a single LHS matching everything.+singlePattern :: Ingredient+singlePattern =  setting SinglePattern++singlePatternI :: [Ingredient] -> Bool+singlePatternI is  =  notNull [True | SinglePattern <- map extract is]++-- | (Debug option)+-- When provided in the ingredients list,+-- this enables showing enumerated candidates.+--+-- > conjure ... ... [ ...+-- >                 , showCandidates+-- >                 , ... ]+--+-- Warning: activating this will likely produce a humongous wall-of-text.+showCandidates :: Ingredient+showCandidates =  setting ShowCandidates++showCandidatesI :: [Ingredient] -> Bool+showCandidatesI is  =  notNull [True | ShowCandidates <- map extract is]++-- | (Debug option)+-- When provided in the ingredients list,+-- 'Conjure.conjure' will print the tests reified from the partial definition.+-- (cf. 'maxTests', 'maxSearchTests')+showTests :: Ingredient+showTests =  setting ShowTests++showTestsI :: [Ingredient] -> Bool+showTestsI is  =  notNull [True | ShowTests <- map extract is]++-- | (Debug option)+-- When this option is provided in the ingredients list,+-- 'Conjure.conjure' will print the enumrated LHS patterns.+-- (cf. 'maxPatternSize', 'maxPatternDepth')+showPatterns :: Ingredient+showPatterns =  setting ShowPatterns++showPatternsI :: [Ingredient] -> Bool+showPatternsI is  =  notNull [True | ShowPatterns <- map extract is]++-- | (Debug option)+-- Makes 'Conjure.conjure' print enumerated deconstructions+-- when provided in its ingredient list.+showDeconstructions :: Ingredient+showDeconstructions =  setting ShowDeconstructions++showDeconstructionsI :: [Ingredient] -> Bool+showDeconstructionsI is  =  notNull [True | ShowDeconstructions <- map extract is]++-- | Disables rewriting-as-pruning+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+dontRewrite :: Ingredient+dontRewrite  =  setting DontRewrite++rewriteI :: [Ingredient] -> Bool+rewriteI is  =  null [False | DontRewrite <- map extract is]++-- | Disables the recursive descent requirement+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+dontRequireDescent :: Ingredient+dontRequireDescent  =  setting DontRequireDescent++requireDescentI :: [Ingredient] -> Bool+requireDescentI is  =  null [False | DontRequireDescent <- map extract is]++-- | Disables assorted pruning rules+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+omitAssortedPruning :: Ingredient+omitAssortedPruning  =  setting OmitAssortedPruning++assortedPruningI :: [Ingredient] -> Bool+assortedPruningI is  =  null [False | OmitAssortedPruning <- map extract is]++-- | Omits early tests+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+omitEarlyTests :: Ingredient+omitEarlyTests  =  setting OmitEarlyTests++earlyTestsI :: [Ingredient] -> Bool+earlyTestsI is  =  null [False | OmitEarlyTests <- map extract is]++-- | Disables the copy-bindings rule+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+dontCopyBindings :: Ingredient+dontCopyBindings  =  setting DontCopyBindings++copyBindingsI :: [Ingredient] -> Bool+copyBindingsI is  =  null [False | DontCopyBindings <- map extract is]++atomicNumbers :: Ingredient+atomicNumbers =  setting AtomicNumbers++-- | Disables the requirement of atomic numeric expressions+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+--   (cf. 'maxConstantSize')+nonAtomicNumbers :: Ingredient+nonAtomicNumbers =  setting NonAtomicNumbers++atomicNumbersI :: [Ingredient] -> Bool+atomicNumbersI is  =  null [False | NonAtomicNumbers <- map extract is]++-- | Enables expensive unique-modulo-testing candidates+--   when provided in the ingredient list+--   of 'Conjure.conjure' or 'Conjure.conjureFromSpec'.+--+-- Warning: this makes 'Conjure.conjure' very slow,+-- it is only intended for approximating the theoretical+-- limits of pruning in toy examples.+uniqueCandidates :: Ingredient+uniqueCandidates =  setting UniqueCandidates++uniqueCandidatesI :: [Ingredient] -> Bool+uniqueCandidatesI is  =  notNull [True | UniqueCandidates <- map extract is]
src/Conjure/Utils.hs view
@@ -28,6 +28,7 @@   , mapHead   , sets   , headOr+  , notNull   , allEqual   , allEqualOn   , allEqual2@@ -150,6 +151,13 @@ headOr :: a -> [a] -> a headOr x []  =  x headOr _ (x:xs)  =  x++-- | Is the given list not null?+--+-- Equivalent to @not . null@+notNull :: [a] -> Bool+notNull []  =  False+notNull (_:_)  =  True  -- | Lists choices of values. choices :: [a] -> [(a,[a])]
test/Test.hs view
@@ -55,14 +55,17 @@ -- were correctly generated. conjurableOK :: (Eq a, Show a, Express a, Listable a, Conjurable a) => a -> Bool conjurableOK x  =  and-  [ holds 60 $ (-==-) ==== (==)+  [ null (conjureArgumentHoles x) -- conjurableOK is for non-functional types+  , holds 60 $ (-==-) ==== (==)   , holds 60 $ expr' === expr   , tiers' =| 6 |= (mapT val $ tiers -: [[x]])   , all isWellTyped cases'   , all (\c -> typ c == typeOf x) cases'+  , isWellTyped (if' :$ (val True) :$ (value "undefined" x) :$ (value "undefined" x))   ]   where   (-==-)  =  evl (fromJust $ conjureEquality x) -:> x   expr'  =  (conjureExpress x . val) -:> x   cases'  =  conjureCases x   tiers'  =  conjureTiersFor x (hole x)+  if'  =  conjureIf x
+ test/factorial.hs view
@@ -0,0 +1,24 @@+-- factorial.hs: conjuring a factorial function+--+-- Copyright (C) 2021-2025 Rudy Matela+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).+import Conjure++factorial :: Int -> Int+factorial 1  =  1+factorial 2  =  2+factorial 3  =  6+factorial 4  =  24++main :: IO ()+main  =  do+  conjure "factorial n" factorial+    [ con (0::Int)+    , con (1::Int)+    , fun "+" ((+) :: Int -> Int -> Int)+    , fun "*" ((*) :: Int -> Int -> Int)+    , fun "-" ((-) :: Int -> Int -> Int)+    ]+  -- should produce:+  -- factorial 0  =  1+  -- factorial x  =  x * factorial (x - 1)