wongi-engine 0.3.6 → 0.3.7

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +80 -0
  4. data/.travis.yml +6 -16
  5. data/Gemfile +4 -0
  6. data/README.md +3 -3
  7. data/Rakefile +1 -2
  8. data/examples/ex01.rb +1 -1
  9. data/examples/ex02.rb +3 -7
  10. data/examples/graphviz.rb +1 -1
  11. data/examples/rdf.rb +1 -1
  12. data/examples/timeline.rb +6 -6
  13. data/lib/wongi-engine/alpha_memory.rb +5 -9
  14. data/lib/wongi-engine/beta/aggregate_node.rb +93 -0
  15. data/lib/wongi-engine/beta/assignment_node.rb +10 -18
  16. data/lib/wongi-engine/beta/beta_memory.rb +20 -9
  17. data/lib/wongi-engine/beta/beta_node.rb +14 -22
  18. data/lib/wongi-engine/beta/filter_node.rb +12 -15
  19. data/lib/wongi-engine/beta/join_node.rb +47 -61
  20. data/lib/wongi-engine/beta/ncc_node.rb +17 -20
  21. data/lib/wongi-engine/beta/ncc_partner.rb +17 -17
  22. data/lib/wongi-engine/beta/neg_node.rb +37 -37
  23. data/lib/wongi-engine/beta/optional_node.rb +53 -60
  24. data/lib/wongi-engine/beta/or_node.rb +6 -9
  25. data/lib/wongi-engine/beta/production_node.rb +6 -9
  26. data/lib/wongi-engine/beta.rb +1 -0
  27. data/lib/wongi-engine/compiler.rb +38 -22
  28. data/lib/wongi-engine/core_ext.rb +11 -20
  29. data/lib/wongi-engine/data_overlay.rb +23 -26
  30. data/lib/wongi-engine/dsl/action/assign_action.rb +1 -1
  31. data/lib/wongi-engine/dsl/action/base.rb +1 -4
  32. data/lib/wongi-engine/dsl/action/error_generator.rb +9 -9
  33. data/lib/wongi-engine/dsl/action/simple_action.rb +14 -10
  34. data/lib/wongi-engine/dsl/action/simple_collector.rb +10 -25
  35. data/lib/wongi-engine/dsl/action/statement_generator.rb +15 -14
  36. data/lib/wongi-engine/dsl/action/trace_action.rb +9 -9
  37. data/lib/wongi-engine/dsl/any_rule.rb +16 -20
  38. data/lib/wongi-engine/dsl/assuming.rb +8 -15
  39. data/lib/wongi-engine/dsl/builder.rb +13 -12
  40. data/lib/wongi-engine/dsl/clause/aggregate.rb +21 -0
  41. data/lib/wongi-engine/dsl/clause/assign.rb +4 -4
  42. data/lib/wongi-engine/dsl/clause/fact.rb +10 -6
  43. data/lib/wongi-engine/dsl/clause/gen.rb +3 -5
  44. data/lib/wongi-engine/dsl/clause/generic.rb +7 -9
  45. data/lib/wongi-engine/dsl/generated.rb +6 -12
  46. data/lib/wongi-engine/dsl/ncc_subrule.rb +6 -9
  47. data/lib/wongi-engine/dsl/query.rb +12 -15
  48. data/lib/wongi-engine/dsl/rule.rb +45 -50
  49. data/lib/wongi-engine/dsl.rb +30 -16
  50. data/lib/wongi-engine/enumerators.rb +2 -1
  51. data/lib/wongi-engine/error.rb +6 -7
  52. data/lib/wongi-engine/filter/asserting_test.rb +4 -7
  53. data/lib/wongi-engine/filter/equality_test.rb +15 -18
  54. data/lib/wongi-engine/filter/filter_test.rb +3 -6
  55. data/lib/wongi-engine/filter/greater_than_or_equal_test.rb +5 -2
  56. data/lib/wongi-engine/filter/greater_than_test.rb +15 -18
  57. data/lib/wongi-engine/filter/inequality_test.rb +15 -18
  58. data/lib/wongi-engine/filter/less_than_or_equal_test.rb +5 -2
  59. data/lib/wongi-engine/filter/less_than_test.rb +15 -18
  60. data/lib/wongi-engine/filter.rb +1 -1
  61. data/lib/wongi-engine/graph.rb +13 -20
  62. data/lib/wongi-engine/network/collectable.rb +10 -14
  63. data/lib/wongi-engine/network/debug.rb +16 -24
  64. data/lib/wongi-engine/network.rb +110 -129
  65. data/lib/wongi-engine/ruleset.rb +18 -20
  66. data/lib/wongi-engine/template.rb +31 -30
  67. data/lib/wongi-engine/token.rb +33 -33
  68. data/lib/wongi-engine/version.rb +1 -1
  69. data/lib/wongi-engine/wme.rb +17 -23
  70. data/lib/wongi-engine/wme_match_data.rb +5 -9
  71. data/lib/wongi-engine.rb +0 -4
  72. data/spec/action_class_spec.rb +43 -49
  73. data/spec/beta_node_spec.rb +2 -8
  74. data/spec/bug_specs/issue_4_spec.rb +12 -20
  75. data/spec/dataset_spec.rb +3 -6
  76. data/spec/filter_specs/assert_test_spec.rb +12 -31
  77. data/spec/filter_specs/greater_than_equality_test_spec.rb +2 -5
  78. data/spec/filter_specs/less_test_spec.rb +7 -17
  79. data/spec/filter_specs/less_than_equality_test_spec.rb +3 -6
  80. data/spec/generation_spec.rb +45 -54
  81. data/spec/high_level_spec.rb +95 -141
  82. data/spec/network_spec.rb +77 -68
  83. data/spec/overlay_spec.rb +4 -5
  84. data/spec/rule_specs/aggregate_spec.rb +197 -0
  85. data/spec/rule_specs/any_rule_spec.rb +4 -19
  86. data/spec/rule_specs/assign_spec.rb +10 -16
  87. data/spec/rule_specs/assuming_spec.rb +10 -17
  88. data/spec/rule_specs/maybe_rule_spec.rb +4 -15
  89. data/spec/rule_specs/ncc_spec.rb +48 -65
  90. data/spec/rule_specs/negative_rule_spec.rb +13 -27
  91. data/spec/rule_specs/or_rule_spec.rb +3 -13
  92. data/spec/ruleset_spec.rb +11 -17
  93. data/spec/simple_action_spec.rb +4 -14
  94. data/spec/wme_spec.rb +14 -21
  95. data/wongi-engine.gemspec +22 -22
  96. metadata +16 -37
  97. data/.hgignore +0 -7
  98. data/spec/dsl_spec.rb +0 -9
