mini_kraken 0.2.02 → 0.2.03
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +3 -3
- data/lib/mini_kraken.rb +0 -1
- data/lib/mini_kraken/core/conde.rb +1 -1
- data/lib/mini_kraken/core/conj2.rb +3 -3
- data/lib/mini_kraken/core/cons_cell_visitor.rb +102 -0
- data/lib/mini_kraken/core/def_relation.rb +3 -0
- data/lib/mini_kraken/core/disj2.rb +2 -2
- data/lib/mini_kraken/core/environment.rb +1 -1
- data/lib/mini_kraken/core/equals.rb +59 -22
- data/lib/mini_kraken/core/goal_template.rb +42 -2
- data/lib/mini_kraken/core/k_boolean.rb +1 -1
- data/lib/mini_kraken/core/outcome.rb +11 -1
- data/lib/mini_kraken/core/variable_ref.rb +6 -0
- data/lib/mini_kraken/core/vocabulary.rb +6 -2
- data/lib/mini_kraken/glue/dsl.rb +17 -8
- data/lib/mini_kraken/glue/fresh_env.rb +31 -3
- data/lib/mini_kraken/glue/fresh_env_factory.rb +83 -0
- data/lib/mini_kraken/glue/run_star_expression.rb +2 -2
- data/lib/mini_kraken/version.rb +1 -1
- data/spec/core/conde_spec.rb +9 -9
- data/spec/core/conj2_spec.rb +7 -7
- data/spec/core/cons_cell_visitor_spec.rb +144 -0
- data/spec/core/def_relation_spec.rb +6 -5
- data/spec/core/disj2_spec.rb +5 -5
- data/spec/core/duck_fiber_spec.rb +1 -1
- data/spec/core/equals_spec.rb +34 -21
- data/spec/core/goal_spec.rb +2 -2
- data/spec/core/outcome_spec.rb +8 -0
- data/spec/core/variable_ref_spec.rb +3 -0
- data/spec/glue/dsl_chap1_spec.rb +10 -2
- data/spec/glue/dsl_chap2_spec.rb +100 -0
- data/spec/glue/fresh_env_factory_spec.rb +97 -0
- data/spec/glue/run_star_expression_spec.rb +3 -2
- metadata +10 -2
@@ -17,6 +17,7 @@ require_relative '../../lib/mini_kraken/core/def_relation'
|
|
17
17
|
module MiniKraken
|
18
18
|
module Core
|
19
19
|
describe DefRelation do
|
20
|
+
# (defrel (teao t) (== 'tea t))
|
20
21
|
let(:tea) { KSymbol.new(:tea) }
|
21
22
|
let(:formal_t) { FormalArg.new('t') }
|
22
23
|
let(:t_ref) { FormalRef.new('t') }
|
@@ -53,13 +54,13 @@ module MiniKraken
|
|
53
54
|
defrel = DefRelation.new('teao', equals_tea, [formal_t])
|
54
55
|
solver = defrel.solver_for([tea], env)
|
55
56
|
outcome = solver.resume
|
56
|
-
expect(outcome).to
|
57
|
+
expect(outcome).to be_success
|
57
58
|
outcome = solver.resume
|
58
59
|
expect(outcome).to be_nil
|
59
60
|
|
60
61
|
solver = defrel.solver_for([cup], env)
|
61
62
|
outcome = solver.resume
|
62
|
-
expect(outcome).not_to
|
63
|
+
expect(outcome).not_to be_success
|
63
64
|
outcome = solver.resume
|
64
65
|
expect(outcome).to be_nil
|
65
66
|
end
|
@@ -69,7 +70,7 @@ module MiniKraken
|
|
69
70
|
env.add_var(Variable.new('x'))
|
70
71
|
solver = defrel.solver_for([ref_x], env)
|
71
72
|
outcome = solver.resume
|
72
|
-
expect(outcome).to
|
73
|
+
expect(outcome).to be_success
|
73
74
|
expect(ref_x.value(outcome)).to eq(tea)
|
74
75
|
|
75
76
|
outcome = solver.resume
|
@@ -80,11 +81,11 @@ module MiniKraken
|
|
80
81
|
env.add_var(Variable.new('x'))
|
81
82
|
solver = subject.solver_for([ref_x], env)
|
82
83
|
outcome = solver.resume
|
83
|
-
expect(outcome).to
|
84
|
+
expect(outcome).to be_success
|
84
85
|
expect(ref_x.value(outcome)).to eq(tea)
|
85
86
|
|
86
87
|
outcome = solver.resume
|
87
|
-
expect(outcome).to
|
88
|
+
expect(outcome).to be_success
|
88
89
|
expect(ref_x.value(outcome)).to eq(cup)
|
89
90
|
|
90
91
|
outcome = solver.resume
|
data/spec/core/disj2_spec.rb
CHANGED
@@ -52,7 +52,7 @@ module MiniKraken
|
|
52
52
|
it 'should fails if both arguments fail' do
|
53
53
|
# Covers frame 1:55
|
54
54
|
solver = subject.solver_for([fails, fails], env)
|
55
|
-
expect(solver.resume).not_to
|
55
|
+
expect(solver.resume).not_to be_success
|
56
56
|
expect(solver.resume).to be_nil
|
57
57
|
end
|
58
58
|
|
@@ -61,7 +61,7 @@ module MiniKraken
|
|
61
61
|
subgoal = Goal.new(Equals.instance, [olive, ref_q])
|
62
62
|
solver = subject.solver_for([subgoal, fails], env)
|
63
63
|
outcome = solver.resume
|
64
|
-
expect(outcome).to
|
64
|
+
expect(outcome).to be_success
|
65
65
|
expect(outcome.associations['q'].first.value).to eq(olive)
|
66
66
|
expect(solver.resume).to be_nil
|
67
67
|
end
|
@@ -71,7 +71,7 @@ module MiniKraken
|
|
71
71
|
subgoal = Goal.new(Equals.instance, [oil, ref_q])
|
72
72
|
solver = subject.solver_for([fails, subgoal], env)
|
73
73
|
outcome = solver.resume
|
74
|
-
expect(outcome).to
|
74
|
+
expect(outcome).to be_success
|
75
75
|
expect(outcome.associations['q'].first.value).to eq(oil)
|
76
76
|
expect(solver.resume).to be_nil
|
77
77
|
end
|
@@ -84,12 +84,12 @@ module MiniKraken
|
|
84
84
|
|
85
85
|
# First solution
|
86
86
|
outcome1 = solver.resume
|
87
|
-
expect(outcome1).to
|
87
|
+
expect(outcome1).to be_success
|
88
88
|
expect(outcome1.associations['q'].first.value).to eq(olive)
|
89
89
|
|
90
90
|
# Second solution
|
91
91
|
outcome2 = solver.resume
|
92
|
-
expect(outcome2).to
|
92
|
+
expect(outcome2).to be_success
|
93
93
|
expect(outcome2.associations['q'].first.value).to eq(oil)
|
94
94
|
expect(solver.resume).to be_nil
|
95
95
|
end
|
@@ -40,7 +40,7 @@ module MiniKraken
|
|
40
40
|
succeeding = DuckFiber.new(:success)
|
41
41
|
outcome = nil
|
42
42
|
expect { outcome = succeeding.resume }.not_to raise_error
|
43
|
-
expect(outcome).to
|
43
|
+
expect(outcome).to be_success
|
44
44
|
expect(outcome.parent).to be_nil
|
45
45
|
|
46
46
|
# Only one result should be yielded
|
data/spec/core/equals_spec.rb
CHANGED
@@ -106,7 +106,7 @@ module MiniKraken
|
|
106
106
|
it 'should succeed for a right-handed fresh argument' do
|
107
107
|
result = solve_for(pea, ref_q)
|
108
108
|
|
109
|
-
expect(result).to
|
109
|
+
expect(result).to be_success
|
110
110
|
expect(env.associations.size).to eq(1)
|
111
111
|
expect(env.associations['q'].first.value).to eq(pea)
|
112
112
|
expect(var_q.fresh?(result)).to be_falsey
|
@@ -116,7 +116,7 @@ module MiniKraken
|
|
116
116
|
it 'should succeed for a left-handed fresh argument' do
|
117
117
|
result = solve_for(ref_q, pea)
|
118
118
|
|
119
|
-
expect(result).to
|
119
|
+
expect(result).to be_success
|
120
120
|
expect(env.associations.size).to eq(1)
|
121
121
|
expect(env.associations['q'].first.value).to eq(pea)
|
122
122
|
expect(var_q.fresh?(result)).to be_falsey
|
@@ -127,7 +127,7 @@ module MiniKraken
|
|
127
127
|
ref_q.associate(pod, env)
|
128
128
|
|
129
129
|
result = solve_for(pod, ref_q)
|
130
|
-
expect(result).to
|
130
|
+
expect(result).to be_success
|
131
131
|
expect(env.associations.size).to eq(1) # No new association
|
132
132
|
expect(ref_q.fresh?(result)).not_to be_truthy
|
133
133
|
expect(ref_q.values(result).first).to eq(pod)
|
@@ -137,7 +137,7 @@ module MiniKraken
|
|
137
137
|
ref_q.associate(pod, env)
|
138
138
|
|
139
139
|
result = solve_for(ref_q, pod)
|
140
|
-
expect(result).to
|
140
|
+
expect(result).to be_success
|
141
141
|
expect(result.associations).to be_empty
|
142
142
|
expect(ref_q.fresh?(result)).to be_falsey
|
143
143
|
expect(ref_q.values(result).first).to eq(pod)
|
@@ -147,7 +147,7 @@ module MiniKraken
|
|
147
147
|
ref_q.associate(pod, env)
|
148
148
|
|
149
149
|
result = solve_for(pea, ref_q)
|
150
|
-
expect(result).not_to
|
150
|
+
expect(result).not_to be_success
|
151
151
|
expect(result.associations).to be_empty
|
152
152
|
expect(ref_q.fresh?(result)).to be_falsey
|
153
153
|
expect(ref_q.values(result).first).to eq(pod)
|
@@ -157,7 +157,7 @@ module MiniKraken
|
|
157
157
|
ref_q.associate(pod, env)
|
158
158
|
|
159
159
|
result = solve_for(ref_q, pea)
|
160
|
-
expect(result).not_to
|
160
|
+
expect(result).not_to be_success
|
161
161
|
expect(result.associations).to be_empty
|
162
162
|
expect(ref_q.fresh?(result)).to be_falsey
|
163
163
|
expect(ref_q.values(result).first).to eq(pod)
|
@@ -166,7 +166,7 @@ module MiniKraken
|
|
166
166
|
it 'should succeed for a composite and right-handed fresh argument' do
|
167
167
|
result = solve_for(sample_cons, ref_q)
|
168
168
|
|
169
|
-
expect(result).to
|
169
|
+
expect(result).to be_success
|
170
170
|
expect(env.associations.size).to eq(1)
|
171
171
|
expect(ref_q.fresh?(result)).to be_falsey
|
172
172
|
expect(ref_q.values(result).first).to eq(sample_cons)
|
@@ -175,7 +175,7 @@ module MiniKraken
|
|
175
175
|
it 'should succeed for composite and left-handed fresh argument' do
|
176
176
|
result = solve_for(ref_q, sample_cons)
|
177
177
|
|
178
|
-
expect(result).to
|
178
|
+
expect(result).to be_success
|
179
179
|
expect(env.associations.size).to eq(1)
|
180
180
|
expect(ref_q.fresh?(result)).to be_falsey
|
181
181
|
expect(ref_q.values(result).first).to eq(sample_cons)
|
@@ -186,7 +186,7 @@ module MiniKraken
|
|
186
186
|
composite = ConsCell.new(pea)
|
187
187
|
result = solve_for(composite, ref_q)
|
188
188
|
|
189
|
-
expect(result).to
|
189
|
+
expect(result).to be_success
|
190
190
|
expect(result.associations).to be_empty
|
191
191
|
expect(ref_q.fresh?(result)).not_to be_truthy
|
192
192
|
expect(ref_q.values(result).first).to eq(sample_cons)
|
@@ -197,7 +197,7 @@ module MiniKraken
|
|
197
197
|
composite = ConsCell.new(pea)
|
198
198
|
result = solve_for(ref_q, composite)
|
199
199
|
|
200
|
-
expect(result).to
|
200
|
+
expect(result).to be_success
|
201
201
|
expect(result.associations).to be_empty
|
202
202
|
expect(ref_q.fresh?(result)).not_to be_truthy
|
203
203
|
expect(ref_q.values(result).first).to eq(sample_cons)
|
@@ -208,7 +208,7 @@ module MiniKraken
|
|
208
208
|
composite = ConsCell.new(pod)
|
209
209
|
result = solve_for(composite, ref_q)
|
210
210
|
|
211
|
-
expect(result).
|
211
|
+
expect(result).to be_failure
|
212
212
|
expect(result.associations).to be_empty
|
213
213
|
expect(ref_q.fresh?(result)).not_to be_truthy
|
214
214
|
expect(ref_q.values(result).first).to eq(sample_cons)
|
@@ -219,7 +219,7 @@ module MiniKraken
|
|
219
219
|
composite = ConsCell.new(pod)
|
220
220
|
result = solve_for(ref_q, composite)
|
221
221
|
|
222
|
-
expect(result).not_to
|
222
|
+
expect(result).not_to be_success
|
223
223
|
expect(result.associations).to be_empty
|
224
224
|
expect(ref_q.fresh?(result)).not_to be_truthy
|
225
225
|
expect(ref_q.values(result).first).to eq(sample_cons)
|
@@ -228,7 +228,7 @@ module MiniKraken
|
|
228
228
|
it 'should succeed for both identical fresh arguments' do
|
229
229
|
result = solve_for(ref_q, ref_q)
|
230
230
|
|
231
|
-
expect(result).to
|
231
|
+
expect(result).to be_success
|
232
232
|
expect(result.associations).to be_empty
|
233
233
|
expect(ref_q.fresh?(result)).to be_truthy
|
234
234
|
end
|
@@ -236,7 +236,7 @@ module MiniKraken
|
|
236
236
|
it 'should succeed for both same fresh arguments' do
|
237
237
|
result = solve_for(ref_q, ref_q_bis)
|
238
238
|
|
239
|
-
expect(result).to
|
239
|
+
expect(result).to be_success
|
240
240
|
expect(result.associations).to be_empty
|
241
241
|
expect(ref_q.fresh?(result)).to be_truthy
|
242
242
|
expect(ref_q_bis.fresh?(result)).to be_truthy
|
@@ -245,7 +245,7 @@ module MiniKraken
|
|
245
245
|
it 'should succeed for both distinct fresh arguments' do
|
246
246
|
result = solve_for(ref_x, ref_y)
|
247
247
|
|
248
|
-
expect(result).to
|
248
|
+
expect(result).to be_success
|
249
249
|
expect(env.associations).to be_empty # Symmetric association
|
250
250
|
expect(ref_x.fresh?(result)).to be_truthy
|
251
251
|
expect(ref_y.fresh?(result)).to be_truthy
|
@@ -258,7 +258,7 @@ module MiniKraken
|
|
258
258
|
expect(ref_y.fresh?(env)).to be_falsey
|
259
259
|
|
260
260
|
result = solve_for(ref_x, ref_y)
|
261
|
-
expect(result).to
|
261
|
+
expect(result).to be_success
|
262
262
|
expect(result.associations).to be_empty
|
263
263
|
end
|
264
264
|
|
@@ -269,19 +269,20 @@ module MiniKraken
|
|
269
269
|
expect(ref_y.fresh?(env)).to be_falsey
|
270
270
|
|
271
271
|
result = solve_for(ref_x, ref_y)
|
272
|
-
expect(result).not_to
|
272
|
+
expect(result).not_to be_success
|
273
273
|
expect(result.associations).to be_empty
|
274
274
|
end
|
275
275
|
|
276
276
|
it 'should unify composite terms with variables' do
|
277
277
|
# Reasoned S2, frame 1:36
|
278
278
|
# (run* q (fresh (x) (== '(((,q)) ,x) `(((,x)) pod)))) ;; => ('pod)
|
279
|
-
expr1 = cons(cons(cons(ref_q)), ref_x)
|
280
|
-
|
279
|
+
expr1 = cons(cons(cons(ref_q)), cons(ref_x))
|
280
|
+
expect(expr1.to_s).to eq('(((q)) x)')
|
281
|
+
expr2 = cons(cons(cons(ref_x)), cons(pod))
|
282
|
+
expect(expr2.to_s).to eq('(((x)) :pod)')
|
281
283
|
|
282
284
|
result = solve_for(expr1, expr2)
|
283
|
-
|
284
|
-
expect(result).to be_successful
|
285
|
+
expect(result).to be_success
|
285
286
|
expect(ref_x.fresh?(env)).to be_falsey
|
286
287
|
expect(ref_q.fresh?(env)).to be_falsey
|
287
288
|
end
|
@@ -298,6 +299,18 @@ module MiniKraken
|
|
298
299
|
expect(result.resultant).to eq(:"#u")
|
299
300
|
expect(result.associations).to be_empty
|
300
301
|
end
|
302
|
+
|
303
|
+
it 'should unify variables with a list' do
|
304
|
+
# Variant of Reasoned S2, frame 2:3
|
305
|
+
# (== (cons q x) '(a c o r n)) ;; q => :a, x => '(c o r n)
|
306
|
+
expr1 = cons(ref_q, ref_x)
|
307
|
+
acorn = cons(k_symbol(:a), cons(k_symbol(:c),
|
308
|
+
cons(k_symbol(:o), cons(k_symbol(:r), cons(k_symbol(:n))))))
|
309
|
+
result = solve_for(expr1, acorn)
|
310
|
+
expect(result.resultant).to eq(:"#s")
|
311
|
+
q_value = env.associations['q'].first.value
|
312
|
+
expect(q_value).to eq(:a)
|
313
|
+
end
|
301
314
|
end # context
|
302
315
|
end # describe
|
303
316
|
end # module
|
data/spec/core/goal_spec.rb
CHANGED
@@ -40,7 +40,7 @@ module MiniKraken
|
|
40
40
|
context 'Provided services:' do
|
41
41
|
it 'should fail if relation does not succeed' do
|
42
42
|
solver = subject.attain(env)
|
43
|
-
expect(solver.resume).not_to
|
43
|
+
expect(solver.resume).not_to be_success
|
44
44
|
|
45
45
|
# No more solution...
|
46
46
|
expect(solver.resume).to be_nil
|
@@ -50,7 +50,7 @@ module MiniKraken
|
|
50
50
|
instance = Goal.new(binary_relation, [KSymbol.new(:pea), KSymbol.new(:pea)])
|
51
51
|
|
52
52
|
solver = instance.attain(env)
|
53
|
-
expect(solver.resume).to
|
53
|
+
expect(solver.resume).to be_success
|
54
54
|
|
55
55
|
# No more solution...
|
56
56
|
expect(solver.resume).to be_nil
|
data/spec/core/outcome_spec.rb
CHANGED
@@ -25,6 +25,14 @@ module MiniKraken
|
|
25
25
|
expect(subject.resultant).to eq(:"#s")
|
26
26
|
end
|
27
27
|
|
28
|
+
it 'should know whether it represents a failure' do
|
29
|
+
expect(Outcome.new(:"#u")).to be_failure
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should know whether it represents a success' do
|
33
|
+
expect(subject).to be_success
|
34
|
+
end
|
35
|
+
|
28
36
|
it 'should know its parent' do
|
29
37
|
expect(subject.parent).to eq(voc)
|
30
38
|
end
|
data/spec/glue/dsl_chap1_spec.rb
CHANGED
@@ -113,7 +113,11 @@ module MiniKraken
|
|
113
113
|
# Reasoned S2, frame 1:34
|
114
114
|
# (run* q (== '(((,q)) pod) `(((pea)) pod))) ;; => ('pea)
|
115
115
|
|
116
|
-
|
116
|
+
expr1 = cons(cons(cons(q)), cons(:pod))
|
117
|
+
expect(expr1.to_s).to eq('(((q)) :pod)')
|
118
|
+
expr2 = cons(cons(cons(:pea)), cons(:pod))
|
119
|
+
expect(expr2.to_s).to eq('(((:pea)) :pod)')
|
120
|
+
result = run_star('q', equals(expr1, expr2))
|
117
121
|
expect(result.car).to eq(:pea)
|
118
122
|
end
|
119
123
|
|
@@ -129,7 +133,11 @@ module MiniKraken
|
|
129
133
|
# Reasoned S2, frame 1:36
|
130
134
|
# (run* q (fresh (x) (== '(((,q)) ,x) `(((,x)) pod)))) ;; => ('pod)
|
131
135
|
|
132
|
-
|
136
|
+
expr1 = cons(cons(cons(q)), cons(x))
|
137
|
+
expect(expr1.to_s).to eq('(((q)) x)')
|
138
|
+
expr2 = cons(cons(cons(x)), cons(:pod))
|
139
|
+
expect(expr2.to_s).to eq('(((x)) :pod)')
|
140
|
+
result = run_star('q', fresh('x', equals(expr1, expr2)))
|
133
141
|
expect(result.car).to eq(:pod)
|
134
142
|
end
|
135
143
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/mini_kraken/glue/dsl'
|
7
|
+
|
8
|
+
|
9
|
+
module MiniKraken
|
10
|
+
module Glue
|
11
|
+
describe 'DSL (Chap 2)' do
|
12
|
+
include DSL
|
13
|
+
|
14
|
+
context 'Chapter 2 examples:' do
|
15
|
+
let(:acorn) { cons(:a, cons(:c, cons(:o, cons(:r, cons(:n))))) }
|
16
|
+
|
17
|
+
it 'accepts caro definition inspired from frame 2:6' do
|
18
|
+
# Reasoned S2, frame 2:6
|
19
|
+
# (defrel (caro p a)
|
20
|
+
# (fresh (d)
|
21
|
+
# (== (cons a d) p)))
|
22
|
+
|
23
|
+
# As 'p' has a special meaning in Ruby, the argument has been remaned to 'r'
|
24
|
+
caro_rel = defrel('caro', %w[r a]) do
|
25
|
+
fresh('d', equals(cons(a, d), r))
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(caro_rel).to be_kind_of(Core::DefRelation)
|
29
|
+
expect(caro_rel.name).to eq('caro')
|
30
|
+
expect(caro_rel.arity).to eq(2)
|
31
|
+
expect(caro_rel.formals[0].name).to eq('r')
|
32
|
+
expect(caro_rel.formals[1].name).to eq('a')
|
33
|
+
g_template = caro_rel.goal_template
|
34
|
+
expect(g_template).to be_kind_of(FreshEnvFactory)
|
35
|
+
expect(g_template.names).to include('d')
|
36
|
+
end
|
37
|
+
|
38
|
+
# In Scheme:
|
39
|
+
# (defrel (caro p a)
|
40
|
+
# (fresh (d)
|
41
|
+
# (== (cons a d) p)))
|
42
|
+
# In Ruby, `p`is a stnadard Kernel method => replaced by `r`
|
43
|
+
def defrel_caro
|
44
|
+
defrel('caro', %w[r a]) { fresh('d', equals(cons(a, d), r)) }
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'passes frame 2:3' do
|
48
|
+
defrel_caro
|
49
|
+
|
50
|
+
# (run* q
|
51
|
+
# (caro '(a c o r n) q)) ;; => (a)
|
52
|
+
result = run_star('q', caro(acorn, q))
|
53
|
+
expect(result.car).to eq(:a)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'passes frame 2:4' do
|
57
|
+
defrel_caro
|
58
|
+
|
59
|
+
# (run* q
|
60
|
+
# (caro '(a c o r n) 'a)) ;; => (_0)
|
61
|
+
result = run_star('q', caro(acorn, :a))
|
62
|
+
expect(result.car).to eq(:_0)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'passes frame 2:5' do
|
66
|
+
defrel_caro
|
67
|
+
|
68
|
+
# (run* r
|
69
|
+
# (fresh (x y)
|
70
|
+
# (caro '(,r ,y) x)
|
71
|
+
# (== 'pear x)));; r => (pear)
|
72
|
+
result = run_star('r', fresh(%w[x y],
|
73
|
+
[caro(cons(r, cons(y)), x),
|
74
|
+
equals(:pear, x)]))
|
75
|
+
expect(result.car).to eq(:pear)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'passes frame 2:8' do
|
79
|
+
defrel_caro
|
80
|
+
|
81
|
+
# (run* r
|
82
|
+
# (fresh (x y)
|
83
|
+
# (caro '(grape raisin pear) x)
|
84
|
+
# (caro '((a) (b) (c)) y)
|
85
|
+
# (== (cons x y) r))) ;; r => ((grape a))
|
86
|
+
fruits = cons(:grape, cons(:raisin, cons(:pear)))
|
87
|
+
expect(fruits.to_s).to eq('(:grape :raisin :pear)')
|
88
|
+
abc = cons(cons(:a), cons(cons(:b), cons(cons(:c))))
|
89
|
+
expect(abc.to_s).to eq('((:a) (:b) (:c))')
|
90
|
+
|
91
|
+
result = run_star('r', fresh(%w[x y],
|
92
|
+
[caro(fruits, x),
|
93
|
+
caro(abc, y),
|
94
|
+
equals(cons(x, y), r)]))
|
95
|
+
expect(result.car).to eq(cons(:grape, cons(:a)))
|
96
|
+
end
|
97
|
+
end # context
|
98
|
+
end # describe
|
99
|
+
end # module
|
100
|
+
end # module
|