1 {-# LANGUAGE PatternSynonyms #-}
5 import Control.Monad.State
8 import qualified HM.Term as HMT
12 data LTerm = Var VarName | Lam VarName LTerm | Let VarName LTerm LTerm | App LTerm LTerm deriving (Eq, Show)
14 pattern RedEx x t s = App (Lam x t) s
16 convert :: HMT.TypedTerm -> LTerm
17 convert (HMT.TTerm t _) = convert (HMT.NTTerm t)
18 convert (HMT.NTTerm (HMT.Var x)) = Var x
19 convert (HMT.NTTerm (HMT.Lam x t)) = Lam x $ convert t
20 convert (HMT.NTTerm (HMT.Let x y z)) = Let x (convert y) (convert z)
21 convert (HMT.NTTerm (HMT.App y z)) = App (convert y) (convert z)
23 isFreeIn :: VarName -> LTerm -> Bool
24 isFreeIn x (Var v) = x == v
25 isFreeIn x (App t u) = x `isFreeIn` t || x `isFreeIn` u
26 isFreeIn x (Lam v t) = x /= v && x `isFreeIn` t
27 isFreeIn x (Let v t u) = x `isFreeIn` t || x /= v && x `isFreeIn` u
29 rename :: LTerm -> LTerm
30 rename (Lam x t) = Lam n (substitute x (Var n) t)
32 rnm v = if (v ++ "r") `isFreeIn` t then rnm (v ++ "r") else v ++ "r"
33 rename _ = error "TODO vymyslet reprezentaci, kde pujde udelat fce, ktera bere jen Lambdy"
35 substitute :: VarName -> LTerm -> LTerm -> LTerm
36 substitute a b (Var x) = if x == a then b else Var x
37 substitute a b (Lam x t)
39 | x `isFreeIn` b = substitute a b $ rename (Lam x t)
40 | otherwise = Lam x (substitute a b t)
41 substitute a b (Let x t u) = error "TODO implement let"
42 substitute a b (App t u) = App (substitute a b t) (substitute a b u)
44 reduce :: LTerm -> LTerm
45 reduce (Var x) = Var x
46 reduce (Lam x t) = Lam x (reduce t)
47 reduce (App t u) = app (reduce t) u
48 where app (Lam x v) w = reduce $ substitute x w v
49 app a b = App a (reduce b)
51 data Strategy = Eager | Lazy
53 reduceStep :: LTerm -> LTerm
54 reduceStep (RedEx x s t) = substitute x t s
57 data Z = R LTerm Z | L Z LTerm | ZL VarName Z | E
59 type TermZipper = (LTerm, Z, D)
61 move :: TermZipper -> TermZipper
62 move (App l r, c, Down) = (l, L c r, Down)
63 move (Lam x t, c, Down) = (t, ZL x c, Down)
64 move (Var x, c, Down) = (Var x, c, Up)
65 move (t, L c r, Up) = (r, R t c, Down)
66 move (t, R l c, Up) = (App l t, c, Up)
67 move (t, ZL x c, Up) = (Lam x t, c, Up)
68 move (t, E, Up) = (t, E, Up)
70 unmove :: TermZipper -> TermZipper
71 unmove (t, L c r, Down) = (App t r, c, Down)
74 -- getTerm :: TermZipper -> Term
76 travPost :: (Monad m) => (LTerm -> m LTerm) -> LTerm -> m LTerm
77 travPost fnc term = tr fnc (term, E, Down)
79 tr f (t@RedEx{}, c, Up) = do
82 tr _ (t, E, Up) = return t
83 tr f (t, c, Up) = tr f $ move (t, c, Up)
84 tr f (t, c, Down) = tr f $ move (t, c, Down)
86 travPre :: (Monad m) => (LTerm -> m LTerm) -> LTerm -> m LTerm
87 travPre fnc term = tr fnc (term, E, Down)
89 tr f (t@RedEx{}, c, Down) = do
91 tr f $ unmove (nt, c, Down)
92 tr _ (t, E, Up) = return t
93 tr f (t, c, Up) = tr f $ move (t, c, Up)
94 tr f (t, c, Down) = tr f $ move (t, c, Down)
98 -- >>> toNormalForm Eager 100 cI
101 -- >>> toNormalForm Eager 100 $ App cI cI
104 -- >>> toNormalForm Eager 100 $ (App (App cK cI) cY)
107 -- >>> toNormalForm Lazy 100 $ (App (App cK cI) cY)
110 -- prop> within 10000000 $ (\ t u -> t == u || t == Nothing || u == Nothing) (alphaNorm <$> toNormalForm Lazy 100 x) (alphaNorm <$> toNormalForm Eager 100 x)
112 -- inf = tRead "(\\d.a ((\\d c.c d c) (\\x y z.x z (y z)) (\\f.(\\x.f (x x)) (\\x.f (x x))) e))"
114 toNormalForm :: Strategy -> Int -> LTerm -> Maybe LTerm
115 toNormalForm Eager n = flip evalStateT 0 . travPost (cnt >=> short n >=> return . reduceStep)
116 toNormalForm Lazy n = flip evalStateT 0 . travPre (cnt >=> short n >=> return . reduceStep)
118 cnt :: (Monad m) => LTerm -> StateT Int m LTerm
124 short :: Int -> LTerm -> StateT Int Maybe LTerm