Guest User

Untitled

a guest
Jun 18th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.49 KB | None | 0 0
  1. (* Basic lambda calculus definition, printing and evaluation. *)
  2.  
  3. (* ocamlc lambda.ml -o lambda *)
  4.  
  5. type lambda =
  6. | Var of string
  7. | Lam of string * lambda
  8. | App of lambda * lambda;;
  9.  
  10. module Free = Set.Make(String);;
  11.  
  12. (* Turn a lambda expression into a human-readable string *)
  13. let rec print_lambda = function
  14. | Var x -> x
  15. | Lam (var, lambda) -> String.concat "" ["(\\"; var; "."; (print_lambda lambda); ")"]
  16. | App (l1, l2) -> String.concat "" [(print_lambda l1); " "; (print_lambda l2)]
  17.  
  18. (* Compute the set of unbound variables in a given lambda expression *)
  19. let rec free_variables lambda =
  20. let rec inner lambda bound_vars =
  21. match lambda with
  22. | Var x -> if Free.mem x bound_vars then Free.empty else Free.singleton x
  23. | Lam (var, lambda) -> inner lambda (Free.add var bound_vars)
  24. | App (l1, l2) -> Free.union (inner l1 bound_vars) (inner l2 bound_vars)
  25. in
  26. inner lambda Free.empty
  27.  
  28. (* Turn a set of unbound variables into a human-readable string *)
  29. let print_free vars = String.concat ", " (Free.elements vars)
  30.  
  31. (* Substitutes a lambda expression for a variable in a given expression. *)
  32. let rec substitute lambda var expr =
  33. match lambda with
  34. | Var x -> if x = var then expr else Var x
  35. | Lam (x, inner) -> if x = var then Lam (x, inner) else Lam (x, substitute inner var expr)
  36. | App (l1, l2) -> App (substitute l1 var expr, substitute l2 var expr)
  37.  
  38. (* Beta-reduce a lambda expression in a given environment of variable bindings *)
  39. let rec reduce = function
  40. | Var x -> Var x
  41. | App (l1, l2) ->
  42. (match l1 with
  43. | Lam (var, lambda) ->
  44. substitute lambda var l2
  45. | something_else ->
  46. App (reduce something_else, l2))
  47. | Lam (var, lambda) -> Lam (var, lambda)
  48.  
  49. (* Beta-reduce a lambda expression a given number of times with no prior variable
  50. bindings *)
  51. let rec reduce_n lambda n =
  52. if n = 0 then lambda else
  53. reduce_n (reduce lambda) (n - 1)
  54.  
  55. (* Display the results of each stage of beta-reducing a lambda expression. Used
  56. for debugging. *)
  57. let display_n_stages lambda n = begin
  58. print_string "Evaluating expression: ";
  59. print_string (print_lambda lambda);
  60. print_string "\n";
  61.  
  62. for iteration = 1 to n do
  63. print_string "Iteration ";
  64. print_int iteration;
  65. print_string ": ";
  66. print_string (print_lambda (reduce_n lambda iteration));
  67. print_string "\n";
  68. done
  69. end
  70.  
  71. (* Beta-reduce a lambda expression until it can't be reduced any further *)
  72. let rec eval lambda =
  73. let lambda' = reduce lambda in
  74. if lambda = lambda' then lambda
  75. else eval lambda'
  76.  
  77. (* Testing things. *)
  78. let x_id = Lam ("x", Var "x")
  79. let y_id = Lam ("y", Var "y")
  80. let swap_f_g = Lam ("f", (Lam ("g", (App ((Var "g"), (Var "f"))))))
  81. (* (\f.(\g.g f)) (\x.x) (\y.y) *)
  82. let swap_ids = App (App(swap_f_g, x_id), y_id)
  83.  
  84. (* (\f.(\g.g f)) y x
  85. Free vars: x, y *)
  86. let mess_of_frees = App ((App (swap_f_g, (Var "y"))), (Var "x"))
  87.  
  88. (* Construct a swap lambda which doesn't work without alpha conversion.
  89. (\x.(\y.y x)) (\y.y) (\x.x) *)
  90. let swap_x_y = Lam ("x", (Lam ("y", (App ((Var "y"), (Var "x"))))))
  91. let swap_ids_pre_alpha = App (App(swap_x_y, y_id), x_id)
  92. ;;
  93.  
  94. print_string "Free var computation for ";
  95. print_string (print_lambda mess_of_frees);
  96. print_string "\n";
  97. print_string (print_free (free_variables mess_of_frees));
  98. print_string "\n\n";
  99. display_n_stages swap_ids 3;
  100. print_string "\n";
  101. display_n_stages swap_ids_pre_alpha 3;
  102. print_string "\n";
  103. print_string "Evaluating lambda: ";
  104. print_string (print_lambda swap_ids_pre_alpha);
  105. print_string "\n";
  106. print_string "Result: ";
  107. print_string (print_lambda (eval swap_ids_pre_alpha));
  108. ;;
Add Comment
Please, Sign In to add comment