Advertisement
elvecent

HaskellLambda

Jun 10th, 2017
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.List
  2.  
  3. prelude = map (\(a,b) -> (a,parse b))
  4.              [("if", "\\f.\\x.\\y.f x y"),
  5.               ("true", "\\x.\\y.x"),
  6.               ("false", "\\x.\\y.y"),
  7.               ("and", "\\a.\\b.a b false"),
  8.               ("or", "\\a.\\b.a true b"),
  9.               ("not", "\\a.a false true"),
  10.               ("fst", "\\p.p true"),
  11.               ("snd", "\\p.p false"),
  12.               ("pair", "\\x.\\y.\\f.f x y"),
  13.               ("nil", "pair true true"),
  14.               ("isnil", "fst"),
  15.               ("cons", "\\h.\\t.pair false (pair h t)"),
  16.               ("head", "\\z.fst (snd z)"),
  17.               ("tail", "\\z.snd (snd z)"),
  18.               ("zero", "\\f.\\x.x"),
  19.               ("succ", "\\n.\\f.\\x.f (n f x)"),
  20.               ("plus", "\\n.\\m.\\f.\\x.n f (m f x)"),
  21.               ("fix", "\\f.(\\x.f (x x)) (\\x.f (x x))")]
  22.        
  23. main = main' prelude
  24.      
  25. main' ctx = do
  26.             line <- getLine
  27.             let declFlag = ('=' `elem` line)
  28.             let (ctx', line') = let (ident, rest) = biteId line
  29.                                     term = tail $ tail rest in
  30.                                 if declFlag
  31.                                 then (updateCtx ctx ident (parse term), term)
  32.                                 else (ctx, line)
  33.             putStrLn $ "=> " ++ (show $ (if declFlag then id else eval ctx') $ parse line')
  34.             main' ctx'
  35.  
  36. data Lexp = Var String
  37.           | App Lexp Lexp
  38.           | Lambda String Lexp
  39.           deriving Eq
  40.          
  41. instance Show Lexp where
  42.   show (Var x) = x
  43.   show (App l1 (l@(App l2 l3))) = show l1 ++ " (" ++ (show l) ++ ")"
  44.   show (App l1 l2) = show l1 ++ " " ++ (show l2)
  45.   show (Lambda x l) = "(" ++ "λ" ++ args ++ "." ++ (show body) ++ ")"
  46.                       where (vars, body) = unlambda (Lambda x l)
  47.                             args = concat $ intersperse " " vars
  48.  
  49. type Context = [(String, Lexp)]
  50.  
  51. updateCtx :: Context -> String -> Lexp -> Context
  52. updateCtx xs s l = (s,l) : xs
  53.  
  54. getFromCtx :: Context -> String -> Lexp
  55. getFromCtx [] s = error $ s ++ " not found in context"
  56. getFromCtx (x:xs) s = if (fst x == s) then snd x else getFromCtx xs s
  57.  
  58. alphanumeric :: Char -> Bool
  59. alphanumeric c = c `elem` ['a'..'z'] || c `elem` ['0'..'9']
  60.  
  61. biteId :: String -> (String, String)
  62. biteId s = if (null $ fst res) then error "Identifier expected" else res
  63.            where res = break (\c -> not $ alphanumeric c) s
  64.  
  65. biteBrackets :: String -> (String, String)
  66. biteBrackets ('(' : s) = helper [] s 1
  67.                          where helper acc rest 0 = (reverse $ tail acc, rest)
  68.                                helper acc ('(' : r) n = helper ('(' : acc) r (n+1)
  69.                                helper acc (')' : r) n = helper (')' : acc) r (n-1)
  70.                                helper acc (c : r) n = helper (c : acc) r n
  71.                                helper acc [] _ = error "Brackets mismatch"
  72.  
  73. bite :: String -> (String, String)
  74. bite ('(' : s) = biteBrackets ('(' : s)
  75. bite s = biteId s
  76.  
  77. cut :: String -> [String]
  78. cut [] = []
  79. cut s = bit : (cut $ dropWhile (== ' ') rest)
  80.         where (bit, rest) = bite s
  81.  
  82. parse :: String -> Lexp
  83. parse [] = error "Empty query"
  84. parse (' ' : s) = parse s
  85. parse ('\\' : s) = if (null rest || (head rest /= '.'))
  86.                    then error "Point after lambda expected"
  87.                    else Lambda ident (parse $ tail rest)
  88.                    where (ident, rest) = biteId s
  89.  
  90. parse s = if (null(tail $ cut s) && head s /= '(')
  91.           then Var $ fst $ biteId s
  92.           else apply $ map parse (cut s)
  93.           where apply (l : []) = l
  94.                 apply (f : x : ls) = apply $ App f x : ls
  95.                
  96. remove :: Eq a => a -> [a] -> [a]
  97. remove _ [] = []
  98. remove x (y:ys) = if (x == y) then remove x ys else y : (remove x ys)
  99.                
  100. freevars :: Lexp -> [String]
  101. freevars (Var x) = [x]
  102. freevars (App l1 l2) = freevars l1 ++ (freevars l2)
  103. freevars (Lambda x l) = remove x (freevars l)
  104.                
  105. substitute :: Lexp -> String -> Lexp -> Lexp
  106. substitute (Var x) y l = if (x == y) then l else (Var x)
  107. substitute (App l1 l2) x l = App (substitute l1 x l) (substitute l2 x l)
  108. substitute (Lambda x l1) y l2 = if (x == y)
  109.                                 then (Lambda x l1)
  110.                                 else if (x `elem` (freevars l2))
  111.                                      then Lambda x' $ substitute (substitute l1 x (Var x')) y l2
  112.                                      else Lambda x $ substitute l1 y l2
  113.                                 where x' = x ++ "'"
  114.                                
  115. reduce :: Lexp -> Lexp
  116. reduce (Var x) = Var x
  117. reduce (App (Lambda x l1) l2) = substitute l1 x l2
  118. reduce (App l1 l2) = App (reduce l1) (reduce l2)
  119. reduce (Lambda x l) = Lambda x (reduce l)
  120.  
  121. beta :: Lexp -> Lexp
  122. beta l = if (normal l) then l else (beta $ reduce l)
  123.  
  124. normal :: Lexp -> Bool
  125. normal (Var _) = True
  126. normal (App (Lambda _ _) _) = False
  127. normal (App f x) = normal f && (normal x)
  128. normal (Lambda _ fx) = normal fx
  129.  
  130. eval :: Context -> Lexp -> Lexp
  131. eval ctx l = if (null fv)
  132.             then beta l
  133.             else eval ctx $ foldl (\e v -> substitute e v (getFromCtx ctx v)) l (nub fv)
  134.             where fv = freevars l
  135.                
  136. unlambda :: Lexp -> ([String], Lexp)
  137. unlambda (Lambda x l) = (x : vars, rest)
  138.                        where (vars, rest) = unlambda l
  139. unlambda l = ([], l)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement