Guest User

Untitled

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