data/spec/network_spec.rb CHANGED
@@ -1,60 +1,85 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Wongi::Engine::Network do
4
+ include Wongi::Engine::DSL
4
5
 
5
- let( :engine ) { Wongi::Engine.create }
6
+ let(:engine) { Wongi::Engine.create }
6
7
  subject { engine }
7
8
 
8
9
  it 'should assert facts' do
9
- subject << [1,2,3]
10
- expect( subject.select( :_, 2, :_) ).to have(1).item
10
+ subject << [1, 2, 3]
11
+ expect(subject.select(:_, 2, :_)).to have(1).item
11
12
  end
12
13
 
13
14
  it 'should retract facts' do
14
- subject << [1,2,3]
15
- subject.retract [1,2,3]
16
- expect( subject.select( :_, 2, :_) ).to be_empty
15
+ subject << [1, 2, 3]
16
+ subject.retract [1, 2, 3]
17
+ expect(subject.select(:_, 2, :_)).to be_empty
17
18
  end
18
19
 
19
20
  it 'asserted facts end up in productions' do
20
-
21
21
  prod = subject << rule { forall { has :X, 2, :Z } }
22
- subject << [1,2,3]
23
- expect( prod ).to have(1).tokens
22
+ subject << [1, 2, 3]
23
+ expect(prod).to have(1).tokens
24
+ end
25
+
26
+ it 'rules can be removed from engine' do
27
+ subject << [1, 2, 3]
28
+ subject << [4, 5, 6]
29
+
30
+ prod1 = subject << rule { forall { has :X, 2, :Z } }
31
+ prod2 = subject << rule { forall { has :X, 5, :Z } }
32
+
33
+ expect(prod1).to have(1).tokens
34
+ expect(prod2).to have(1).tokens
24
35
 
