1 | module Lambda where |
---|
2 | |
---|
3 | {- |
---|
4 | Ez a cikkben megadott lambda kalkulus egy implementacioja + redukcio + peldak. |
---|
5 | |
---|
6 | Hasznalat: lasd Lambda_proof.hs |
---|
7 | |
---|
8 | -} |
---|
9 | import Data.List |
---|
10 | import qualified Data.Set as Set |
---|
11 | import Data.Char |
---|
12 | |
---|
13 | data L = Abs Int L | App L L | Var Int | Num Int | Op L Char L | List L L | AAbs Int Int L |
---|
14 | | Shift L L L | Unsized | Bottom |
---|
15 | deriving Eq |
---|
16 | |
---|
17 | showVar x = if x>28 |
---|
18 | then showVar (x `div` 29) . showChar (chr $ ord 'a' + (x `mod` 29)) |
---|
19 | else showChar $ chr $ ord 'a' + x |
---|
20 | |
---|
21 | getPrec :: Char -> (Int,Int,Int) |
---|
22 | getPrec '+' = (4,4,5) |
---|
23 | getPrec '-' = (4,4,5) |
---|
24 | getPrec '*' = (5,5,6) |
---|
25 | getPrec '/' = (5,5,6) |
---|
26 | getPrec c = error $ "Unknown operator "++[c] |
---|
27 | |
---|
28 | instance Show L where |
---|
29 | showsPrec p (Abs s l) = showParen (p>0) $ showChar 'λ' . showVar s . showChar '.' . shows l |
---|
30 | showsPrec p (AAbs f s l) = showParen (p>0) $ showChar 'Î' . showVar f . showChar ',' . showVar s . showChar '.' . shows l |
---|
31 | showsPrec p (App m n) = showParen (p>6) $ showsPrec 6 m . showChar ' ' . showsPrec 7 n |
---|
32 | showsPrec _ (Var s) = showVar s |
---|
33 | showsPrec _ (Num i) = shows i |
---|
34 | showsPrec p (Op m op n) = showParen (p>prec) $ showsPrec lprec m . showChar op . showsPrec rprec n |
---|
35 | where (prec,lprec,rprec)=getPrec op |
---|
36 | showsPrec p (List s f) = showParen (p>0) $ showString "List " . showsPrec 9 s . showChar ' ' . showsPrec 9 f |
---|
37 | showsPrec p (Shift e1 s e2) = showParen (p>0) $ showString "Shift " .showsPrec 2 e1 . |
---|
38 | showChar ' ' . showsPrec 2 s . showChar ' ' . showsPrec 2 e2 |
---|
39 | showsPrec _ Bottom = showChar 'âŽ' |
---|
40 | showsPrec _ Unsized = showChar 'U' |
---|
41 | |
---|
42 | t3s = Abs 1 $ Abs 0 $ App t (App t (App t x)) |
---|
43 | where t = Var 1 |
---|
44 | x = Var 0 |
---|
45 | |
---|
46 | subs (App x z) var exp = App (subs x var exp) (subs z var exp) |
---|
47 | subs (List s f) var exp = List (subs s var exp) (subs f var exp) |
---|
48 | subs (Shift e1 e2 e3) var exp = Shift (subs e1 var exp) (subs e2 var exp) (subs e3 var exp) |
---|
49 | subs (Op x c z) var exp = Op (subs x var exp) c (subs z var exp) |
---|
50 | subs e@(Var v) var exp | v==var = exp |
---|
51 | | otherwise = e |
---|
52 | subs x@(Abs v e) var exp | v==var = x |
---|
53 | | otherwise = Abs v (subs e var exp) |
---|
54 | subs x@(AAbs s f e) var exp | s==var||f==var = x |
---|
55 | | otherwise = AAbs s f (subs e var exp) |
---|
56 | subs x@(Num _) _ _ = x |
---|
57 | subs x@Bottom _ _ = x |
---|
58 | subs x@Unsized _ _ = x |
---|
59 | |
---|
60 | |
---|
61 | alpha (App x z) from to = App (alpha x from to) (alpha z from to) |
---|
62 | alpha (List x z) from to = List (alpha x from to) (alpha z from to) |
---|
63 | alpha (Op x c z) from to = Op (alpha x from to) c (alpha z from to) |
---|
64 | alpha (Shift x y z) from to = Shift (alpha x from to) (alpha y from to) (alpha z from to) |
---|
65 | alpha e@(Var _) _ _ = e |
---|
66 | alpha e@(Num _) _ _ = e |
---|
67 | alpha e@Bottom _ _ = e |
---|
68 | alpha e@Unsized _ _ = e |
---|
69 | alpha (Abs v e) from to | v==from = Abs to (alpha' e from to) |
---|
70 | | otherwise = Abs v (alpha e from to) |
---|
71 | alpha (AAbs v1 v2 e) from to | v1==from = AAbs to v2 (alpha' e from to) |
---|
72 | | v2==from = AAbs v1 to (alpha' e from to) |
---|
73 | | otherwise = AAbs v1 v2 (alpha e from to) |
---|
74 | |
---|
75 | alpha' (App x z) from to = App (alpha' x from to) (alpha' z from to) |
---|
76 | alpha' (List x z) from to = List (alpha' x from to) (alpha' z from to) |
---|
77 | alpha' (Op x c z) from to = Op (alpha' x from to) c (alpha' z from to) |
---|
78 | alpha' (Shift x y z) from to = Shift (alpha' x from to) (alpha' y from to) (alpha' z from to) |
---|
79 | alpha' e@(Var v) from to | v==from = Var to |
---|
80 | | otherwise = e |
---|
81 | alpha' (Abs v e) from to | v==from = Abs to (alpha' e from to) |
---|
82 | | otherwise = Abs v (alpha' e from to) |
---|
83 | alpha' (AAbs v1 v2 e) from to | v1==from = AAbs to v2 (alpha' e from to) |
---|
84 | | v2==from = AAbs v1 to (alpha' e from to) |
---|
85 | | otherwise = AAbs v1 v2 (alpha' e from to) |
---|
86 | alpha' x@(Num _) _ _ = x |
---|
87 | alpha' x@Bottom _ _ = x |
---|
88 | alpha' x@Unsized _ _ = x |
---|
89 | |
---|
90 | fv (Var x) = Set.singleton x |
---|
91 | fv (App x y) = fv x `Set.union` fv y |
---|
92 | fv (Op x _ y) = fv x `Set.union` fv y |
---|
93 | fv (Abs v e) = v `Set.delete` fv e |
---|
94 | fv (AAbs x y e) = x `Set.delete` ( y `Set.delete` fv e) |
---|
95 | fv (List s e) = fv s `Set.union` fv e |
---|
96 | fv (Num _) = Set.empty |
---|
97 | fv (Shift e1 e2 e3) = fv e1 `Set.union` fv e2 `Set.union` fv e3 |
---|
98 | fv Unsized = Set.empty |
---|
99 | fv Bottom = Set.empty |
---|
100 | |
---|
101 | bv (Var _) = Set.empty |
---|
102 | bv (App x y) = bv x `Set.union` bv y |
---|
103 | bv (Op x _ y) = bv x `Set.union` bv y |
---|
104 | bv (List x y) = bv x `Set.union` bv y |
---|
105 | bv (Abs v e) = v `Set.insert` bv e |
---|
106 | bv (AAbs v1 v2 e) = v1 `Set.insert` (v2 `Set.insert` bv e) |
---|
107 | bv (Shift e1 e2 e3) = bv e1 `Set.union` bv e2 `Set.union` bv e3 |
---|
108 | bv (Num _) = Set.empty |
---|
109 | bv Unsized = Set.empty |
---|
110 | bv Bottom = Set.empty |
---|
111 | |
---|
112 | maxv (Var x) = x |
---|
113 | maxv (Num _) = 0 |
---|
114 | maxv Unsized = 0 |
---|
115 | maxv Bottom = 0 |
---|
116 | maxv (App x y) = maxv x `max` maxv y |
---|
117 | maxv (Op x _ y) = maxv x `max` maxv y |
---|
118 | maxv (Shift x y z) = maxv x `max` maxv y `max` maxv z |
---|
119 | maxv (List x y) = maxv x `max` maxv y |
---|
120 | maxv (Abs v e) = v `max` maxv e |
---|
121 | maxv (AAbs v1 v2 e) = v1 `max` v2 `max` maxv e |
---|
122 | |
---|
123 | rsubs oexp var exp = subs renamed var exp |
---|
124 | where |
---|
125 | dvar = fv exp `Set.intersection` bv oexp |
---|
126 | m = maxv exp `max` maxv oexp |
---|
127 | renames = zip (Set.toList dvar) [m+1..] |
---|
128 | renamed = foldr rename oexp renames |
---|
129 | rename (from,to) _ = alpha oexp from to |
---|
130 | |
---|
131 | |
---|
132 | reduce (App (Abs var exp) z) = return $ rsubs exp var z |
---|
133 | reduce (App (AAbs s f exp) (List s' f')) = return $ rsubs (App (Abs f exp) f') s s' |
---|
134 | reduce (App e f) = case reduce e of |
---|
135 | Just e' -> return $ App e' f |
---|
136 | _ -> reduce f >>= \f' -> return $ App e f' |
---|
137 | reduce (Abs v e) = reduce e >>= \e' -> return $ Abs v e' |
---|
138 | reduce (Var _) = Nothing |
---|
139 | reduce (Num _) = Nothing |
---|
140 | reduce (List e f) = case reduce e of |
---|
141 | Just e' -> return $ List e' f |
---|
142 | _ -> reduce f >>= \f' -> return $ List e f' |
---|
143 | reduce (AAbs v1 v2 e) = reduce e >>= \e' -> return $ AAbs v1 v2 e' |
---|
144 | reduce Unsized = Nothing |
---|
145 | reduce Bottom = Nothing |
---|
146 | reduce (Shift e1 e2 e3) = case reduce e1 of |
---|
147 | Just e' -> return $ Shift e' e2 e3 |
---|
148 | _ -> case reduce e2 of |
---|
149 | Just e' -> return $ Shift e1 e' e3 |
---|
150 | _ -> reduce e3 >>= \e' -> return $ Shift e1 e2 e' |
---|
151 | reduce (Op m c n) = case c of |
---|
152 | '+' | (Num i, Num j) <- (m,n) -> return $ Num $ i+j |
---|
153 | '-' | (Num i, Num j) <- (m,n) -> return $ Num $ i-j |
---|
154 | '*' | (Num i, Num j) <- (m,n) -> return $ Num $ i*j |
---|
155 | '+' | (Num 0) <- m -> reduce n |
---|
156 | '+' | (Num 0) <- n -> reduce m |
---|
157 | '*' | (Num 0) <- m -> return $ Num 0 |
---|
158 | '*' | (Num 0) <- n -> return $ Num 0 |
---|
159 | '*' | (Num 1) <- m -> reduce n |
---|
160 | '*' | (Num 1) <- n -> reduce m |
---|
161 | '-' | (Num 0) <- n -> reduce m |
---|
162 | _ -> case reduce m of |
---|
163 | Just m' -> return $ Op m' c n |
---|
164 | _ -> reduce n >>= \n' -> return $ Op m c n' |
---|
165 | |
---|
166 | r :: Maybe L -> Maybe L |
---|
167 | r x = x >>= reduce |
---|
168 | |
---|
169 | it f x = it' f (Just x) |
---|
170 | where |
---|
171 | it' _ Nothing = [] |
---|
172 | it' f (Just x) = x:it' f (f x) |
---|
173 | |
---|
174 | rchain :: L -> [L] |
---|
175 | rchain = it reduce |
---|
176 | |
---|
177 | pchain = putStrLn . intercalate "\n-> " . map show . rchain |
---|
178 | |
---|
179 | lplus = Abs m $ Abs n $ Abs f $ Abs x $ App (App (Var m) (Var f)) $ App (App (Var n) (Var f)) (Var x) |
---|
180 | where [m,n,f,x] = [0..3] |
---|
181 | lzero = Abs f $ Abs x $ Var x |
---|
182 | where [f,x] = [0,1] |
---|
183 | lsucc = Abs n $ Abs f $ Abs x $ App (Var f) $ App (App (Var n) (Var f)) (Var x) |
---|
184 | where [n,f,x] = [0..2] |
---|
185 | lone = last $ it reduce $ App lsucc lzero |
---|
186 | ltwo = last $ it reduce $ App lsucc lone |
---|
187 | |
---|
188 | lpred = Abs n $ Abs f $ Abs x $ App (App (App (Var n) u1) (Abs u $ Var x)) (Abs u $ Var u) |
---|
189 | where |
---|
190 | u1 = Abs g $ Abs h $ App (Var h) $ App (Var g) (Var f) |
---|
191 | [n,f,x,g,h,u] = [0..5] |
---|
192 | |
---|
193 | lsub = Abs m $ Abs n $ App (App (Var n) lpred) (Var m) |
---|
194 | where (m,n) = (0,1) |
---|
195 | |
---|
196 | ltrue = Abs 0 $ Abs 1 $ Var 0 |
---|
197 | lfalse = Abs 0 $ Abs 1 $ Var 1 |
---|
198 | |
---|
199 | liszero = Abs n $ App (App (Var n) (Abs x lfalse)) ltrue |
---|
200 | where (n,x) = (0,1) |
---|
201 | |
---|
202 | land = Abs 0 $ Abs 1 $ App (App (Var 0) (Var 1)) (Var 1) |
---|
203 | lleq = Abs 0 $ Abs 1 $ App liszero $ App (App lsub (Var 0)) (Var 1) |
---|
204 | leq = Abs 0 $ Abs 1 $ App (App land l1) l2 |
---|
205 | where |
---|
206 | l1 = App (App lleq (Var 0)) (Var 1) |
---|
207 | l2 = App (App lleq (Var 1)) (Var 0) |
---|
208 | |
---|
209 | test = Abs 0 $ Abs 1 $ App (App leq xpy) ypx |
---|
210 | xpy = App (App lplus (Var 0)) (Var 1) |
---|
211 | ypx = App (App lplus (Var 1)) (Var 0) |
---|
212 | |
---|
213 | smap = Abs 5 $ AAbs 18 6 $ List (Var 18) (Abs 8$ App (Var 5) (App (Var 6) (Var 8))) |
---|
214 | conss = Abs 23 $ AAbs 19 5 $ List (Op (Num 1) '+' (Var 19)) $ Shift (Var 5) (Var 19) (Abs 8 $ Var 23) |
---|
215 | addones = AAbs 19 5 $ List (Op (Num 1) '+' (Var 19)) (Abs 8 Unsized) |
---|
216 | nils = List (Num 0) (Abs 8 Bottom) |
---|
217 | lz n = List (Num n) (Abs 8 Unsized) |
---|
218 | srep n x = List (Num n) (Abs 8 x) |
---|
219 | dupfst = AAbs 19 5 $ List (Op (Num 1) '+' (Var 19)) $ Shift (Var 5) (Op (Var 19) '-' (Num 1)) |
---|
220 | $ Abs 8 $ App (Var 5) (Op (Var 19) '-' (Num 1)) |
---|
221 | y = Abs 18 $ App (Abs 22 $ App (Var 18) (App (Var 22) (Var 22))) (Abs 22 $ App (Var 18) (App (Var 22) (Var 22))) |
---|
222 | -- Îs,g.List s (λi.(λx.Ît,f.List (1+t) (Shift f (t-1) x)) U (g i)) |
---|
223 | reverses = AAbs 18 5 $ List (Var 18) (Abs 8 $ App (Var 5) $ Op (Op (Var 18) '-' (Num 1)) '-' (Var 8) ) |
---|
224 | reverse' l = case l of |
---|
225 | [] -> [] |
---|
226 | (x:xs) -> x:reverse' xs |
---|
227 | appends = AAbs 18 5 $ AAbs 19 6 $ List (Op (Var 18) '+' (Var 19)) $ Shift (Var 6) (Var 19) (Var 5) |
---|
228 | |
---|
229 | headc = AAbs 18 5 $ App (Var 5) (Op (Var 18) '-' (Num 1)) |
---|
230 | tailc = AAbs 18 5 $ List (Op (Var 18) '-' (Num 1)) (Var 5) |
---|
231 | rall = last . it reduce |
---|
232 | |
---|
233 | sheads = rall $ App smap headc |
---|
234 | stails = rall $ App smap tailc |
---|