speculate 0.2.10 → 0.3.0
raw patch · 4 files changed
+96/−10 lines, 4 files
Files
- speculate.cabal +2/−2
- src/Test/Speculate/Engine.hs +48/−8
- src/Test/Speculate/Expr/Core.hs +5/−0
- tests/test-engine.hs +41/−0
speculate.cabal view
@@ -1,5 +1,5 @@ name: speculate-version: 0.2.10+version: 0.3.0 synopsis: discovery of properties about Haskell functions description: Speculate automatically discovers laws about Haskell functions.@@ -31,7 +31,7 @@ source-repository this type: git location: https://github.com/rudymatela/speculate- tag: v0.2.10+ tag: v0.3.0 library
src/Test/Speculate/Engine.hs view
@@ -10,6 +10,8 @@ module Test.Speculate.Engine ( vassignments , expansions+ , expansionsOfType+ , expansionsWith , mostGeneral , mostSpecific @@ -21,6 +23,7 @@ , consider , distinctFromSchemas , classesFromSchemas+ , classesFromSchemasAndVariables , semiTheoryFromThyAndReps @@ -79,16 +82,43 @@ vassignmentsEqn :: (Expr,Expr) -> [(Expr,Expr)] vassignmentsEqn = filter (uncurry (/=)) . map unEquation . vassignments . uncurry phonyEquation +-- | List all variable assignments for a given type and list of variables.+expansionsOfType :: TypeRep -> [String] -> Expr -> [Expr]+expansionsOfType t vs e = [ fill e [Var v t | v <- vs']+ | vs' <- placements (countHoles t e) vs ]+ where+ placements :: Int -> [a] -> [[a]]+ placements 0 xs = [[]]+ placements n xs = [y:ys | y <- xs, ys <- placements (n-1) xs]++expansionsWith :: [Expr] -> Expr -> [Expr]+expansionsWith es = ew (collectWith typ nam (,) es)+ where+ nam (Var s _) = s+ typ (Var _ t) = t+ ew :: [(TypeRep,[String])] -> Expr -> [Expr]+ ew [] e = [e]+ ew ((t,ns):tnss) e = ew tnss+ `concatMap` expansionsOfType t ns e++-- | List all variable assignments for a given number of variables.+-- It only assign variables to holes (variables with "" as its name).+--+-- > > expansions preludeInstances 2 '(_ + _ + ord _)+-- > [ (x + x) + ord c :: Int+-- > , (x + x) + ord d :: Int+-- > , (x + y) + ord c :: Int+-- > , (x + y) + ord d :: Int+-- > , (y + x) + ord c :: Int+-- > , (y + x) + ord d :: Int+-- > , (y + y) + ord c :: Int+-- > , (y + y) + ord d :: Int ] expansions :: Instances -> Int -> Expr -> [Expr] expansions ti n e =- [ foldl fill e [ [ Var (names ti t !! i) t | i <- is ]- | (t,is) <- fs ]- | fs <- productsList [[(t,is) | is <- foo c n] | (t,c) <- counts (holes e)] ]- where- foo :: Int -> Int -> [[Int]]- foo 0 nVars = [[]]- foo nPos nVars = [i:is | i <- [0..(nVars-1)], is <- foo (nPos-1) nVars]--- TODO: test expansions, put foo together with iss+ case counts (holes e) of+ [] -> [e]+ (t,c):_ -> expansions ti n `concatMap`+ expansionsOfType t (take n (names ti t)) e -- | List the most general assignment of holes in an expression mostGeneral :: Expr -> Expr@@ -198,6 +228,16 @@ classesFromSchema ti thy n = C.mergesOn (normalizeE thy) . map C.fromRep . expansions ti n++classesFromSchemasAndVariables :: Thy -> [Expr] -> [Expr] -> [Class Expr]+classesFromSchemasAndVariables thy vs = C.mergesOn (normalizeE thy)+ . concatMap (classesFromSchemaAndVariables thy vs)++classesFromSchemaAndVariables :: Thy -> [Expr] -> Expr -> [Class Expr]+classesFromSchemaAndVariables thy vs = C.mergesOn (normalizeE thy)+ . map C.fromRep+ . filter (null . holes)+ . expansionsWith vs -- Return relevant equivalences between holed expressions: --
src/Test/Speculate/Expr/Core.hs view
@@ -43,6 +43,7 @@ -- * Properties of expressions , lengthE , depthE+ , countHoles , countVar , countVars , unrepeatedVars@@ -399,6 +400,10 @@ depthE :: Expr -> Int depthE e@(_:$_) = 1 + maximum (map depthE $ unfoldApp e) depthE _ = 1++-- | Number of occurrences of holes with a given type.+countHoles :: TypeRep -> Expr -> Int+countHoles t = count t . holes -- | Number of occurrences of a given variable name. -- In term rewriting terms: |s|_x
tests/test-engine.hs view
@@ -82,6 +82,47 @@ , subConsequence emptyThy [] (abs' xx -==- abs' yy) (abs' xx) (abs' yy) , not $ subConsequence emptyThy [] (abs' xx -<=- abs' yy) (abs' xx) (abs' yy) , not $ subConsequence emptyThy [] (abs' xx -==- one) (xx -+- abs' xx) zero++ , holds n $ \e -> length (expansions preludeInstances 1 e) == 1++ , expansions preludeInstances 2 (i_ -+- i_)+ == [ xx -+- xx+ , xx -+- yy+ , yy -+- xx+ , yy -+- yy ]++ , expansions preludeInstances 2 (i_ -+- i_ -+- ord' c_)+ == [ xx -+- xx -+- ord' cc+ , xx -+- xx -+- ord' dd+ , xx -+- yy -+- ord' cc+ , xx -+- yy -+- ord' dd+ , yy -+- xx -+- ord' cc+ , yy -+- xx -+- ord' dd+ , yy -+- yy -+- ord' cc+ , yy -+- yy -+- ord' dd ]++ , expansionsOfType intTy ["x","y"] (i_ -+- i_ -+- ord' c_)+ == [ xx -+- xx -+- ord' c_+ , xx -+- yy -+- ord' c_+ , yy -+- xx -+- ord' c_+ , yy -+- yy -+- ord' c_ ]++ , expansionsOfType intTy [] (i_ -+- i_ -+- ord' c_) == []++ , expansionsWith [xx, yy] (i_ -+- i_ -+- ord' c_)+ == [ xx -+- xx -+- ord' c_+ , xx -+- yy -+- ord' c_+ , yy -+- xx -+- ord' c_+ , yy -+- yy -+- ord' c_ ]++ , expansionsWith [cc] (i_ -+- i_ -+- ord' c_)+ == [ i_ -+- i_ -+- ord' cc ]++ , expansionsWith [xx, yy, cc] (i_ -+- i_ -+- ord' c_)+ == [ xx -+- xx -+- ord' cc+ , xx -+- yy -+- ord' cc+ , yy -+- xx -+- ord' cc+ , yy -+- yy -+- ord' cc ] ] where x === y = equal preludeInstances 1000 x y