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 +1/−0
- Makefile +3/−6
- README.md +30/−30
- TODO.md +7/−18
- bench/candidates.hs +30/−30
- bench/carry-on.hs +8/−6
- bench/carry-on.txt +1/−1
- bench/erroneous.hs +29/−29
- bench/gps.hs +240/−230
- bench/gps.txt +11/−15
- bench/gps2.hs +168/−156
- bench/gps2.txt +20/−38
- bench/ill-hit.hs +15/−11
- bench/ill-hit.txt +3/−0
- bench/lowtests.hs +26/−17
- bench/lowtests.txt +2/−2
- bench/p12.hs +31/−34
- bench/p12.txt +1/−1
- bench/p30.hs +42/−45
- bench/p30.txt +1/−1
- bench/redundants.hs +30/−30
- bench/runtime/lapmatrud/bench/candidates.runtime +1/−1
- bench/runtime/lapmatrud/bench/carry-on.runtime +1/−1
- bench/runtime/lapmatrud/bench/erroneous.runtime +1/−1
- bench/runtime/lapmatrud/bench/gps.runtime +1/−1
- bench/runtime/lapmatrud/bench/gps2.runtime +1/−1
- bench/runtime/lapmatrud/bench/ill-hit.runtime +1/−1
- bench/runtime/lapmatrud/bench/lowtests.runtime +1/−1
- bench/runtime/lapmatrud/bench/p12.runtime +1/−1
- bench/runtime/lapmatrud/bench/redundants.runtime +1/−1
- bench/runtime/lapmatrud/bench/strategies.runtime +1/−1
- bench/runtime/lapmatrud/bench/terpret.runtime +1/−1
- bench/runtime/lapmatrud/bench/unique.runtime +1/−1
- bench/runtime/lapmatrud/bench/weird.runtime +1/−1
- bench/runtime/lapmatrud/eg/arith.runtime +1/−1
- bench/runtime/lapmatrud/eg/bits.runtime +1/−1
- bench/runtime/lapmatrud/eg/bools.runtime +1/−1
- bench/runtime/lapmatrud/eg/bst.runtime +1/−1
- bench/runtime/lapmatrud/eg/count.runtime +1/−1
- bench/runtime/lapmatrud/eg/dupos.runtime +1/−1
- bench/runtime/lapmatrud/eg/either.runtime +1/−1
- bench/runtime/lapmatrud/eg/factorial.runtime +1/−1
- bench/runtime/lapmatrud/eg/fib01.runtime +1/−1
- bench/runtime/lapmatrud/eg/fibonacci.runtime +1/−1
- bench/runtime/lapmatrud/eg/higher.runtime +1/−1
- bench/runtime/lapmatrud/eg/ints.runtime +1/−1
- bench/runtime/lapmatrud/eg/maybe.runtime +1/−1
- bench/runtime/lapmatrud/eg/oddeven.runtime +1/−1
- bench/runtime/lapmatrud/eg/pow.runtime +1/−1
- bench/runtime/lapmatrud/eg/sort.runtime +1/−1
- bench/runtime/lapmatrud/eg/these.runtime +1/−1
- bench/runtime/lapmatrud/eg/tree.runtime +1/−1
- bench/runtime/lapmatrud/eg/tri.runtime +1/−1
- bench/runtime/lapmatrud/eg/tuple.runtime +1/−1
- bench/runtime/lapmatrud/versions +1/−1
- bench/runtime/zero/bench/candidates.runtime +1/−1
- bench/runtime/zero/bench/carry-on.runtime +1/−1
- bench/runtime/zero/bench/erroneous.runtime +1/−1
- bench/runtime/zero/bench/gps.runtime +1/−1
- bench/runtime/zero/bench/gps2.runtime +1/−1
- bench/runtime/zero/bench/ill-hit.runtime +1/−1
- bench/runtime/zero/bench/longshot.runtime +1/−1
- bench/runtime/zero/bench/p30.runtime +1/−1
- bench/runtime/zero/bench/redundants.runtime +1/−1
- bench/runtime/zero/bench/strategies.runtime +1/−1
- bench/runtime/zero/bench/weird.runtime +1/−1
- bench/runtime/zero/eg/arith.runtime +1/−1
- bench/runtime/zero/eg/bits.runtime +1/−1
- bench/runtime/zero/eg/bools.runtime +1/−1
- bench/runtime/zero/eg/bst.runtime +1/−1
- bench/runtime/zero/eg/dupos.runtime +1/−1
- bench/runtime/zero/eg/fibonacci.runtime +1/−1
- bench/runtime/zero/eg/ints.runtime +1/−1
- bench/runtime/zero/eg/oddeven.runtime +1/−1
- bench/runtime/zero/eg/setelem.runtime +1/−1
- bench/runtime/zero/eg/sort.runtime +1/−1
- bench/runtime/zero/eg/spec.runtime +1/−1
- bench/runtime/zero/eg/these.runtime +1/−1
- bench/runtime/zero/eg/tree.runtime +1/−1
- bench/runtime/zero/eg/tuple.runtime +1/−1
- bench/runtime/zero/versions +1/−1
- bench/self.hs +12/−14
- bench/self.txt +1/−1
- bench/strategies.hs +18/−21
- bench/terpret.hs +54/−52
- bench/terpret.txt +1/−1
- bench/unique.hs +28/−28
- bench/weird.hs +14/−14
- changelog.md +19/−0
- code-conjure.cabal +12/−3
- eg/arith.hs +12/−12
- eg/bits.hs +11/−11
- eg/bits.txt +2/−2
- eg/bools.hs +15/−15
- eg/bst.hs +47/−40
- eg/bst.txt +7/−7
- eg/colin/IntFuns.hs +27/−27
- eg/colin/ListFuns.hs +54/−54
- eg/count.hs +12/−12
- eg/count.txt +2/−2
- eg/dupos.hs +18/−18
- eg/either.hs +14/−14
- eg/either.txt +1/−1
- eg/factorial.hs +12/−12
- eg/fib01.hs +16/−10
- eg/fib01.txt +2/−2
- eg/fibonacci.hs +5/−5
- eg/gcd.hs +2/−2
- eg/higher.hs +10/−10
- eg/id.hs +1/−1
- eg/ints.hs +26/−26
- eg/list.hs +33/−32
- eg/list.txt +2/−2
- eg/maybe.hs +25/−25
- eg/oddeven.hs +22/−22
- eg/peano.hs +6/−6
- eg/pow.hs +13/−12
- eg/pow.txt +1/−1
- eg/replicate.hs +15/−15
- eg/setelem.hs +16/−16
- eg/setelem.txt +2/−2
- eg/sort.hs +38/−33
- eg/sort.txt +2/−2
- eg/spec.hs +23/−23
- eg/subset.hs +8/−8
- eg/subset.txt +1/−1
- eg/take-drop.hs +10/−10
- eg/tapps.hs +24/−24
- eg/these.hs +23/−20
- eg/tree.hs +43/−42
- eg/tree.txt +3/−3
- eg/tri.hs +3/−3
- eg/tuple.hs +27/−29
- eg/tuple.txt +2/−2
- mk/depend.mk +144/−65
- mk/haddock-i +31/−20
- mk/haskell.mk +1/−1
- src/Conjure.hs +58/−28
- src/Conjure/Conjurable.hs +1/−1
- src/Conjure/Engine.hs +173/−244
- src/Conjure/Expr.hs +15/−3
- src/Conjure/Ingredient.hs +275/−0
- src/Conjure/Prim.hs +0/−217
- src/Conjure/Settings.hs +424/−0
- src/Conjure/Utils.hs +8/−0
- test/Test.hs +4/−1
- test/factorial.hs +24/−0
.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)