mini_kraken 0.2.04 → 0.3.00

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +16 -16
  4. data/lib/mini_kraken/atomic/all_atomic.rb +1 -0
  5. data/lib/mini_kraken/atomic/atomic_term.rb +32 -17
  6. data/lib/mini_kraken/atomic/k_integer.rb +0 -4
  7. data/lib/mini_kraken/atomic/k_string.rb +17 -0
  8. data/lib/mini_kraken/atomic/k_symbol.rb +0 -6
  9. data/lib/mini_kraken/composite/all_composite.rb +4 -0
  10. data/lib/mini_kraken/composite/composite_term.rb +2 -18
  11. data/lib/mini_kraken/composite/cons_cell.rb +178 -11
  12. data/lib/mini_kraken/composite/cons_cell_visitor.rb +12 -64
  13. data/lib/mini_kraken/composite/list.rb +32 -0
  14. data/lib/mini_kraken/core/all_core.rb +8 -0
  15. data/lib/mini_kraken/core/any_value.rb +31 -7
  16. data/lib/mini_kraken/core/arity.rb +69 -0
  17. data/lib/mini_kraken/core/association.rb +29 -4
  18. data/lib/mini_kraken/core/association_copy.rb +50 -0
  19. data/lib/mini_kraken/core/base_term.rb +13 -0
  20. data/lib/mini_kraken/core/blackboard.rb +315 -0
  21. data/lib/mini_kraken/core/bookmark.rb +46 -0
  22. data/lib/mini_kraken/core/context.rb +624 -0
  23. data/lib/mini_kraken/core/duck_fiber.rb +21 -19
  24. data/lib/mini_kraken/core/entry.rb +40 -0
  25. data/lib/mini_kraken/core/fail.rb +20 -18
  26. data/lib/mini_kraken/core/fusion.rb +29 -0
  27. data/lib/mini_kraken/core/goal.rb +20 -29
  28. data/lib/mini_kraken/core/log_var.rb +4 -30
  29. data/lib/mini_kraken/core/log_var_ref.rb +72 -48
  30. data/lib/mini_kraken/core/nullary_relation.rb +2 -9
  31. data/lib/mini_kraken/core/parametrized_term.rb +61 -0
  32. data/lib/mini_kraken/core/relation.rb +14 -28
  33. data/lib/mini_kraken/core/scope.rb +67 -0
  34. data/lib/mini_kraken/core/solver_adapter.rb +58 -0
  35. data/lib/mini_kraken/core/specification.rb +48 -0
  36. data/lib/mini_kraken/core/succeed.rb +21 -17
  37. data/lib/mini_kraken/core/symbol_table.rb +137 -0
  38. data/lib/mini_kraken/core/term.rb +15 -4
  39. data/lib/mini_kraken/glue/dsl.rb +35 -69
  40. data/lib/mini_kraken/glue/run_star_expression.rb +28 -30
  41. data/lib/mini_kraken/rela/all_rela.rb +8 -0
  42. data/lib/mini_kraken/rela/binary_relation.rb +30 -0
  43. data/lib/mini_kraken/rela/conde.rb +146 -0
  44. data/lib/mini_kraken/rela/conj2.rb +65 -0
  45. data/lib/mini_kraken/rela/def_relation.rb +64 -0
  46. data/lib/mini_kraken/rela/disj2.rb +70 -0
  47. data/lib/mini_kraken/rela/fresh.rb +98 -0
  48. data/lib/mini_kraken/{core → rela}/goal_relation.rb +6 -8
  49. data/lib/mini_kraken/rela/unify.rb +258 -0
  50. data/lib/mini_kraken/version.rb +1 -1
  51. data/spec/atomic/atomic_term_spec.rb +23 -20
  52. data/spec/atomic/k_symbol_spec.rb +0 -5
  53. data/spec/composite/cons_cell_spec.rb +116 -0
  54. data/spec/composite/cons_cell_visitor_spec.rb +16 -3
  55. data/spec/composite/list_spec.rb +50 -0
  56. data/spec/core/any_value_spec.rb +52 -0
  57. data/spec/core/arity_spec.rb +91 -0
  58. data/spec/core/association_copy_spec.rb +69 -0
  59. data/spec/core/association_spec.rb +25 -0
  60. data/spec/core/blackboard_spec.rb +287 -0
  61. data/spec/core/bookmark_spec.rb +40 -0
  62. data/spec/core/context_spec.rb +221 -0
  63. data/spec/core/core_spec.rb +40 -0
  64. data/spec/core/duck_fiber_spec.rb +22 -46
  65. data/spec/core/fail_spec.rb +5 -6
  66. data/spec/core/goal_spec.rb +20 -11
  67. data/spec/core/log_var_ref_spec.rb +80 -5
  68. data/spec/core/log_var_spec.rb +35 -6
  69. data/spec/core/nullary_relation_spec.rb +33 -0
  70. data/spec/core/parametrized_tem_spec.rb +39 -0
  71. data/spec/core/relation_spec.rb +33 -0
  72. data/spec/core/scope_spec.rb +73 -0
  73. data/spec/core/solver_adapter_spec.rb +70 -0
  74. data/spec/core/specification_spec.rb +43 -0
  75. data/spec/core/succeed_spec.rb +5 -5
  76. data/spec/core/symbol_table_spec.rb +142 -0
  77. data/spec/glue/dsl_chap1_spec.rb +88 -99
  78. data/spec/glue/dsl_chap2_spec.rb +59 -41
  79. data/spec/glue/run_star_expression_spec.rb +69 -896
  80. data/spec/{core → rela}/conde_spec.rb +50 -46
  81. data/spec/rela/conj2_spec.rb +123 -0
  82. data/spec/rela/def_relation_spec.rb +119 -0
  83. data/spec/rela/disj2_spec.rb +117 -0
  84. data/spec/rela/fresh_spec.rb +147 -0
  85. data/spec/rela/unify_spec.rb +369 -0
  86. data/spec/support/factory_atomic.rb +7 -0
  87. data/spec/support/factory_composite.rb +21 -0
  88. metadata +71 -48
  89. data/lib/mini_kraken/core/association_walker.rb +0 -183
  90. data/lib/mini_kraken/core/base_arg.rb +0 -10
  91. data/lib/mini_kraken/core/binary_relation.rb +0 -63
  92. data/lib/mini_kraken/core/composite_goal.rb +0 -46
  93. data/lib/mini_kraken/core/conde.rb +0 -143
  94. data/lib/mini_kraken/core/conj2.rb +0 -79
  95. data/lib/mini_kraken/core/def_relation.rb +0 -53
  96. data/lib/mini_kraken/core/designation.rb +0 -55
  97. data/lib/mini_kraken/core/disj2.rb +0 -72
  98. data/lib/mini_kraken/core/environment.rb +0 -73
  99. data/lib/mini_kraken/core/equals.rb +0 -191
  100. data/lib/mini_kraken/core/formal_arg.rb +0 -22
  101. data/lib/mini_kraken/core/formal_ref.rb +0 -25
  102. data/lib/mini_kraken/core/freshness.rb +0 -45
  103. data/lib/mini_kraken/core/goal_arg.rb +0 -12
  104. data/lib/mini_kraken/core/goal_template.rb +0 -102
  105. data/lib/mini_kraken/core/outcome.rb +0 -63
  106. data/lib/mini_kraken/core/tap.rb +0 -46
  107. data/lib/mini_kraken/core/vocabulary.rb +0 -446
  108. data/lib/mini_kraken/glue/fresh_env.rb +0 -108
  109. data/lib/mini_kraken/glue/fresh_env_factory.rb +0 -83
  110. data/spec/core/association_walker_spec.rb +0 -194
  111. data/spec/core/conj2_spec.rb +0 -116
  112. data/spec/core/def_relation_spec.rb +0 -99
  113. data/spec/core/disj2_spec.rb +0 -100
  114. data/spec/core/environment_spec.rb +0 -144
  115. data/spec/core/equals_spec.rb +0 -319
  116. data/spec/core/goal_template_spec.rb +0 -74
  117. data/spec/core/outcome_spec.rb +0 -56
  118. data/spec/core/vocabulary_spec.rb +0 -220
  119. data/spec/glue/fresh_env_factory_spec.rb +0 -99
  120. data/spec/glue/fresh_env_spec.rb +0 -62
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniKraken
4
- VERSION = '0.2.04'
4
+ VERSION = '0.3.00'
5
5
  end
@@ -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 ground term' do
32
- env = double('mock-env')
33
- expect(subject.ground?(env)).to be_truthy
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 fresh term' do
37
- env = double('mock-env')
38
- expect(subject.fresh?(env)).to be_falsy
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 its freshness' do
42
- env = double('mock-env')
43
- expect(subject.freshness(env).degree).to eq(:ground)
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
- env = double('mock-env')
80
- expect(subject.quote(env)).to eq(subject)
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.new(nil)
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(pod)
144
+ second_cell = ConsCell.new(pea)
132
145
  first_cell = ConsCell.new(pea, second_cell)
133
- second_cell.instance_variable_set(:@car, first_cell) # Ugly!
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