-
Notifications
You must be signed in to change notification settings - Fork 0
/
d.ml
82 lines (67 loc) · 4.43 KB
/
d.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
open Tree;;
let rec write_to_string expression =
let token = expression in
match token with
| Application (a,b) -> "(" ^ (write_to_string a) ^ " " ^ (write_to_string b) ^ ")"
| Abstraction (a,b) -> (String.concat "" ["(\\";a;"."]) ^ (write_to_string b) ^ ")"
| Variable(a) -> a;;
let s = Abstraction("f", Abstraction("g", Abstraction("x", Application(Application(Variable "f", Variable "x"), Application(Variable "g", Variable "x")))));;
let k = Abstraction("a", Abstraction("b", Variable "a"));;
let rec pretty_print expression =
match expression with
| Abstraction("f", Abstraction("g", Abstraction("x", Application(Application(Variable "f", Variable "x"), Application(Variable "g", Variable "x"))))) -> "s"
| Abstraction("a", Abstraction("b", Variable "a")) -> "k"
| Application(a, b) -> let left = pretty_print a in
let right = pretty_print b in
String.concat " " ["(" ^ left; right ^ ")"]
| Variable(a) -> a
| Abstraction(a, b) -> (String.concat "" ["(\\";a;"."]) ^ (pretty_print b) ^ ")"
;;
let is_combinator exp =
match exp with
| Abstraction(f, Abstraction(g, Abstraction(x, Application(Application(Variable f1, Variable x1), Application(Variable g1, Variable x2))))) ->
if (f = f1) && (g = g1) && (x = x1 && x = x2 && x1 = x2) then
true
else
false
| Abstraction(a, Abstraction(b, Variable a1)) -> if a = a1 then
true
else
false
| _ -> false
;;
let rec f_tunc expression =
match expression with
| Variable (x) -> Variable x
| Application (a, b) -> let left_ok = if is_combinator a then a else f_tunc a in
let right_ok = if is_combinator b then b else f_tunc b in
Application(left_ok, right_ok)
| Abstraction (x, Abstraction(y, p)) -> if is_combinator (Abstraction(y, p)) then
Application (k, Abstraction(y, p))
else
begin
let inner = Abstraction (y, p) in
let inner_ok = if is_combinator inner then inner else f_tunc inner in
let result = Abstraction (x, inner_ok) in
let result_ok = if is_combinator result then result else f_tunc result in
result_ok
end
| Abstraction (x, Variable y) -> if x = y then
begin
Application(Application(s, k), k)
end
else
begin
Application (k, Variable y)
end
| Abstraction (x, Application(p, q)) -> let left = Abstraction (x, p) in
let right = Abstraction (x, q) in
let left_ok = if is_combinator left then left else f_tunc left in
let right_ok = if is_combinator right then right else f_tunc right in
Application (Application (s, left_ok), right_ok)
| Abstraction (x, p) -> let inner = if is_combinator p then p else f_tunc p in
Application (k, inner)
;;
let b = Lexing.from_channel stdin;;
let d = (Parser.lambdaParser Lexer.main) b;;
print_string (pretty_print (f_tunc d));;