-- $Id: FoldLambdaTests.hs,v 1.1 2013/03/22 01:00:25 leavens Exp leavens $
module FoldLambdaTests where
import Lambda
import Data.List
import FoldLambda
import Testing
main = do startTesting "FoldLambdaTests $Revision: 1.1 $"
errs <- composeTests testsInteger testsBool 0
doneTesting errs
-- The following definitions are just for use in testing
countVarrefs :: Exp -> Integer
countVarrefs = foldLambda (\v -> 1) (+) (\_ body -> (countVarrefs body))
fv :: Exp -> [String] -- using union from Data.List
fv = foldLambda (\v -> [v]) union (\v body -> filter (/=v) (fv body))
bv :: Exp -> [String] -- using union and intersect from Data.List
bv = foldLambda (\v -> []) union
(\v body -> (bv body) `union` ((fv body) `intersect` [v]))
data Value = Const Integer | Fun (Value -> Value)
instance Eq Value where
(Const i) == (Const j) = (i == j)
(Fun f) == (Fun g) = undefined
eval :: (String -> Value) -> Exp -> Value
eval env = foldLambda (\v -> env v) (\(Fun f) a -> f a)
(\v body -> Fun (\x -> let newenv y = (if y == v then x else env y)
in eval newenv body))
-- End of example definitions for help in testing, start of test cases
testsInteger :: [TestCase Integer]
testsInteger =
[eqTest (countVarrefs (Varref "x")) "==" 1
,eqTest (countVarrefs (App (Varref "f") (Varref "x"))) "==" 2
,eqTest (countVarrefs (Lambda "x" (App (Varref "f") (Varref "x")))) "==" 2
,eqTest (countVarrefs (App (Lambda "x" (App (Varref "f") (Varref "x")))
(Varref "z"))) "==" 3 ]
testsBool :: [TestCase Bool]
testsBool =
[assertTrue (fv (Varref "x") == ["x"])
,assertTrue (fv (App (Varref "f") (Varref "x")) == ["f","x"])
,assertTrue (fv (Lambda "x" (App (Varref "f") (Varref "x"))) == ["f"])
,assertTrue (fv (App (Lambda "x" (App (Varref "f") (Varref "x")))
(Varref "z")) == ["f","z"])
,assertTrue (bv (Varref "z") == [])
,assertTrue (bv (App (Varref "g") (Varref "z")) == [])
,assertTrue (bv (Lambda "q" (App (Varref "h") (Varref "q"))) == ["q"])
,assertTrue (bv (Lambda "z" (App (Lambda "x" (App (Varref "f") (Varref "x")))
(Varref "z"))) == ["x","z"])
,assertTrue (eval env (Varref "x") == (Const 1))
,assertTrue (eval env (App (Varref "f") (Varref "x")) == (Const 2))
,assertTrue (eval env (App (Lambda "x" (App (Varref "f") (Varref "x")))
(Varref "x")) == (Const 2))
] where env = (\v -> if v == "x" then Const 1
else if v == "f" then Fun (\(Const n) -> (Const (n+1)))
else (error "undefined var!"))