{-# LANGUAGE DeriveDataTypeable #-}
module Test.Extrapolate.Expr
( module Data.Express
, module Test.Speculate.Expr
, canonicalizeUsingHoles
, canonicalizeUsingHolesWith
, unand
, replaceFun
, (-&&-)
, false
)
where
import Data.Express
import Data.Express.Fixtures
import Test.Speculate.Expr
canonicalizeUsingHoles :: Expr -> Expr
canonicalizeUsingHoles = canonicalizeUsingHolesWith (lookupNames preludeNameInstances)
canonicalizeUsingHolesWith :: (Expr -> [String]) -> Expr -> Expr
canonicalizeUsingHolesWith namesFor = c1 . unrepeatedToHole1
where
c1 e = e //- cn e
cn e = canonicalizationWith namesFor
$ fold [v | v <- vars e, not $ isHole v]
unrepeatedToHole1 e = e //- [(v, holeAsTypeOf v) | (v,1) <- countVars e]
countVars e = map (\e' -> (e',length . filter (== e') $ vars e)) $ nubVars e
unand :: Expr -> (Expr,Expr)
unand ((op :$ e1) :$ e2) | op == andE = (e1,e2)
unand _ = error "unimply: not an implication"
replaceFun :: Expr -> Expr -> Expr
replaceFun ef e = foldApp (ef:tail es)
where
es = unfoldApp e