36
+ subject.remove_production(prod1)
37
+
38
+ expect(prod1).to have(0).tokens
39
+ expect(prod2).to have(1).tokens
25
40
  end
26
41
 
27
- it 'retracted facts are removed from productions' do
42
+ it 'new rules can be added to engine after a rule has been been removed' do
43
+ subject << [1, 2, 3]
44
+ subject << [4, 5, 6]
28
45
 
29
- prod = subject << rule { forall { has :X, 2, :Z } }
30
- subject << [1,2,3]
31
- subject.retract [1,2,3]
32
- expect( prod ).to have(0).tokens
46
+ prod1 = subject << rule { forall { has :X, 2, :Z } }
47
+
48
+ expect(prod1).to have(1).tokens
33
49
 
50
+ subject.remove_production(prod1)
51
+ expect(prod1).to have(0).tokens
52
+
53
+ prod2 = subject << rule { forall { has :X, 5, :Z } }
54
+ expect(prod2).to have(1).tokens
34
55
  end
35
56
 
36
- it 'retracted facts should trigger deactivation' do
57
+ it 'retracted facts are removed from productions' do
58
+ prod = subject << rule { forall { has :X, 2, :Z } }
59
+ subject << [1, 2, 3]
60
+ subject.retract [1, 2, 3]
61
+ expect(prod).to have(0).tokens
62
+ end
37
63
 
64
+ it 'retracted facts should trigger deactivation' do
38
65
  activated_z = nil
39
66
  deactivated_z = nil
40
67
 
