Guest User

Untitled

a guest
May 26th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. module ULC where
  2.  
  3. import Data.Set as S
  4. import Data.Map.Lazy as M
  5.  
  6. --untyped lambda calculus - variables are numbers now as it's easier for renaming
  7. data Term
  8. = Var Int
  9. | Abs Int Term
  10. | App Term Term
  11. deriving Ord
  12.  
  13. -- alpha equivalence of lambda terms as Eq instance for Lambda Terms
  14. instance Eq Term where
  15. a == b = checker (a, b) (M.empty, M.empty) 0
  16.  
  17. -- checks for equality of terms, has a map (term, id) for each variable
  18. -- each abstraction adds to the map and increments the id
  19. -- variable occurrence checks for ocurrences in t1 and t2 using the logic:
  20. -- if both bound, check that s is same in both maps
  21. -- if neither is bound, check literal equality
  22. -- if bound t1 XOR bound t2 == true then False
  23. -- application recursively checks both the LHS and RHS
  24. checker :: (Term, Term) -> (Map Int Int, Map Int Int) -> Int -> Bool
  25. checker (Var x, Var y) (m1, m2) s = case M.lookup x m1 of
  26. Just a -> case M.lookup y m2 of
  27. Just b -> a == b
  28. _ -> False
  29. _ -> x == y
  30. checker (Abs x t1, Abs y t2) (m1, m2) s =
  31. checker (t1, t2) (m1', m2') (s+1)
  32. where
  33. m1' = M.insert x s m1
  34. m2' = M.insert y s m2
  35. checker (App a1 b1, App a2 b2) c s =
  36. checker (a1, a2) c s && checker (b1, b2) c s
  37. checker _ _ _ = False
  38.  
  39. --Show instance TODO brackets convention
  40. instance Show Term where
  41. show (Var x) = show x
  42. show (App t1 t2) = '(':show t1 ++ ' ':show t2 ++ ")"
  43. show (Abs x t1) = '(':"\x03bb" ++ show x++ "." ++ show t1 ++ ")"
  44.  
  45. --bound variables of a term
  46. bound :: Term -> Set Int
  47. bound (Var n) = S.empty
  48. bound (Abs n t) = S.insert n $ bound t
  49. bound (App t1 t2) = S.union (bound t1) (bound t2)
  50.  
  51. --free variables of a term
  52. free :: Term -> Set Int
  53. free (Var n) = S.singleton n
  54. free (Abs n t) = S.delete n (free t)
  55. free (App t1 t2) = S.union (free t1) (free t2)
  56.  
  57. --test to see if a term is closed (has no free vars)
  58. closed :: Term -> Bool
  59. closed = S.null . free
  60.  
  61. --subterms of a term
  62. sub :: Term -> Set Term
  63. sub t@(Var x) = S.singleton t
  64. sub t@(Abs c t') = S.insert t $ sub t'
  65. sub t@(App t1 t2) = S.insert t $ S.union (sub t1) (sub t2)
  66.  
  67. --element is bound in a term
  68. notfree :: Int -> Term -> Bool
  69. notfree x = not . S.member x . free
  70.  
  71. --set of variables in a term
  72. vars :: Term -> Set Int
  73. vars (Var x) = S.singleton x
  74. vars (App t1 t2) = S.union (vars t1) (vars t2)
  75. vars (Abs x t1) = S.insert x $ vars t1
  76.  
  77. --generates a fresh variable name for a term
  78. newlabel :: Term -> Int
  79. newlabel = (+1) . maximum . vars
  80.  
  81. --rename t (x,y): renames free occurences of x in t to y
  82. rename :: Term -> (Int, Int) -> Term
  83. rename (Var a) (x,y) = if a == x then Var y else Var a
  84. rename t@(Abs a t') (x,y) = if a == x then t else Abs a $ rename t' (x, y)
  85. rename (App t1 t2) (x,y) = App (rename t1 (x,y)) (rename t2 (x,y))
  86.  
  87. --substitute one term for another in a term
  88. --does capture avoiding substitution
  89. substitute :: Term -> (Term, Term) -> Term
  90. substitute t1@(Var c1) (Var c2, t2)
  91. = if c1 == c2 then t2 else t1
  92. substitute (App t1 t2) c
  93. = App (substitute t1 c) (substitute t2 c)
  94. substitute (Abs y s) c@(Var x, t)
  95. | y == x = Abs y s
  96. | y `notfree` t = Abs y $ substitute s c
  97. | otherwise = Abs z $ substitute (rename s (y,z)) c
  98. where z = max (newlabel s) (newlabel t)
  99.  
  100. --eta reduction
  101. eta :: Term -> Maybe Term
  102. eta (Abs x (App t (Var y)))
  103. | x == y && x `notfree` t = Just t
  104. | otherwise = Nothing
  105.  
  106. --term is normal form if has no subterms of the form (\x.s) t
  107. isNormalForm :: Term -> Bool
  108. isNormalForm = not . any testnf . sub
  109. where
  110. testnf t = case t of
  111. (App (Abs _ _) _) -> True
  112. _ -> False
  113.  
  114. --one-step reduction relation
  115. reduce1 :: Term -> Maybe Term
  116. reduce1 t@(Var x) = Nothing
  117. reduce1 t@(Abs x s) = case reduce1 s of
  118. Just s' -> Just $ Abs x s'
  119. Nothing -> Nothing
  120. reduce1 t@(App (Abs x t1) t2)
  121. = Just $ substitute t1 (Var x, t2) --beta conversion
  122. reduce1 t@(App t1 t2) = case reduce1 t1 of
  123. Just t' -> Just $ App t' t2
  124. _ -> case reduce1 t2 of
  125. Just t' -> Just $ App t1 t'
  126. _ -> Nothing
  127.  
  128. --multi-step reduction relation - NOT GUARANTEED TO TERMINATE
  129. reduce :: Term -> Term
  130. reduce t = case reduce1 t of
  131. Just t' -> reduce t'
  132. Nothing -> t
  133.  
  134. ---multi-step reduction relation that accumulates all reduction steps
  135. reductions :: Term -> [Term]
  136. reductions t = case reduce1 t of
  137. Just t' -> t' : reductions t'
  138. _ -> []
  139.  
  140. --common combinators
  141. i = Abs 1 (Var 1)
  142. true = Abs 1 (Abs 2 (Var 1))
  143. false = Abs 1 (Abs 2 (Var 2))
  144. zero = false
  145. xx = Abs 1 (App (Var 1) (Var 1))
  146. omega = App xx xx
  147. _if = \c t f -> App (App c t) f
  148. _isZero = \n -> _if n false true
  149. _succ = Abs 0 $ Abs 1 $ Abs 2 $ App (Var 1) $ App (App (Var 0) (Var 1)) (Var 2)
  150. appsucc = App _succ
  151.  
  152. -- function from Haskell Int to Church Numeral
  153. toChurch :: Int -> Term
  154. toChurch n = Abs 0 (Abs 1 (toChurch' n))
  155. where
  156. toChurch' 0 = Var 1
  157. toChurch' n = App (Var 0) (toChurch' (n-1))
  158.  
  159. test1 = App i (Abs 1 (App (Var 1) (Var 1)))
  160. test2 = App (App (Abs 1 (Abs 2 (Var 2))) (Var 2)) (Var 4)
  161. test3 = App (App (toChurch 3) (Abs 0 (App (Var 0) (toChurch 2)))) (toChurch 1)
Add Comment
Please, Sign In to add comment