-
Notifications
You must be signed in to change notification settings - Fork 0
/
lambda_calculus.rb
88 lines (71 loc) · 1.42 KB
/
lambda_calculus.rb
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
83
84
85
86
87
class LCVariable < Struct.new(:name)
def to_s
name.to_s
end
def inspect
to_s
end
def callable?
false
end
def reducible?
false
end
def replace(name, replacement)
if self.name == name
replacement
else
self
end
end
end
class LCFunction < Struct.new(:parameter, :body)
def to_s
"-> #{parameter} { #{body} }"
end
def inspect
to_s
end
def reducible?
false
end
def callable?
true
end
def replace(name, replacement)
if parameter == name
self
else
LCFunction.new(parameter, body.replace(name, replacement))
end
end
def call(argument)
body.replace(parameter, argument)
end
end
class LCCall < Struct.new(:left, :right)
def to_s
"#{left}[#{right}]"
end
def inspect
to_s
end
def reducible?
left.reducible? || right.reducible? || left.callable?
end
def callable?
false
end
def reduce
if left.reducible?
LCCall.new(left.reduce, right)
elsif right.reducible?
LCCall.new(left, right.reduce)
else
left.call(right)
end
end
def replace(name, replacement)
LCCall.new(left.replace(name, replacement), right.replace(name, replacement))
end
end