41
- prod = subject << rule {
68
+ subject << rule {
42
69
  forall { has :X, 2, :Z }
43
70
  make {
44
71
  action activate: ->(token) { activated_z = token[:Z] },
45
72
  deactivate: ->(token) { deactivated_z = token[:Z] }
46
73
  }
47
74
  }
48
- subject << [1,2,3]
49
- expect( activated_z ).to be == 3
50
-
51
- subject.retract [1,2,3]
52
- expect( deactivated_z ).to be == 3
75
+ subject << [1, 2, 3]
76
+ expect(activated_z).to be == 3
53
77
 
78
+ subject.retract [1, 2, 3]
79
+ expect(deactivated_z).to be == 3
54
80
  end
55
81
 
56
82
  it 'retracted facts should propagate through join chains' do
57
-
58
83
  deactivated = nil
59
84
 
60
85
  prod = engine << rule {
@@ -70,113 +95,97 @@ describe Wongi::Engine::Network do
70
95
  engine << [1, :is, 2]
71
96
  engine << [2, :is, 3]
72
97
 
73
- expect( prod ).to have(1).tokens
98
+ expect(prod).to have(1).tokens
74
99
 
75
100
  engine.retract [1, :is, 2]
76
- expect( prod ).to have(0).tokens
77
- expect( deactivated[:X] ).to be == 1
78
- expect( deactivated[:Y] ).to be == 2
79
- expect( deactivated[:Z] ).to be == 3
80
-
101
+ expect(prod).to have(0).tokens
102
+ expect(deactivated[:X]).to be == 1
103
+ expect(deactivated[:Y]).to be == 2
104
+ expect(deactivated[:Z]).to be == 3
81
105
  end
82
106
 
83
107
  it 'retraction should reactivate neg nodes' do
108
+ prod = engine << rule { forall { neg 1, 2, 3 } }
84
109
 
85
- prod = engine << rule { forall { neg 1, 2, 3} }
86
-
87
- expect( prod ).to have(1).tokens
110
+ expect(prod).to have(1).tokens
88
111
 
89
- engine << [1, 2 ,3]
90
- expect( prod ).to have(0).tokens
112
+ engine << [1, 2, 3]
113
+ expect(prod).to have(0).tokens
91
114
 
92
115
  engine.retract [1, 2, 3]
93
- expect( prod ).to have(1).tokens
94
-
116
+ expect(prod).to have(1).tokens
95
117
  end
96
118
 
97
119
  describe 'retraction with neg nodes lower in the chain' do
98
-
99
- def expect_tokens n
100
- expect( prod ).to have(n).tokens
120
+ def expect_tokens(n)
121
+ expect(prod).to have(n).tokens
101
122
  end
102
123
 
103
- before :each do
104
-
124
+ before do
105
125
  engine << rule('retract') {
106
126
  forall {
107
127
  has :x, :u, :Y
108
128
  neg :Y, :w, :_
109
129
  }
110
130
  }
111
-
112
131
  end
113
132
 
114
- let( :prod ) { engine.productions['retract'] }
133
+ let(:prod) { engine.productions['retract'] }
115
134
 
116
135
  specify 'case 1' do
117
-
118
- engine << [:x, :u, :y]
136
+ engine << %i[x u y]
119
137
  expect_tokens 1
120
138
 
121
- engine << [:y, :w, :z]
139
+ engine << %i[y w z]
122
140
  expect_tokens 0
123
141
 
124
- engine.retract [:y, :w, :z]
142
+ engine.retract %i[y w z]
125
143
  expect_tokens 1
126
144
 
127
- engine.retract [:x, :u, :y]
145
+ engine.retract %i[x u y]
128
146
  expect_tokens 0
129
-
130
147
  end
131
148
 
132
149
  specify 'case 2' do
133
-
134
- engine << [:x, :u, :y]
150
+ engine << %i[x u y]
135
151
  expect_tokens 1
136
152
 
137
- engine << [:y, :w, :z]
153
+ engine << %i[y w z]
138
154
  expect_tokens 0
139
155
 
140
- engine.retract [:x, :u, :y]
156
+ engine.retract %i[x u y]
141
157
  expect_tokens 0
142
158
 
143
- engine.retract [:y, :w, :z]
159
+ engine.retract %i[y w z]
144
160
  expect_tokens 0
145
-
146
161
  end
147
162
 
148
163
  specify 'case 3' do
149
-
150
- engine << [:y, :w, :z]
164
+ engine << %i[y w z]
151
165
  expect_tokens 0
152
166
 
153
- engine << [:x, :u, :y]
167
+ engine << %i[x u y]
154
168
  expect_tokens 0
155
169
 
156
- engine.retract [:x, :u, :y]
170
+ engine.retract %i[x u y]
157
171
  expect_tokens 0
158
172
 
159
- engine.retract [:y, :w, :z]
173
+ engine.retract %i[y w z]
160
174
  expect_tokens 0
161
-
162
175
  end
163
176
 
164
177
  specify 'case 4' do
165
-
166
- engine << [:y, :w, :z]
178
+ engine << %i[y w z]
167
179
  expect_tokens 0
168
180
 
169
- engine << [:x, :u, :y]
181
+ engine << %i[x u y]
170
182
  expect_tokens 0
171
183
 
172
- engine.retract [:y, :w, :z]
184
+ engine.retract %i[y w z]
173
185
  expect_tokens 1
174
186
 
175
- engine.retract [:x, :u, :y]
187
+ engine.retract %i[x u y]
176
188
  expect_tokens 0
177
-
178
189
  end
179
-
180
190
  end
181
-
182
191
  end
data/spec/overlay_spec.rb CHANGED
@@ -12,7 +12,7 @@ describe Wongi::Engine::DataOverlay do
12
12
  }
13
13
  }
