source: sizechecking/Lambda.hs @ 16

Last change on this file since 16 was 15, checked in by gobi, 13 years ago

new solver

File size: 9.1 KB
Line 
1module Lambda where
2
3{-
4   Ez a cikkben megadott lambda kalkulus egy implementacioja + redukcio + peldak.
5
6   Hasznalat: lasd Lambda_proof.hs
7
8 -}
9import Data.List
10import qualified Data.Set as Set
11import Data.Char
12
13data 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, Ord)
16
17showVar 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
21getPrec :: Char -> (Int,Int,Int)
22getPrec '+' = (4,4,5)
23getPrec '-' = (4,4,5)
24getPrec '*' = (5,5,6)
25getPrec '/' = (5,5,6)
26getPrec c   = error $ "Unknown operator "++[c]
27
28instance 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
42t3s = Abs 1 $ Abs 0 $ App t (App t (App t x))
43    where t = Var 1
44          x = Var 0
45
46subs (App x z)   var exp = App (subs x var exp) (subs z var exp)
47subs (List s f)  var exp = List (subs s var exp) (subs f var exp)
48subs (Shift e1 e2 e3) var exp = Shift (subs e1 var exp) (subs e2 var exp) (subs e3 var exp)
49subs (Op x c z)  var exp = Op (subs x var exp) c (subs z var exp)
50subs e@(Var v)   var exp | v==var    = exp
51                         | otherwise = e
52subs x@(Abs v e) var exp | v==var    = x
53                         | otherwise = Abs v (subs e var exp)
54subs x@(AAbs s f e) var exp | s==var||f==var = x
55                            | otherwise = AAbs s f (subs e var exp)
56subs x@(Num _)   _ _ = x
57subs x@Bottom    _ _ = x
58subs x@Unsized   _ _ = x
59
60
61alpha (App x z)   from to = App (alpha x from to) (alpha z from to)
62alpha (List x z)  from to = List (alpha x from to) (alpha z from to)
63alpha (Op x c z)  from to = Op (alpha x from to) c (alpha z from to)
64alpha (Shift x y z) from to = Shift (alpha x from to) (alpha y from to) (alpha z from to)
65alpha e@(Var _)   _    _  = e
66alpha e@(Num _)   _    _  = e
67alpha e@Bottom   _    _  = e
68alpha e@Unsized   _    _  = e
69alpha (Abs v e) from to | v==from   = Abs to (alpha' e from to)
70                        | otherwise = Abs v (alpha e from to)
71alpha (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
75alpha' (App x z)   from to = App (alpha' x from to) (alpha' z from to)
76alpha' (List x z)  from to = List (alpha' x from to) (alpha' z from to)
77alpha' (Op x c z)  from to = Op (alpha' x from to) c (alpha' z from to)
78alpha' (Shift x y z) from to = Shift (alpha' x from to) (alpha' y from to) (alpha' z from to)
79alpha' e@(Var v)   from to | v==from   = Var to
80                           | otherwise = e
81alpha' (Abs v e) from to | v==from   = Abs to (alpha' e from to)
82                         | otherwise = Abs v (alpha' e from to)
83alpha' (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)
86alpha' x@(Num _)   _    _  = x
87alpha' x@Bottom   _    _  = x
88alpha' x@Unsized   _    _  = x
89
90fv (Var x) = Set.singleton x
91fv (App x y) = fv x `Set.union` fv y
92fv (Op x _ y) = fv x `Set.union` fv y
93fv (Abs v e) = v `Set.delete` fv e
94fv (AAbs x y e) = x `Set.delete` ( y `Set.delete` fv e)
95fv (List s e) = fv s `Set.union` fv e
96fv (Num _) = Set.empty
97fv (Shift e1 e2 e3) = fv e1 `Set.union` fv e2 `Set.union` fv e3
98fv Unsized = Set.empty
99fv Bottom = Set.empty
100
101bv (Var _) = Set.empty
102bv (App x y) = bv x `Set.union` bv y
103bv (Op x _ y) = bv x `Set.union` bv y
104bv (List x y) = bv x `Set.union` bv y
105bv (Abs v e) = v `Set.insert` bv e
106bv (AAbs v1 v2 e) = v1 `Set.insert` (v2 `Set.insert` bv e)
107bv (Shift e1 e2 e3) = bv e1 `Set.union` bv e2 `Set.union` bv e3
108bv (Num _)   = Set.empty
109bv Unsized = Set.empty
110bv Bottom = Set.empty
111
112maxv (Var x)   = x
113maxv (Num _)   = 0
114maxv Unsized = 0
115maxv Bottom = 0
116maxv (App x y) = maxv x `max` maxv y
117maxv (Op x _ y) = maxv x `max` maxv y
118maxv (Shift x y z) = maxv x `max` maxv y `max` maxv z
119maxv (List x y) = maxv x `max` maxv y
120maxv (Abs v e) = v `max` maxv e
121maxv (AAbs v1 v2 e) = v1 `max` v2 `max` maxv e
122
123rsubs 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
132reduce (App (Abs var exp) z) = return $ rsubs exp var z
133reduce (App (AAbs s f exp) (List s' f')) = return $ rsubs (App (Abs f exp) f') s s'
134reduce (App e f) = case reduce e of
135        Just e' -> return $ App e' f
136        _       -> reduce f >>= \f' -> return $ App e f'
137reduce (Abs v e) = reduce e >>= \e' -> return $ Abs v e'
138reduce (Var _) = Nothing
139reduce (Num _) = Nothing
140reduce (List e f) = case reduce e of
141        Just e' -> return $ List e' f
142        _       -> reduce f >>= \f' -> return $ List e f'
143reduce (AAbs v1 v2 e) = reduce e >>= \e' -> return $ AAbs v1 v2 e'
144reduce Unsized = Nothing
145reduce Bottom  = Nothing
146reduce (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'
151reduce (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
166r :: Maybe L -> Maybe L
167r x = x >>= reduce
168
169it f x = it' f (Just x)
170    where
171    it' _ Nothing  = []
172    it' f (Just x) = x:it' f (f x)
173
174rchain :: L -> [L]
175rchain = it reduce
176
177pchain = putStrLn . intercalate "\n-> " . map show . rchain
178
179lplus = 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]
181lzero = Abs f $ Abs x $ Var x
182    where [f,x] = [0,1]
183lsucc = Abs n $ Abs f $ Abs x $ App (Var f) $ App (App (Var n) (Var f)) (Var x)
184    where [n,f,x] = [0..2]
185lone = last $ it reduce $ App lsucc lzero
186ltwo = last $ it reduce $ App lsucc lone
187
188lpred = 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   
193lsub = Abs m $ Abs n $ App (App (Var n) lpred) (Var m)
194    where (m,n) = (0,1)
195
196ltrue = Abs 0 $ Abs 1 $ Var 0
197lfalse = Abs 0 $ Abs 1 $ Var 1
198
199liszero = Abs n $ App (App (Var n) (Abs x lfalse)) ltrue
200    where (n,x) = (0,1)
201
202land = Abs 0 $ Abs 1 $ App (App (Var 0) (Var 1)) (Var 1)
203lleq = Abs 0 $ Abs 1 $ App liszero $ App (App lsub (Var 0)) (Var 1)
204leq = 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
209test = Abs 0 $ Abs 1 $ App (App leq xpy) ypx
210xpy = App (App lplus (Var 0)) (Var 1)
211ypx = App (App lplus (Var 1)) (Var 0)
212
213smap  = Abs 5 $ AAbs 18 6 $ List (Var 18) (Abs 8$ App (Var 5) (App (Var 6) (Var 8)))
214conss = Abs 23 $ AAbs 19 5 $ List (Op (Num 1) '+' (Var 19)) $ Shift (Var 5) (Var 19)  (Abs 8 $ Var 23)
215addones = AAbs 19 5 $ List (Op (Num 1) '+' (Var 19)) (Abs 8 Unsized)
216nils = List (Num 0) (Abs 8 Bottom)
217lz n = List (Num n) (Abs 8 Unsized)
218srep n x = List (Num n) (Abs 8 x)
219dupfst = 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))
221yComb = 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))
223reverses = AAbs 18 5 $ List (Var 18) (Abs 8 $ App (Var 5) $ Op (Op (Var 18) '-' (Num 1)) '-' (Var 8) )
224reverse' l = case l of
225    [] -> []
226    (x:xs) -> x:reverse' xs
227appends = AAbs 18 5 $ AAbs 19 6 $ List (Op (Var 18) '+' (Var 19)) $ Shift (Var 6) (Var 19) (Var 5)
228
229headc = AAbs 18 5 $ App (Var 5) (Op (Var 18) '-' (Num 1))
230tailc = AAbs 18 5 $ List (Op (Var 18) '-' (Num 1)) (Var 5)
231rall = last . it reduce
232
233sheads = rall $ App smap headc
234stails = rall $ App smap tailc
Note: See TracBrowser for help on using the repository browser.