mini_kraken 0.2.04 → 0.3.00
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 +7 -0
- data/README.md +16 -16
- data/lib/mini_kraken/atomic/all_atomic.rb +1 -0
- data/lib/mini_kraken/atomic/atomic_term.rb +32 -17
- data/lib/mini_kraken/atomic/k_integer.rb +0 -4
- data/lib/mini_kraken/atomic/k_string.rb +17 -0
- data/lib/mini_kraken/atomic/k_symbol.rb +0 -6
- data/lib/mini_kraken/composite/all_composite.rb +4 -0
- data/lib/mini_kraken/composite/composite_term.rb +2 -18
- data/lib/mini_kraken/composite/cons_cell.rb +178 -11
- data/lib/mini_kraken/composite/cons_cell_visitor.rb +12 -64
- data/lib/mini_kraken/composite/list.rb +32 -0
- data/lib/mini_kraken/core/all_core.rb +8 -0
- data/lib/mini_kraken/core/any_value.rb +31 -7
- data/lib/mini_kraken/core/arity.rb +69 -0
- data/lib/mini_kraken/core/association.rb +29 -4
- data/lib/mini_kraken/core/association_copy.rb +50 -0
- data/lib/mini_kraken/core/base_term.rb +13 -0
- data/lib/mini_kraken/core/blackboard.rb +315 -0
- data/lib/mini_kraken/core/bookmark.rb +46 -0
- data/lib/mini_kraken/core/context.rb +624 -0
- data/lib/mini_kraken/core/duck_fiber.rb +21 -19
- data/lib/mini_kraken/core/entry.rb +40 -0
- data/lib/mini_kraken/core/fail.rb +20 -18
- data/lib/mini_kraken/core/fusion.rb +29 -0
- data/lib/mini_kraken/core/goal.rb +20 -29
- data/lib/mini_kraken/core/log_var.rb +4 -30
- data/lib/mini_kraken/core/log_var_ref.rb +72 -48
- data/lib/mini_kraken/core/nullary_relation.rb +2 -9
- data/lib/mini_kraken/core/parametrized_term.rb +61 -0
- data/lib/mini_kraken/core/relation.rb +14 -28
- data/lib/mini_kraken/core/scope.rb +67 -0
- data/lib/mini_kraken/core/solver_adapter.rb +58 -0
- data/lib/mini_kraken/core/specification.rb +48 -0
- data/lib/mini_kraken/core/succeed.rb +21 -17
- data/lib/mini_kraken/core/symbol_table.rb +137 -0
- data/lib/mini_kraken/core/term.rb +15 -4
- data/lib/mini_kraken/glue/dsl.rb +35 -69
- data/lib/mini_kraken/glue/run_star_expression.rb +28 -30
- data/lib/mini_kraken/rela/all_rela.rb +8 -0
- data/lib/mini_kraken/rela/binary_relation.rb +30 -0
- data/lib/mini_kraken/rela/conde.rb +146 -0
- data/lib/mini_kraken/rela/conj2.rb +65 -0
- data/lib/mini_kraken/rela/def_relation.rb +64 -0
- data/lib/mini_kraken/rela/disj2.rb +70 -0
- data/lib/mini_kraken/rela/fresh.rb +98 -0
- data/lib/mini_kraken/{core → rela}/goal_relation.rb +6 -8
- data/lib/mini_kraken/rela/unify.rb +258 -0
- data/lib/mini_kraken/version.rb +1 -1
- data/spec/atomic/atomic_term_spec.rb +23 -20
- data/spec/atomic/k_symbol_spec.rb +0 -5
- data/spec/composite/cons_cell_spec.rb +116 -0
- data/spec/composite/cons_cell_visitor_spec.rb +16 -3
- data/spec/composite/list_spec.rb +50 -0
- data/spec/core/any_value_spec.rb +52 -0
- data/spec/core/arity_spec.rb +91 -0
- data/spec/core/association_copy_spec.rb +69 -0
- data/spec/core/association_spec.rb +25 -0
- data/spec/core/blackboard_spec.rb +287 -0
- data/spec/core/bookmark_spec.rb +40 -0
- data/spec/core/context_spec.rb +221 -0
- data/spec/core/core_spec.rb +40 -0
- data/spec/core/duck_fiber_spec.rb +22 -46
- data/spec/core/fail_spec.rb +5 -6
- data/spec/core/goal_spec.rb +20 -11
- data/spec/core/log_var_ref_spec.rb +80 -5
- data/spec/core/log_var_spec.rb +35 -6
- data/spec/core/nullary_relation_spec.rb +33 -0
- data/spec/core/parametrized_tem_spec.rb +39 -0
- data/spec/core/relation_spec.rb +33 -0
- data/spec/core/scope_spec.rb +73 -0
- data/spec/core/solver_adapter_spec.rb +70 -0
- data/spec/core/specification_spec.rb +43 -0
- data/spec/core/succeed_spec.rb +5 -5
- data/spec/core/symbol_table_spec.rb +142 -0
- data/spec/glue/dsl_chap1_spec.rb +88 -99
- data/spec/glue/dsl_chap2_spec.rb +59 -41
- data/spec/glue/run_star_expression_spec.rb +69 -896
- data/spec/{core → rela}/conde_spec.rb +50 -46
- data/spec/rela/conj2_spec.rb +123 -0
- data/spec/rela/def_relation_spec.rb +119 -0
- data/spec/rela/disj2_spec.rb +117 -0
- data/spec/rela/fresh_spec.rb +147 -0
- data/spec/rela/unify_spec.rb +369 -0
- data/spec/support/factory_atomic.rb +7 -0
- data/spec/support/factory_composite.rb +21 -0
- metadata +71 -48
- data/lib/mini_kraken/core/association_walker.rb +0 -183
- data/lib/mini_kraken/core/base_arg.rb +0 -10
- data/lib/mini_kraken/core/binary_relation.rb +0 -63
- data/lib/mini_kraken/core/composite_goal.rb +0 -46
- data/lib/mini_kraken/core/conde.rb +0 -143
- data/lib/mini_kraken/core/conj2.rb +0 -79
- data/lib/mini_kraken/core/def_relation.rb +0 -53
- data/lib/mini_kraken/core/designation.rb +0 -55
- data/lib/mini_kraken/core/disj2.rb +0 -72
- data/lib/mini_kraken/core/environment.rb +0 -73
- data/lib/mini_kraken/core/equals.rb +0 -191
- data/lib/mini_kraken/core/formal_arg.rb +0 -22
- data/lib/mini_kraken/core/formal_ref.rb +0 -25
- data/lib/mini_kraken/core/freshness.rb +0 -45
- data/lib/mini_kraken/core/goal_arg.rb +0 -12
- data/lib/mini_kraken/core/goal_template.rb +0 -102
- data/lib/mini_kraken/core/outcome.rb +0 -63
- data/lib/mini_kraken/core/tap.rb +0 -46
- data/lib/mini_kraken/core/vocabulary.rb +0 -446
- data/lib/mini_kraken/glue/fresh_env.rb +0 -108
- data/lib/mini_kraken/glue/fresh_env_factory.rb +0 -83
- data/spec/core/association_walker_spec.rb +0 -194
- data/spec/core/conj2_spec.rb +0 -116
- data/spec/core/def_relation_spec.rb +0 -99
- data/spec/core/disj2_spec.rb +0 -100
- data/spec/core/environment_spec.rb +0 -144
- data/spec/core/equals_spec.rb +0 -319
- data/spec/core/goal_template_spec.rb +0 -74
- data/spec/core/outcome_spec.rb +0 -56
- data/spec/core/vocabulary_spec.rb +0 -220
- data/spec/glue/fresh_env_factory_spec.rb +0 -99
- data/spec/glue/fresh_env_spec.rb +0 -62
data/lib/mini_kraken/version.rb
CHANGED
|
@@ -28,19 +28,19 @@ module MiniKraken
|
|
|
28
28
|
end # context
|
|
29
29
|
|
|
30
30
|
context 'Provided services:' do
|
|
31
|
-
it 'should know that it is a
|
|
32
|
-
|
|
33
|
-
expect(subject.
|
|
31
|
+
it 'should know that it is a pinned term' do
|
|
32
|
+
ctx = double('mock-ctx')
|
|
33
|
+
expect(subject.pinned?(ctx)).to be_truthy
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
it 'should know that it is not a
|
|
37
|
-
|
|
38
|
-
expect(subject.
|
|
36
|
+
it 'should know that it is not a floating term' do
|
|
37
|
+
ctx = double('mock-ctx')
|
|
38
|
+
expect(subject.floating?(ctx)).to be_falsy
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
it 'should know
|
|
42
|
-
|
|
43
|
-
expect(subject.
|
|
41
|
+
it 'should know that it is not an unbound term' do
|
|
42
|
+
ctx = double('mock-ctx')
|
|
43
|
+
expect(subject.unbound?(ctx)).to be_falsy
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it 'performs data value comparison' do
|
|
@@ -76,19 +76,22 @@ module MiniKraken
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
it 'returns itself when receiving quote message' do
|
|
79
|
-
|
|
80
|
-
expect(subject.quote(
|
|
79
|
+
ctx = double('mock-ctx')
|
|
80
|
+
expect(subject.quote(ctx)).to eq(subject)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'should know it has no dependency on variable(s)' do
|
|
84
|
+
ctx = double('mock-ctx')
|
|
85
|
+
expect(subject.dependencies(ctx)).to be_empty
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it 'should dup itself' do
|
|
89
|
+
substitutions = double('fake-substitutions')
|
|
90
|
+
duplicate = subject.dup_cond(substitutions)
|
|
91
|
+
expect(duplicate).to eq(subject) # same value
|
|
92
|
+
expect(duplicate).not_to be_equal(subject) # different object ids
|
|
81
93
|
end
|
|
82
94
|
end # context
|
|
83
|
-
=begin
|
|
84
|
-
# An atomic term is by definition a ground term: since it doesn't contain
|
|
85
|
-
# any bound variable (in Prolog sense).
|
|
86
|
-
# @param _env [Vocabulary]
|
|
87
|
-
# @return [Freshness]
|
|
88
|
-
def freshness(_env)
|
|
89
|
-
Freshness.new(:ground, self)
|
|
90
|
-
end
|
|
91
|
-
=end
|
|
92
95
|
end # describe
|
|
93
96
|
end # module
|
|
94
97
|
end # module
|
|
@@ -20,11 +20,6 @@ module MiniKraken
|
|
|
20
20
|
it 'should know its value' do
|
|
21
21
|
expect(subject.value).to eq(a_value)
|
|
22
22
|
end
|
|
23
|
-
|
|
24
|
-
it 'should know that it is a ground term' do
|
|
25
|
-
env = double('mock-env')
|
|
26
|
-
expect(subject.ground?(env)).to be_truthy
|
|
27
|
-
end
|
|
28
23
|
end # context
|
|
29
24
|
|
|
30
25
|
context 'Provided services:' do
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative '../spec_helper' # Use the RSpec framework
|
|
4
4
|
require_relative '../support/factory_atomic'
|
|
5
|
+
require_relative '../../lib/mini_kraken/core/context'
|
|
6
|
+
require_relative '../../lib/mini_kraken/core/log_var'
|
|
7
|
+
require_relative '../../lib/mini_kraken/core/log_var_ref'
|
|
5
8
|
|
|
6
9
|
# Load the class under test
|
|
7
10
|
require_relative '../../lib/mini_kraken/composite/cons_cell'
|
|
@@ -14,6 +17,7 @@ module MiniKraken
|
|
|
14
17
|
let(:pea) { k_symbol(:pea) }
|
|
15
18
|
let(:pod) { k_symbol(:pod) }
|
|
16
19
|
let(:corn) { k_symbol(:corn) }
|
|
20
|
+
let(:ctx) { Core::Context.new }
|
|
17
21
|
subject { ConsCell.new(pea, pod) }
|
|
18
22
|
|
|
19
23
|
context 'Initialization:' do
|
|
@@ -25,6 +29,10 @@ module MiniKraken
|
|
|
25
29
|
expect { ConsCell.new(pea, pod) }.not_to raise_error
|
|
26
30
|
end
|
|
27
31
|
|
|
32
|
+
it 'could be initialized as null list' do
|
|
33
|
+
expect { ConsCell.null }.not_to raise_error
|
|
34
|
+
end
|
|
35
|
+
|
|
28
36
|
it 'should know its car child' do
|
|
29
37
|
expect(subject.car).to eq(pea)
|
|
30
38
|
end
|
|
@@ -33,6 +41,7 @@ module MiniKraken
|
|
|
33
41
|
expect(subject.cdr).to eq(pod)
|
|
34
42
|
end
|
|
35
43
|
|
|
44
|
+
|
|
36
45
|
it 'should know its children' do
|
|
37
46
|
expect(subject.children).to eq([pea, pod])
|
|
38
47
|
end
|
|
@@ -40,6 +49,7 @@ module MiniKraken
|
|
|
40
49
|
it 'should know if it is empty (null)' do
|
|
41
50
|
expect(subject).not_to be_null
|
|
42
51
|
expect(ConsCell.new(nil, nil)).to be_null
|
|
52
|
+
expect(ConsCell.null).to be_null
|
|
43
53
|
expect(NullList).to be_null
|
|
44
54
|
end
|
|
45
55
|
|
|
@@ -68,6 +78,14 @@ module MiniKraken
|
|
|
68
78
|
expect(subject.eql?(different)).to be_falsey
|
|
69
79
|
end
|
|
70
80
|
|
|
81
|
+
it 'should set_car! another cons cell' do
|
|
82
|
+
instance = ConsCell.new(pea)
|
|
83
|
+
head = ConsCell.new(pod)
|
|
84
|
+
instance.set_car!(head)
|
|
85
|
+
expect(instance.car).to eq(head)
|
|
86
|
+
expect(instance.cdr).to be_nil
|
|
87
|
+
end
|
|
88
|
+
|
|
71
89
|
it 'should set_cdr! another cons cell' do
|
|
72
90
|
instance = ConsCell.new(pea)
|
|
73
91
|
trail = ConsCell.new(pod)
|
|
@@ -76,6 +94,37 @@ module MiniKraken
|
|
|
76
94
|
expect(instance.cdr).to eq(trail)
|
|
77
95
|
end
|
|
78
96
|
|
|
97
|
+
it 'should set a member to some term' do
|
|
98
|
+
instance = ConsCell.null
|
|
99
|
+
head = ConsCell.new(pea)
|
|
100
|
+
trail = ConsCell.new(pod)
|
|
101
|
+
instance.set!(:car, head)
|
|
102
|
+
instance.set!(:cdr, trail)
|
|
103
|
+
expect(instance.car).to eq(head)
|
|
104
|
+
expect(instance.cdr).to eq(trail)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'should know whether it is pinned or not' do
|
|
108
|
+
# Case: all pair members are atomic items
|
|
109
|
+
expect(subject).to be_pinned(ctx)
|
|
110
|
+
|
|
111
|
+
# Case: cdr is nil
|
|
112
|
+
instance = ConsCell.new(pea)
|
|
113
|
+
expect(instance).to be_pinned(ctx)
|
|
114
|
+
|
|
115
|
+
# Case: embedded composite
|
|
116
|
+
nested = ConsCell.new(ConsCell.new(pod, pea), ConsCell.new(pea))
|
|
117
|
+
expect(nested).to be_pinned(ctx)
|
|
118
|
+
|
|
119
|
+
ctx.add_vars('q')
|
|
120
|
+
nested.set_cdr!(Core::LogVarRef.new('q'))
|
|
121
|
+
expect(nested).not_to be_pinned(ctx)
|
|
122
|
+
expect(nested).to be_floating(ctx)
|
|
123
|
+
|
|
124
|
+
ctx.associate('q', ConsCell.new(pea))
|
|
125
|
+
expect(nested).to be_pinned(ctx)
|
|
126
|
+
end
|
|
127
|
+
|
|
79
128
|
it 'should provide a list representation of itself' do
|
|
80
129
|
# Case of null list
|
|
81
130
|
expect(NullList.to_s).to eq '()'
|
|
@@ -91,6 +140,11 @@ module MiniKraken
|
|
|
91
140
|
# Case of two elements improper list
|
|
92
141
|
expect(subject.to_s).to eq '(:pea . :pod)'
|
|
93
142
|
|
|
143
|
+
# Case of one element plus null list
|
|
144
|
+
cell = ConsCell.new(pea)
|
|
145
|
+
cell.set_cdr!(ConsCell.null)
|
|
146
|
+
expect(cell.to_s).to eq '(:pea)'
|
|
147
|
+
|
|
94
148
|
# Case of three elements proper list
|
|
95
149
|
cell = ConsCell.new(pea, ConsCell.new(pod, ConsCell.new(corn)))
|
|
96
150
|
expect(cell.to_s).to eq '(:pea :pod :corn)'
|
|
@@ -103,6 +157,68 @@ module MiniKraken
|
|
|
103
157
|
cell = ConsCell.new(ConsCell.new(pea), ConsCell.new(pod))
|
|
104
158
|
expect(cell.to_s).to eq '((:pea) :pod)'
|
|
105
159
|
end
|
|
160
|
+
|
|
161
|
+
it 'should know its dependencies' do
|
|
162
|
+
# Case: no var ref...
|
|
163
|
+
lst = ConsCell.new(ConsCell.new(pod, pea), ConsCell.new(pea))
|
|
164
|
+
expect(lst.dependencies(ctx)).to be_empty
|
|
165
|
+
|
|
166
|
+
# Case: multiple var refs
|
|
167
|
+
ctx.add_vars(%w[q x])
|
|
168
|
+
q_ref = Core::LogVarRef.new('q')
|
|
169
|
+
x_ref = Core::LogVarRef.new('x')
|
|
170
|
+
list2 = ConsCell.new(ConsCell.new(q_ref, pea), ConsCell.new(x_ref))
|
|
171
|
+
expect(list2.dependencies(ctx).size).to eq(2)
|
|
172
|
+
q_var = ctx.lookup('q')
|
|
173
|
+
x_var = ctx.lookup('x')
|
|
174
|
+
predicted = Set.new([q_var.i_name, x_var.i_name])
|
|
175
|
+
expect(list2.dependencies(ctx)).to eq(predicted)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'should, as list with atomic terms, provide an expanded copy' do
|
|
179
|
+
# Case of a list of atomic terms
|
|
180
|
+
lst = ConsCell.new(ConsCell.new(ConsCell.new(pea), pod))
|
|
181
|
+
representation = lst.to_s
|
|
182
|
+
|
|
183
|
+
copy = lst.expand(ctx, {})
|
|
184
|
+
expect(copy.to_s).to eq(representation)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'should, as list with variable refs, provide an expanded copy' do
|
|
188
|
+
# Case of a list of variable refs
|
|
189
|
+
ctx.add_vars(['x'])
|
|
190
|
+
x_ref = Core::LogVarRef.new('x')
|
|
191
|
+
x_var = ctx.lookup('x')
|
|
192
|
+
ctx.associate('x', Core::AnyValue.new(0))
|
|
193
|
+
lst = ConsCell.new(x_ref, ConsCell.new(x_ref))
|
|
194
|
+
substitutions = {}
|
|
195
|
+
substitutions[x_var.i_name] = Core::AnyValue.new(0)
|
|
196
|
+
|
|
197
|
+
copy = lst.expand(ctx, substitutions)
|
|
198
|
+
expect(copy.to_s).to eq('(_0 _0)')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'should provide a duplicate with variable replaced by their value' do
|
|
202
|
+
q_ref = Core::LogVarRef.new('q')
|
|
203
|
+
x_ref = Core::LogVarRef.new('x')
|
|
204
|
+
y_ref = Core::LogVarRef.new('y')
|
|
205
|
+
substitutions = {
|
|
206
|
+
'q' => ConsCell.new(pea, ConsCell.new(x_ref, y_ref)),
|
|
207
|
+
'x' => pod,
|
|
208
|
+
'y' => corn
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
# Basic case: variable ref points to an atomic value
|
|
212
|
+
expr = ConsCell.new(pea, x_ref)
|
|
213
|
+
duplicate = expr.dup_cond(substitutions)
|
|
214
|
+
expect(duplicate.to_s).to eq('(:pea . :pod)')
|
|
215
|
+
|
|
216
|
+
expr = ConsCell.new(pod, ConsCell.new(q_ref, y_ref))
|
|
217
|
+
duplicate = expr.dup_cond(substitutions)
|
|
218
|
+
expect(duplicate.car).to eq(pod)
|
|
219
|
+
expect(duplicate.cdr.car.to_s).to eq('(:pea :pod . :corn)')
|
|
220
|
+
expect(duplicate.to_s).to eq('(:pod (:pea :pod . :corn) . :corn)')
|
|
221
|
+
end
|
|
106
222
|
end # context
|
|
107
223
|
end # describe
|
|
108
224
|
end # module
|
|
@@ -29,7 +29,7 @@ module MiniKraken
|
|
|
29
29
|
|
|
30
30
|
context 'proper list visiting:' do
|
|
31
31
|
it 'can visit a null list' do
|
|
32
|
-
null_list = ConsCell.
|
|
32
|
+
null_list = ConsCell.null
|
|
33
33
|
visitor = subject.df_visitor(null_list)
|
|
34
34
|
expect(visitor.resume).to eq([:car, null_list])
|
|
35
35
|
expect(visitor.resume).to eq([:car, nil])
|
|
@@ -89,6 +89,7 @@ module MiniKraken
|
|
|
89
89
|
|
|
90
90
|
it 'can visit a three elements improper list' do
|
|
91
91
|
l_improper = ConsCell.new(pea, ConsCell.new(pod, corn))
|
|
92
|
+
expect(l_improper.to_s).to eq('(:pea :pod . :corn)')
|
|
92
93
|
visitor = subject.df_visitor(l_improper)
|
|
93
94
|
expect(visitor.resume).to eq([:car, l_improper])
|
|
94
95
|
expect(visitor.resume).to eq([:car, pea])
|
|
@@ -97,6 +98,18 @@ module MiniKraken
|
|
|
97
98
|
expect(visitor.resume).to eq([:cdr, corn])
|
|
98
99
|
expect(visitor.resume).to eq([:stop, nil])
|
|
99
100
|
end
|
|
101
|
+
|
|
102
|
+
it 'smurch' do
|
|
103
|
+
composite = ConsCell.new(ConsCell.new(ConsCell.new(pea)), pod)
|
|
104
|
+
visitor = subject.df_visitor(composite)
|
|
105
|
+
expect(visitor.resume).to eq([:car, composite])
|
|
106
|
+
expect(visitor.resume).to eq([:car, composite.car])
|
|
107
|
+
expect(visitor.resume).to eq([:car, composite.car.car])
|
|
108
|
+
expect(visitor.resume).to eq([:car, pea])
|
|
109
|
+
expect(visitor.resume).to eq([:cdr, nil])
|
|
110
|
+
expect(visitor.resume).to eq([:cdr, nil])
|
|
111
|
+
expect(visitor.resume).to eq([:cdr, pod])
|
|
112
|
+
end
|
|
100
113
|
end # context
|
|
101
114
|
|
|
102
115
|
context 'Skip visit of children of a ConsCell:' do
|
|
@@ -128,9 +141,9 @@ module MiniKraken
|
|
|
128
141
|
|
|
129
142
|
context 'Circular structures visiting:' do
|
|
130
143
|
it 'should cope with a circular graph' do
|
|
131
|
-
second_cell = ConsCell.new(
|
|
144
|
+
second_cell = ConsCell.new(pea)
|
|
132
145
|
first_cell = ConsCell.new(pea, second_cell)
|
|
133
|
-
second_cell.
|
|
146
|
+
second_cell.set_car!(first_cell)
|
|
134
147
|
|
|
135
148
|
visitor = subject.df_visitor(first_cell)
|
|
136
149
|
expect(visitor.resume).to eq([:car, first_cell])
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
|
4
|
+
require_relative '../support/factory_atomic'
|
|
5
|
+
|
|
6
|
+
# Load the class under test
|
|
7
|
+
require_relative '../../lib/mini_kraken/composite/list'
|
|
8
|
+
|
|
9
|
+
module MiniKraken
|
|
10
|
+
module Composite
|
|
11
|
+
describe List do
|
|
12
|
+
include MiniKraken::FactoryAtomic # Use mix-in module
|
|
13
|
+
|
|
14
|
+
let(:pea) { k_symbol(:pea) }
|
|
15
|
+
let(:pod) { k_symbol(:pod) }
|
|
16
|
+
let(:corn) { k_symbol(:corn) }
|
|
17
|
+
|
|
18
|
+
context 'Module as a factory:' do
|
|
19
|
+
subject { List }
|
|
20
|
+
|
|
21
|
+
it 'builds a pair wiht one argument (= one element proper list)' do
|
|
22
|
+
pair = subject.cons(pea)
|
|
23
|
+
expect(pair.car).to eq(pea)
|
|
24
|
+
expect(pair.cdr).to be_nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'builds a pair with two explicit arguments' do
|
|
28
|
+
pair = subject.cons(pea, pod)
|
|
29
|
+
expect(pair.car).to eq(pea)
|
|
30
|
+
expect(pair.cdr).to eq(pod)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'builds a null list from an empty array' do
|
|
34
|
+
l = subject.make_list([])
|
|
35
|
+
expect(l).to be_kind_of(ConsCell)
|
|
36
|
+
expect(l).to be_null
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'builds a proper list from an non-empty array' do
|
|
40
|
+
l = subject.make_list([pea, pod, corn])
|
|
41
|
+
|
|
42
|
+
expect(l.car).to eq(pea)
|
|
43
|
+
expect(l.cdr.car).to eq(pod)
|
|
44
|
+
expect(l.cdr.cdr.car).to eq(corn)
|
|
45
|
+
expect(l.cdr.cdr.cdr).to be_nil
|
|
46
|
+
end
|
|
47
|
+
end # context
|
|
48
|
+
end # describz
|
|
49
|
+
end # module
|
|
50
|
+
end # module
|
|
@@ -0,0 +1,52 @@
|
|
|
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/core/any_value'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module MiniKraken
|
|
10
|
+
module Core
|
|
11
|
+
describe AnyValue do
|
|
12
|
+
let(:some_rank) { 2 }
|
|
13
|
+
subject { AnyValue.new(some_rank) }
|
|
14
|
+
|
|
15
|
+
context 'Initialization:' do
|
|
16
|
+
it "should be initialized with a variable's rank" do
|
|
17
|
+
expect { AnyValue.new(0) }.not_to raise_error
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should know its rank' do
|
|
21
|
+
expect(subject.rank).to eq(some_rank)
|
|
22
|
+
end
|
|
23
|
+
end # context
|
|
24
|
+
|
|
25
|
+
context 'Provided services:' do
|
|
26
|
+
it 'should compare itself to another instance' do
|
|
27
|
+
expect(subject == AnyValue.new(some_rank)).to be_truthy
|
|
28
|
+
expect(subject == AnyValue.new(1)).to be_falsey
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'should compare itself to an integer' do
|
|
32
|
+
expect(subject == some_rank).to be_truthy
|
|
33
|
+
expect(subject == 1).to be_falsey
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should compare itself to a symbol' do
|
|
37
|
+
expect(subject == :_2).to be_truthy
|
|
38
|
+
expect(subject == :_1).to be_falsey
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'should know its text representation' do
|
|
42
|
+
expect(subject.to_s).to eq('_2')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'should know that it represents a non-pinned variable' do
|
|
46
|
+
ctx = double('dummy-context')
|
|
47
|
+
expect(subject).not_to be_pinned(ctx)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end # describe
|
|
51
|
+
end # module
|
|
52
|
+
end # module
|
|
@@ -0,0 +1,91 @@
|
|
|
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/core/arity'
|
|
7
|
+
|
|
8
|
+
module MiniKraken
|
|
9
|
+
module Core
|
|
10
|
+
describe Arity do
|
|
11
|
+
subject { Arity.new(0, 1) }
|
|
12
|
+
|
|
13
|
+
context 'Initialization:' do
|
|
14
|
+
it 'should be initialized with two integers' do
|
|
15
|
+
expect { Arity.new(0, 1) }.not_to raise_error
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should know its lower bound' do
|
|
19
|
+
expect(subject.low).to eq(0)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'should know its upper bound' do
|
|
23
|
+
expect(subject.high).to eq(1)
|
|
24
|
+
end
|
|
25
|
+
end # context
|
|
26
|
+
|
|
27
|
+
context 'Initialization:' do
|
|
28
|
+
it 'should know whether is is nullary' do
|
|
29
|
+
expect(subject).not_to be_nullary
|
|
30
|
+
|
|
31
|
+
instance = Arity.new(0, '*')
|
|
32
|
+
expect(instance).not_to be_nullary
|
|
33
|
+
|
|
34
|
+
instance = Arity.new(0, 0)
|
|
35
|
+
expect(instance).to be_nullary
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should know whether is is unary' do
|
|
39
|
+
expect(subject).not_to be_unary
|
|
40
|
+
|
|
41
|
+
instance = Arity.new(1, 2)
|
|
42
|
+
expect(instance).not_to be_unary
|
|
43
|
+
|
|
44
|
+
instance = Arity.new(1, 1)
|
|
45
|
+
expect(instance).to be_unary
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should know whether is is binary' do
|
|
49
|
+
expect(subject).not_to be_binary
|
|
50
|
+
|
|
51
|
+
instance = Arity.new(1, 2)
|
|
52
|
+
expect(instance).not_to be_binary
|
|
53
|
+
|
|
54
|
+
instance = Arity.new(2, 2)
|
|
55
|
+
expect(instance).to be_binary
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'should know whether is is variadic' do
|
|
59
|
+
expect(subject).not_to be_variadic
|
|
60
|
+
|
|
61
|
+
instance = Arity.new(1, '*')
|
|
62
|
+
expect(instance).to be_variadic
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'should know whether an integer fits the arity range' do
|
|
66
|
+
expect(subject.match?(0)).to be_truthy
|
|
67
|
+
expect(subject.match?(1)).to be_truthy
|
|
68
|
+
expect(subject.match?(2)).to be_falsey
|
|
69
|
+
|
|
70
|
+
instance = Arity.new(2, '*')
|
|
71
|
+
expect(instance.match?(1)).to be_falsey
|
|
72
|
+
expect(instance.match?(2)).to be_truthy
|
|
73
|
+
expect(instance.match?(42)).to be_truthy
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'should know whether is equal to another arity' do
|
|
77
|
+
expect(subject == subject).to be_truthy
|
|
78
|
+
|
|
79
|
+
same = Arity.new(0, 1)
|
|
80
|
+
expect(subject == same).to be_truthy
|
|
81
|
+
|
|
82
|
+
same_low = Arity.new(0, 2)
|
|
83
|
+
expect(subject == same_low).to be_falsey
|
|
84
|
+
|
|
85
|
+
same_high = Arity.new(1, 1)
|
|
86
|
+
expect(subject == same_high).to be_falsey
|
|
87
|
+
end
|
|
88
|
+
end # context
|
|
89
|
+
end # describe
|
|
90
|
+
end # module
|
|
91
|
+
end # module
|