14
14
  engine.with_overlay { |overlay|
15
- overlay << [1,2,3]
15
+ overlay << [1, 2, 3]
16
16
  expect(production).to have(1).token
17
17
  }
18
18
  expect(production).to have(0).tokens
@@ -28,7 +28,7 @@ describe Wongi::Engine::DataOverlay do
28
28
  }
29
29
  }
30
30
  engine.with_overlay { |overlay|
31
- overlay << [1,2,3]
31
+ overlay << [1, 2, 3]
32
32
  expect(production).to have(1).token
33
33
  expect(engine.find(3, 4, 5)).not_to be_nil
34
34
  }
@@ -49,13 +49,12 @@ describe Wongi::Engine::DataOverlay do
49
49
  }
50
50
 
51
51
  engine.with_overlay { |overlay|
52
- overlay << [1,2,3]
52
+ overlay << [1, 2, 3]
53
53
  expect(production).to have(1).token
54
- expect(engine.find(:_, :_, :_)).not_to be_nil
54
+ expect(engine.find(:person, 'stuff', 6)).not_to be_nil
55
55
  }
56
56
 
57
57
  expect(production).to have(0).tokens
58
58
  expect(engine.find(:_, :_, :_)).to be_nil
59
59
  end
60
-
61
60
  end
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+ require 'securerandom'
3
+
4
+ describe 'aggregate' do
5
+ include Wongi::Engine::DSL
6
+
7
+ let(:engine) { Wongi::Engine.create }
8
+ let(:rule_name) { SecureRandom.alphanumeric(16) }
9
+ let(:production) { engine.productions[rule_name] }
10
+
11
+ context 'generic clause' do
12
+ it 'should return a single token' do
13
+ engine << rule(rule_name) do
14
+ forall {
15
+ aggregate :_, :weight, :_, on: :object, function: :min, assign: :X
16
+ }
17
+ end
18
+
19
+ expect(production.size).to be == 0
20
+
21
+ engine << [:apple, :weight, 5]
22
+ expect(production.size).to be == 1
23
+ expect(production.tokens.first[:X]).to be == 5
24
+
25
+ engine << [:pea, :weight, 2]
26
+ expect(production.size).to be == 1
27
+ expect(production.tokens.first[:X]).to be == 2
28
+
29
+ engine << [:melon, :weight, 15]
30
+ expect(production.size).to be == 1
31
+ expect(production.tokens.first[:X]).to be == 2
32
+
33
+ engine.retract [:pea, :weight, 2]
34
+ expect(production.size).to be == 1
35
+ expect(production.tokens.first[:X]).to be == 5
36
+
37
+ engine.retract [:apple, :weight, 5]
38
+ expect(production.size).to be == 1
39
+ expect(production.tokens.first[:X]).to be == 15
40
+
41
+ engine.retract [:melon, :weight, 15]
42
+ expect(production.size).to be == 0
43
+ end
44
+ end
45
+
46
+ context 'least' do
47
+ it 'works' do
48
+ engine << rule(rule_name) do
49
+ forall {
50
+ least :_, :weight, :_, on: :object, assign: :X
51
+ has :Fruit, :weight, :X
52
+ }
53
+ end
54
+
55
+ engine << [:apple, :weight, 5]
56
+ expect(production.size).to be == 1
57
+ expect(production.tokens.first[:X]).to be == 5
58
+ expect(production.tokens.first[:Fruit]).to be == :apple
59
+
60
+ engine << [:pea, :weight, 2]
61
+ expect(production.size).to be == 1
62
+ expect(production.tokens.first[:X]).to be == 2
63
+ expect(production.tokens.first[:Fruit]).to be == :pea
64
+
65
+ engine.retract [:pea, :weight, 2]
66
+ expect(production.size).to be == 1
67
+ expect(production.tokens.first[:X]).to be == 5
68
+ expect(production.tokens.first[:Fruit]).to be == :apple
69
+ end
70
+ end
71
+
72
+ context 'min' do
73
+ it 'works' do
74
+ engine << rule(rule_name) do
75
+ forall {
76
+ min :_, :weight, :_, on: :object, assign: :X
77
+ has :Fruit, :weight, :X
78
+ }
79
+ end
80
+
81
+ engine << [:apple, :weight, 5]
82
+ expect(production.size).to be == 1
83
+ expect(production.tokens.first[:X]).to be == 5
84
+ expect(production.tokens.first[:Fruit]).to be == :apple
85
+
86
+ engine << [:pea, :weight, 2]
87
+ expect(production.size).to be == 1
88
+ expect(production.tokens.first[:X]).to be == 2
89
+ expect(production.tokens.first[:Fruit]).to be == :pea
90
+
91
+ engine.retract [:pea, :weight, 2]
92
+ expect(production.size).to be == 1
93
+ expect(production.tokens.first[:X]).to be == 5
94
+ expect(production.tokens.first[:Fruit]).to be == :apple
95
+ end
96
+ end
97
+
98
+ context 'greatest' do
99
+ it 'works' do
100
+ engine << rule(rule_name) do
101
+ forall {
102
+ greatest :_, :weight, :_, on: :object, assign: :X
103
+ has :Fruit, :weight, :X
104
+ }
105
+ end
106
+
107
+ engine << [:pea, :weight, 2]
108
+ expect(production.size).to be == 1
109
+ expect(production.tokens.first[:X]).to be == 2
110
+ expect(production.tokens.first[:Fruit]).to be == :pea
111
+
112
+ engine << [:apple, :weight, 5]
113
+ expect(production.size).to be == 1
114
+ expect(production.tokens.first[:X]).to be == 5
115
+ expect(production.tokens.first[:Fruit]).to be == :apple
116
+
117
+ engine.retract [:apple, :weight, 5]
118
+ expect(production.size).to be == 1
119
+ expect(production.tokens.first[:X]).to be == 2
120
+ expect(production.tokens.first[:Fruit]).to be == :pea
121
+ end
122
+ end
123
+
124
+ context 'max' do
125
+ it 'works' do
126
+ engine << rule(rule_name) do
127
+ forall {
128
+ max :_, :weight, :_, on: :object, assign: :X
129
+ has :Fruit, :weight, :X
130
+ }
131
+ end
132
+
133
+ engine << [:pea, :weight, 2]
134
+ expect(production.size).to be == 1
135
+ expect(production.tokens.first[:X]).to be == 2
136
+ expect(production.tokens.first[:Fruit]).to be == :pea
137
+
138
+ engine << [:apple, :weight, 5]
139
+ expect(production.size).to be == 1
140
+ expect(production.tokens.first[:X]).to be == 5
141
+ expect(production.tokens.first[:Fruit]).to be == :apple
142
+
143
+ engine.retract [:apple, :weight, 5]
144
+ expect(production.size).to be == 1
145
+ expect(production.tokens.first[:X]).to be == 2
146
+ expect(production.tokens.first[:Fruit]).to be == :pea
147
+ end
148
+ end
149
+
150
+ context 'count' do
151
+ it 'works' do
152
+ engine << rule(rule_name) do
153
+ forall {
154
+ count :_, :weight, :_, assign: :Count
155
+ }
156
+ end
157
+
158
+ engine << [:pea, :weight, 1]
159
+ expect(production.size).to be == 1
160
+ expect(production.tokens.first[:Count]).to be == 1
161
+
162
+ engine << [:apple, :weight, 5]
163
+ expect(production.size).to be == 1
164
+ expect(production.tokens.first[:Count]).to be == 2
165
+
166
+ engine << [:watermelon, :weight, 15]
167
+ expect(production.size).to be == 1
168
+ expect(production.tokens.first[:Count]).to be == 3
169
+
170
+ engine.retract [:apple, :weight, 5]
171
+ expect(production.size).to be == 1
172
+ expect(production.tokens.first[:Count]).to be == 2
173
+ end
174
+
175
+ it 'works with a post-filter' do
176
+ engine << rule(rule_name) do
177
+ forall {
178
+ count :_, :weight, :_, assign: :Count
179
+ gte :Count, 3 # pass if at least 3 matching facts exist
180
+ }
181
+ end
182
+
183
+ engine << [:pea, :weight, 1]
184
+ expect(production.size).to be == 0
185
+
186
+ engine << [:apple, :weight, 5]
187
+ expect(production.size).to be == 0
188
+
189
+ engine << [:watermelon, :weight, 15]
190
+ expect(production.size).to be == 1
191
+ expect(production.tokens.first[:Count]).to be == 3
192
+
193
+ engine.retract [:apple, :weight, 5]
194
+ expect(production.size).to be == 0
195
+ end
196
+ end
197
+ end
@@ -1,21 +1,12 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "ANY rule" do
4
-
5
4
  include Wongi::Engine::DSL
