[5] | 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 |
---|
[6] | 14 | | Shift L L L | Unsized | Bottom |
---|
[5] | 15 | deriving Eq |
---|
| 16 | |
---|
| 17 | showVar x = if x>28 |
---|
[6] | 18 | then showVar (x `div` 29) . showChar (chr $ ord 'a' + (x `mod` 29)) |
---|
[5] | 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) |
---|
[6] | 26 | getPrec c = error $ "Unknown operator "++[c] |
---|
[5] | 27 | |
---|
| 28 | instance Show L where |
---|
[6] | 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 |
---|
[5] | 31 | showsPrec p (App m n) = showParen (p>6) $ showsPrec 6 m . showChar ' ' . showsPrec 7 n |
---|
[6] | 32 | showsPrec _ (Var s) = showVar s |
---|
| 33 | showsPrec _ (Num i) = shows i |
---|
[5] | 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 |
---|
[6] | 39 | showsPrec _ Bottom = showChar 'âŽ' |
---|
| 40 | showsPrec _ Unsized = showChar 'U' |
---|
[5] | 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) |
---|
[6] | 56 | subs x@(Num _) _ _ = x |
---|
| 57 | subs x@Bottom _ _ = x |
---|
| 58 | subs x@Unsized _ _ = x |
---|
[5] | 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 |
---|
[6] | 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) |
---|
[5] | 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 |
---|
[6] | 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) |
---|
[5] | 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 |
---|
[6] | 96 | fv (Num _) = Set.empty |
---|
[5] | 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 | |
---|
[6] | 101 | bv (Var _) = Set.empty |
---|
[5] | 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 |
---|
[6] | 108 | bv (Num _) = Set.empty |
---|
[5] | 109 | bv Unsized = Set.empty |
---|
| 110 | bv Bottom = Set.empty |
---|
| 111 | |
---|
| 112 | maxv (Var x) = x |
---|
[6] | 113 | maxv (Num _) = 0 |
---|
[5] | 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 |
---|
[6] | 125 | dvar = fv exp `Set.intersection` bv oexp |
---|
[5] | 126 | m = maxv exp `max` maxv oexp |
---|
| 127 | renames = zip (Set.toList dvar) [m+1..] |
---|
| 128 | renamed = foldr rename oexp renames |
---|
[6] | 129 | rename (from,to) _ = alpha oexp from to |
---|
[5] | 130 | |
---|
[6] | 131 | |
---|
[5] | 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 |
---|
[6] | 171 | it' _ Nothing = [] |
---|
[5] | 172 | it' f (Just x) = x:it' f (f x) |
---|
| 173 | |
---|
| 174 | rchain :: L -> [L] |
---|
[6] | 175 | rchain = it reduce |
---|
[5] | 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 | |
---|
[6] | 199 | liszero = Abs n $ App (App (Var n) (Abs x lfalse)) ltrue |
---|
[5] | 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 |
---|