source: sizechecking/Lambda.hs @ 17

Last change on this file since 17 was 17, checked in by gobi, 12 years ago

copyu

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