6
5
 
7
- before :each do
8
- @engine = Wongi::Engine.create
9
- end
10
-
11
- def engine
12
- @engine
13
- end
6
+ let(:engine) { Wongi::Engine.create }
14
7
 
15
8
  context "with just one option" do
16
-
17
9
  it "should act like a positive matcher" do
18
-
19
10
  engine << rule('one-option') {
20
11
  forall {
21
12
  any {
@@ -33,15 +24,11 @@ describe "ANY rule" do
33
24
  engine << [3, 4, 5]
34
25
 
35
26
  expect(production.size).to eq(1)
36
-
37
27
  end
38
-
39
28
  end
40
29
 
41
30
  context "with several options" do
42
-
43
31
  specify "all matching branches must pass" do
44
-
45
32
  engine << rule('two-options') {
46
33
  forall {
47
34
  has 1, 2, :X
@@ -64,14 +51,12 @@ describe "ANY rule" do
64
51
  engine << [1, 2, 3]
65
52
  engine << [3, 4, 5]
66
53
  engine << [1, 2, "three"]
67
- engine << ["three", "four", "five"]
54
+ engine << %w[three four five]
68
55
 
69
56
  expect(production.size).to eq(2)
70
- expect( engine.collection(:threes) ).to include(3)
71
- expect( engine.collection(:threes) ).to include("three")
72
-
57
+ expect(engine.collection(:threes)).to include(3)
58
+ expect(engine.collection(:threes)).to include("three")
73
59
  end
74
-
75
60
  end
76
61
 
77
62
  context "with two options and same assignments" do
@@ -1,11 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "ASSIGN rule" do
4
-
5
- let( :engine ) { Wongi::Engine.create }
4
+ include Wongi::Engine::DSL
5
+ let(:engine) { Wongi::Engine.create }
6
6
 
7
7
  it "should assign simple expressions" do
8
-
9
8
  production = engine << rule {
10
9
  forall {
11
10
  assign :X do
@@ -15,7 +14,6 @@ describe "ASSIGN rule" do
15
14
  }
16
15
  expect(production.size).to eq(1)
17
16
  expect(production.tokens.first[:X]).to eq(42)
18
-
19
17
  end
20
18
 
21
19
  it 'should be available in the make section' do
@@ -35,7 +33,6 @@ describe "ASSIGN rule" do
35
33
  end
36
34
 
37
35
  it "should be able to access previous assignments" do
38
-
39
36
  production = engine << rule {
40
37
  forall {
41
38
  has 1, 2, :X
@@ -47,11 +44,9 @@ describe "ASSIGN rule" do
47
44
 
48
45
  engine << [1, 2, 5]
49
46
  expect(production.tokens.first[:Y]).to eq(10)
50
-
51
47
  end
52
48
 
53
49
  it 'should be deactivatable' do
54
-
55
50
  prod = engine << rule {
56
51
  forall {
57
52
  has 1, 2, :X
@@ -64,13 +59,12 @@ describe "ASSIGN rule" do
64
59
  engine << [1, 2, 5]
65
60
  engine.retract [1, 2, 5]
66
61
 
67
- expect( prod ).to have(0).tokens
68
-
62
+ expect(prod).to have(0).tokens
69
63
  end
70
64
 
71
65
  it 'should be evaluated once' do
72
66
  x = 0
73
- prod = engine << rule {
67
+ engine << rule {
74
68
  forall {
75
69
  has :a, :b, :c
76
70
  assign :T do
@@ -82,15 +76,15 @@ describe "ASSIGN rule" do
82
76
  gen :f, :g, :T
83
77
  }
84
78
  }
85
- engine << [:a, :b, :c]
79
+ engine << %i[a b c]
86
80
  expect(x).to be == 1
87
81
  end
88
82
 
89
- it 'should handle booleans' do
83
+ xit 'should handle booleans' do
90
84
  engine << rule do
91
- for_all {
85
+ forall {
92
86
  has :a, :b, :c
93
- assign :X do |token|
87
+ assign :X do |_token|
94
88
  false
95
89
  end
96
90
  }
@@ -98,7 +92,7 @@ describe "ASSIGN rule" do
98
92
  gen :d, :e, :X
99
93
  }
100
94
  end
101
- engine << [:a, :b, :c]
95
+ engine << %i[a b c]
96
+ expect(engine.find(:d, :e, false)).not_to be_nil
102
97
  end
103
-
104
98
  end
@@ -1,12 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Wongi::Engine::AssumingClause do
4
-
5
- let( :engine ) { Wongi::Engine.create }
4
+ include Wongi::Engine::DSL
5
+ let(:engine) { Wongi::Engine.create }
6
6
 
7
7
  it 'should include base rules' do
8
-
9
- engine << rule( :base ) {
8
+ engine << rule(:base) {
10
9
  forall {
11
10
  has :x, :y, :Z
12
11
  }
@@ -23,14 +22,12 @@ describe Wongi::Engine::AssumingClause do
23
22
  engine << [:x, :y, 2]
24
23
  engine << [1, :u, :a]
25
24
  engine << [2, :u, :b]
26
- result = Hash[ extended.tokens.map { |token| [ token[:Z], token[:W] ] } ]
27
- expect( result ).to eq(1 => :a, 2 => :b)
28
-
25
+ result = extended.tokens.to_h { |token| [token[:Z], token[:W]] }
26
+ expect(result).to eq(1 => :a, 2 => :b)
29
27
  end
30
28
 
31
29
  it 'should check for base rule\'s existence' do
32
-
33
- f = -> {
30
+ f = lambda {
34
31
  engine << rule {
35
32
  forall {
36
33
  assuming :base
@@ -38,14 +35,12 @@ describe Wongi::Engine::AssumingClause do
38
35
  }
39
36
  }
40
37
 
41
- expect( &f ).to raise_error Wongi::Engine::UndefinedBaseRule
42
-
38
+ expect(&f).to raise_error Wongi::Engine::UndefinedBaseRule
43
39
  end
44
40
 
45
41
  it 'should come first in a rule' do
46
-
47
- f = -> {
48
- engine << rule( :base ) {
42
+ f = lambda {
43
+ engine << rule(:base) {
49
44
  forall {
50
45
  has :x, :y, :Z
51
46
  }
@@ -59,8 +54,6 @@ describe Wongi::Engine::AssumingClause do
59
54
  }
60
55
  }
61
56
 
62
- expect( &f ).to raise_error Wongi::Engine::DefinitionError
63
-
57
+ expect(&f).to raise_error Wongi::Engine::DefinitionError
64
58
  end
65
-
66
59
  end