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
type Ingredient = (Expr, Reification)
con :: (Conjurable a, Show a) => a -> Ingredient
con :: forall a. (Conjurable a, Show a) => a -> Ingredient
con a
x = (a -> Expr
forall a. (Typeable a, Show a) => a -> Expr
val a
x, a -> Reification
forall a. Conjurable a => a -> Reification
conjureType a
x)
fun :: Conjurable a => String -> a -> Ingredient
fun :: forall a. Conjurable a => String -> a -> Ingredient
fun String
s a
x = (String -> a -> Expr
forall a. Typeable a => String -> a -> Expr
value String
s a
x, a -> Reification
forall a. Conjurable a => a -> Reification
conjureType a
x)
iif :: Conjurable a => a -> Ingredient
iif :: forall a. Conjurable a => a -> Ingredient
iif a
x = (a -> Expr
forall a. Typeable a => a -> Expr
ifFor a
x, a -> Reification
forall a. Conjurable a => a -> Reification
conjureType a
x)
guard :: Ingredient
guard :: Ingredient
guard = (Bool -> Expr
forall a. Typeable a => a -> Expr
guardFor (Bool
forall a. HasCallStack => a
undefined :: Bool), Bool -> Reification
forall a. Conjurable a => a -> Reification
conjureType (Bool
forall a. HasCallStack => a
undefined :: Bool))
ordcase :: Conjurable a => a -> Ingredient
ordcase :: forall a. Conjurable a => a -> Ingredient
ordcase a
x = (a -> Expr
forall a. Typeable a => a -> Expr
caseForOrd a
x, a -> Reification
forall a. Conjurable a => a -> Reification
conjureType a
x)
cjReification :: [Ingredient] -> [Reification1]
cjReification :: [Ingredient] -> [Reification1]
cjReification [Ingredient]
ps = (Reification1 -> Expr) -> Reification
forall b a. Eq b => (a -> b) -> [a] -> [a]
nubOn (\(Expr
eh,Maybe Expr
_,Maybe [[Expr]]
_,[String]
_,[Expr]
_,Expr
_) -> Expr
eh)
Reification -> Reification
forall a b. (a -> b) -> a -> b
$ (Reification -> Reification -> Reification)
-> Reification -> [Reification] -> Reification
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Reification -> Reification -> Reification
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) Reification
forall a. a -> a
id ((Ingredient -> Reification) -> [Ingredient] -> [Reification]
forall a b. (a -> b) -> [a] -> [b]
map Ingredient -> Reification
forall a b. (a, b) -> b
snd [Ingredient]
ps) [Bool -> Reification1
forall a. Conjurable a => a -> Reification1
conjureReification1 Bool
bool]
cjHoles :: [Ingredient] -> [Expr]
cjHoles :: [Ingredient] -> [Expr]
cjHoles [Ingredient]
ps = [Expr
eh | (Expr
eh,Maybe Expr
_,Just [[Expr]]
_,[String]
_,[Expr]
_,Expr
_) <- [Ingredient] -> [Reification1]
cjReification [Ingredient]
ps]
cjMkEquation :: [Ingredient] -> Expr -> Expr -> Expr
cjMkEquation :: [Ingredient] -> Expr -> Expr -> Expr
cjMkEquation [Ingredient]
ps = [Expr] -> Expr -> Expr -> Expr
mkEquation [Expr
eq | (Expr
_,Just Expr
eq,Maybe [[Expr]]
_,[String]
_,[Expr]
_,Expr
_) <- [Ingredient] -> [Reification1]
cjReification [Ingredient]
ps]
cjAreEqual :: [Ingredient] -> Int -> Expr -> Expr -> Bool
cjAreEqual :: [Ingredient] -> Int -> Expr -> Expr -> Bool
cjAreEqual [Ingredient]
ps Int
maxTests = Expr -> Expr -> Bool
(===)
where
-==- :: Expr -> Expr -> Expr
(-==-) = [Ingredient] -> Expr -> Expr -> Expr
cjMkEquation [Ingredient]
ps
Expr
e1 === :: Expr -> Expr -> Bool
=== Expr
e2 = Expr -> Bool
isTrue (Expr -> Bool) -> Expr -> Bool
forall a b. (a -> b) -> a -> b
$ Expr
e1 Expr -> Expr -> Expr
-==- Expr
e2
isTrue :: Expr -> Bool
isTrue = (Expr -> Bool) -> [Expr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
errorToFalse (Bool -> Bool) -> (Expr -> Bool) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Expr -> Bool
forall a. Typeable a => a -> Expr -> a
eval Bool
False) ([Expr] -> Bool) -> (Expr -> [Expr]) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
gs
gs :: Expr -> [Expr]
gs = Int -> [Expr] -> [Expr]
forall a. Int -> [a] -> [a]
take Int
maxTests ([Expr] -> [Expr]) -> (Expr -> [Expr]) -> Expr -> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ingredient] -> Expr -> [Expr]
cjGrounds [Ingredient]
ps
cjGrounds :: [Ingredient] -> Expr -> [Expr]
cjGrounds :: [Ingredient] -> Expr -> [Expr]
cjGrounds = (Expr -> [[Expr]]) -> Expr -> [Expr]
grounds ((Expr -> [[Expr]]) -> Expr -> [Expr])
-> ([Ingredient] -> Expr -> [[Expr]])
-> [Ingredient]
-> Expr
-> [Expr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Ingredient] -> Expr -> [[Expr]]
cjTiersFor
cjTiersFor :: [Ingredient] -> Expr -> [[Expr]]
cjTiersFor :: [Ingredient] -> Expr -> [[Expr]]
cjTiersFor [Ingredient]
ps Expr
e = [[[Expr]]] -> [[Expr]]
tf [[[Expr]]]
allTiers
where
allTiers :: [ [[Expr]] ]
allTiers :: [[[Expr]]]
allTiers = [[[Expr]]
etiers | (Expr
_,Maybe Expr
_,Just [[Expr]]
etiers,[String]
_,[Expr]
_,Expr
_) <- [Ingredient] -> [Reification1]
cjReification [Ingredient]
ps]
tf :: [[[Expr]]] -> [[Expr]]
tf [] = [[Expr
e]]
tf ([[Expr]]
etiers:[[[Expr]]]
etc) = case [[Expr]]
etiers of
((Expr
e':[Expr]
_):[[Expr]]
_) | Expr -> TypeRep
typ Expr
e' TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== Expr -> TypeRep
typ Expr
e -> [[Expr]]
etiers
[[Expr]]
_ -> [[[Expr]]] -> [[Expr]]
tf [[[Expr]]]
etc
type Prim = Ingredient
{-# DEPRECATED Prim "'Prim' is deprecated, please use 'Ingredient' instead" #-}
pr :: (Conjurable a, Show a) => a -> Ingredient
pr :: forall a. (Conjurable a, Show a) => a -> Ingredient
pr = a -> Ingredient
forall a. (Conjurable a, Show a) => a -> Ingredient
con
{-# DEPRECATED pr "'pr' is deprecated, please use 'con' instead" #-}
prim :: Conjurable a => String -> a -> Ingredient
prim :: forall a. Conjurable a => String -> a -> Ingredient
prim = String -> a -> Ingredient
forall a. Conjurable a => String -> a -> Ingredient
fun
{-# DEPRECATED prim "'prim' is deprecated, please use 'fun' instead" #-}
prif :: Conjurable a => a -> Ingredient
prif :: forall a. Conjurable a => a -> Ingredient
prif = a -> Ingredient
forall a. Conjurable a => a -> Ingredient
iif
{-# DEPRECATED prif "'prif' is deprecated, please use 'iif' instead" #-}
primOrdCaseFor :: Conjurable a => a -> Ingredient
primOrdCaseFor :: forall a. Conjurable a => a -> Ingredient
primOrdCaseFor = a -> Ingredient
forall a. Conjurable a => a -> Ingredient
ordcase
{-# DEPRECATED primOrdCaseFor "'primOrdCaseFor' is deprecated, please use 'ordcase' instead" #-}