wongi-engine 0.3.5 → 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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +80 -0
- data/.travis.yml +8 -15
- data/Gemfile +4 -0
- data/README.md +3 -3
- data/Rakefile +1 -2
- data/examples/ex01.rb +1 -1
- data/examples/ex02.rb +3 -7
- data/examples/graphviz.rb +1 -1
- data/examples/rdf.rb +1 -1
- data/examples/timeline.rb +6 -6
- data/lib/wongi-engine/alpha_memory.rb +5 -9
- data/lib/wongi-engine/beta/aggregate_node.rb +93 -0
- data/lib/wongi-engine/beta/assignment_node.rb +10 -18
- data/lib/wongi-engine/beta/beta_memory.rb +20 -9
- data/lib/wongi-engine/beta/beta_node.rb +14 -22
- data/lib/wongi-engine/beta/filter_node.rb +12 -15
- data/lib/wongi-engine/beta/join_node.rb +47 -61
- data/lib/wongi-engine/beta/ncc_node.rb +17 -20
- data/lib/wongi-engine/beta/ncc_partner.rb +17 -17
- data/lib/wongi-engine/beta/neg_node.rb +37 -37
- data/lib/wongi-engine/beta/optional_node.rb +53 -60
- data/lib/wongi-engine/beta/or_node.rb +6 -9
- data/lib/wongi-engine/beta/production_node.rb +6 -9
- data/lib/wongi-engine/beta.rb +1 -0
- data/lib/wongi-engine/compiler.rb +38 -22
- data/lib/wongi-engine/core_ext.rb +11 -20
- data/lib/wongi-engine/data_overlay.rb +23 -26
- data/lib/wongi-engine/dsl/action/assign_action.rb +1 -1
- data/lib/wongi-engine/dsl/action/base.rb +1 -4
- data/lib/wongi-engine/dsl/action/error_generator.rb +9 -9
- data/lib/wongi-engine/dsl/action/simple_action.rb +14 -10
- data/lib/wongi-engine/dsl/action/simple_collector.rb +10 -25
- data/lib/wongi-engine/dsl/action/statement_generator.rb +15 -14
- data/lib/wongi-engine/dsl/action/trace_action.rb +9 -9
- data/lib/wongi-engine/dsl/any_rule.rb +16 -20
- data/lib/wongi-engine/dsl/assuming.rb +8 -15
- data/lib/wongi-engine/dsl/builder.rb +13 -12
- data/lib/wongi-engine/dsl/clause/aggregate.rb +21 -0
- data/lib/wongi-engine/dsl/clause/assign.rb +4 -4
- data/lib/wongi-engine/dsl/clause/fact.rb +10 -6
- data/lib/wongi-engine/dsl/clause/gen.rb +3 -5
- data/lib/wongi-engine/dsl/clause/generic.rb +7 -9
- data/lib/wongi-engine/dsl/generated.rb +6 -12
- data/lib/wongi-engine/dsl/ncc_subrule.rb +6 -9
- data/lib/wongi-engine/dsl/query.rb +12 -15
- data/lib/wongi-engine/dsl/rule.rb +45 -50
- data/lib/wongi-engine/dsl.rb +30 -16
- data/lib/wongi-engine/enumerators.rb +2 -1
- data/lib/wongi-engine/error.rb +6 -7
- data/lib/wongi-engine/filter/asserting_test.rb +4 -7
- data/lib/wongi-engine/filter/equality_test.rb +15 -18
- data/lib/wongi-engine/filter/filter_test.rb +3 -6
- data/lib/wongi-engine/filter/greater_than_or_equal_test.rb +5 -2
- data/lib/wongi-engine/filter/greater_than_test.rb +15 -18
- data/lib/wongi-engine/filter/inequality_test.rb +15 -18
- data/lib/wongi-engine/filter/less_than_or_equal_test.rb +5 -2
- data/lib/wongi-engine/filter/less_than_test.rb +15 -18
- data/lib/wongi-engine/filter.rb +1 -1
- data/lib/wongi-engine/graph.rb +13 -20
- data/lib/wongi-engine/network/collectable.rb +10 -14
- data/lib/wongi-engine/network/debug.rb +16 -24
- data/lib/wongi-engine/network.rb +110 -129
- data/lib/wongi-engine/ruleset.rb +18 -20
- data/lib/wongi-engine/template.rb +31 -30
- data/lib/wongi-engine/token.rb +33 -33
- data/lib/wongi-engine/version.rb +1 -1
- data/lib/wongi-engine/wme.rb +17 -23
- data/lib/wongi-engine/wme_match_data.rb +5 -9
- data/lib/wongi-engine.rb +0 -4
- data/spec/action_class_spec.rb +43 -49
- data/spec/beta_node_spec.rb +2 -8
- data/spec/bug_specs/issue_4_spec.rb +12 -20
- data/spec/dataset_spec.rb +3 -6
- data/spec/filter_specs/assert_test_spec.rb +12 -31
- data/spec/filter_specs/greater_than_equality_test_spec.rb +2 -5
- data/spec/filter_specs/less_test_spec.rb +7 -17
- data/spec/filter_specs/less_than_equality_test_spec.rb +3 -6
- data/spec/generation_spec.rb +45 -54
- data/spec/high_level_spec.rb +95 -141
- data/spec/network_spec.rb +77 -68
- data/spec/overlay_spec.rb +4 -5
- data/spec/rule_specs/aggregate_spec.rb +197 -0
- data/spec/rule_specs/any_rule_spec.rb +73 -19
- data/spec/rule_specs/assign_spec.rb +10 -16
- data/spec/rule_specs/assuming_spec.rb +10 -17
- data/spec/rule_specs/maybe_rule_spec.rb +4 -15
- data/spec/rule_specs/ncc_spec.rb +48 -65
- data/spec/rule_specs/negative_rule_spec.rb +13 -27
- data/spec/rule_specs/or_rule_spec.rb +3 -13
- data/spec/ruleset_spec.rb +11 -17
- data/spec/simple_action_spec.rb +4 -14
- data/spec/wme_spec.rb +14 -21
- data/wongi-engine.gemspec +22 -22
- metadata +19 -41
- data/.hgignore +0 -7
- data/spec/dsl_spec.rb +0 -9
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Wongi::Engine::AssumingClause do
|
4
|
-
|
5
|
-
let(
|
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 =
|
27
|
-
expect(
|
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(
|
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
|
-
|
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(
|
63
|
-
|
57
|
+
expect(&f).to raise_error Wongi::Engine::DefinitionError
|
64
58
|
end
|
65
|
-
|
66
59
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "MAYBE rule" do
|
4
|
-
|
5
|
-
let(
|
6
|
-
let(
|
4
|
+
include Wongi::Engine::DSL
|
5
|
+
let(:engine) { Wongi::Engine.create }
|
6
|
+
let(:maybe_rule) {
|
7
7
|
rule {
|
8
8
|
forall {
|
9
9
|
has 1, 2, :X
|
@@ -13,7 +13,6 @@ describe "MAYBE rule" do
|
|
13
13
|
}
|
14
14
|
|
15
15
|
it "should pass with existing facts" do
|
16
|
-
|
17
16
|
production = engine << maybe_rule
|
18
17
|
|
19
18
|
engine << [1, 2, 3]
|
@@ -23,11 +22,9 @@ describe "MAYBE rule" do
|
|
23
22
|
|
24
23
|
expect(production.tokens.first[:X]).to eq(3)
|
25
24
|
expect(production.tokens.first[:Y]).to eq(5)
|
26
|
-
|
27
25
|
end
|
28
26
|
|
29
27
|
it "should pass with missing facts" do
|
30
|
-
|
31
28
|
production = engine << maybe_rule
|
32
29
|
|
33
30
|
engine << [1, 2, 3]
|
@@ -36,11 +33,9 @@ describe "MAYBE rule" do
|
|
36
33
|
|
37
34
|
expect(production.tokens.first[:X]).to eq(3)
|
38
35
|
expect(production.tokens.first[:Y]).to be_nil
|
39
|
-
|
40
36
|
end
|
41
37
|
|
42
38
|
it "should pass with pre-added missing facts" do
|
43
|
-
|
44
39
|
engine << [1, 2, 3]
|
45
40
|
|
46
41
|
production = engine << maybe_rule
|
@@ -49,11 +44,9 @@ describe "MAYBE rule" do
|
|
49
44
|
|
50
45
|
expect(production.tokens.first[:X]).to eq(3)
|
51
46
|
expect(production.tokens.first[:Y]).to be_nil
|
52
|
-
|
53
47
|
end
|
54
48
|
|
55
49
|
it 'should pass with retracted facts' do
|
56
|
-
|
57
50
|
prod = engine << maybe_rule
|
58
51
|
|
59
52
|
engine << [1, 2, 3]
|
@@ -64,11 +57,9 @@ describe "MAYBE rule" do
|
|
64
57
|
|
65
58
|
expect(prod.tokens.first[:X]).to eq(3)
|
66
59
|
expect(prod.tokens.first[:Y]).to be_nil
|
67
|
-
|
68
60
|
end
|
69
61
|
|
70
62
|
it 'should work with repeated activations' do
|
71
|
-
|
72
63
|
prod = engine << maybe_rule
|
73
64
|
|
74
65
|
engine << [1, 2, 3]
|
@@ -84,7 +75,6 @@ describe "MAYBE rule" do
|
|
84
75
|
expect(prod.size).to eq(1)
|
85
76
|
expect(prod.tokens.first[:Y]).to be_nil
|
86
77
|
}
|
87
|
-
|
88
78
|
end
|
89
79
|
|
90
80
|
it 'should handle retracted parent tokens' do
|
@@ -95,7 +85,6 @@ describe "MAYBE rule" do
|
|
95
85
|
engine.retract [1, 2, 3]
|
96
86
|
|
97
87
|
expect(prod).to have(0).tokens
|
98
|
-
expect(engine.find(3,4,5).opt_join_results).to be_empty
|
88
|
+
expect(engine.find(3, 4, 5).opt_join_results).to be_empty
|
99
89
|
end
|
100
|
-
|
101
90
|
end
|
data/spec/rule_specs/ncc_spec.rb
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Wongi::Engine::NccNode do
|
4
|
-
|
5
|
-
|
6
|
-
@engine = Wongi::Engine.create
|
7
|
-
end
|
8
|
-
|
9
|
-
def engine
|
10
|
-
@engine
|
11
|
-
end
|
4
|
+
include Wongi::Engine::DSL
|
5
|
+
let(:engine) { Wongi::Engine.create }
|
12
6
|
|
13
7
|
def ncc_rule
|
14
8
|
rule('ncc') {
|
@@ -36,7 +30,6 @@ describe Wongi::Engine::NccNode do
|
|
36
30
|
end
|
37
31
|
|
38
32
|
it 'should pass with a mismatching subchain' do
|
39
|
-
|
40
33
|
engine << ncc_rule
|
41
34
|
production = engine.productions['ncc']
|
42
35
|
|
@@ -51,11 +44,9 @@ describe Wongi::Engine::NccNode do
|
|
51
44
|
engine << [3, 4, 5]
|
52
45
|
|
53
46
|
expect(production).to have(0).token
|
54
|
-
|
55
47
|
end
|
56
48
|
|
57
49
|
it 'should remain consistent after retraction' do
|
58
|
-
|
59
50
|
engine << ncc_rule
|
60
51
|
production = engine.productions['ncc']
|
61
52
|
|
@@ -66,15 +57,13 @@ describe Wongi::Engine::NccNode do
|
|
66
57
|
expect(production).to have(0).tokens
|
67
58
|
|
68
59
|
engine.retract [3, 4, 5]
|
69
|
-
expect(
|
60
|
+
expect(production).to have(1).token
|
70
61
|
|
71
62
|
engine.retract ["base", "is", 1]
|
72
63
|
expect(production).to have(0).tokens
|
73
|
-
|
74
64
|
end
|
75
65
|
|
76
66
|
it 'can handle an alpha node template introduced after the negative-conjunctive-condition' do
|
77
|
-
|
78
67
|
engine << ncc_rule_post_has
|
79
68
|
|
80
69
|
production = engine.productions['ncc post has']
|
@@ -83,30 +72,28 @@ describe Wongi::Engine::NccNode do
|
|
83
72
|
engine << [1, 2, 3]
|
84
73
|
engine << [3, 4, 5]
|
85
74
|
|
86
|
-
expect(
|
75
|
+
expect(production).to have(0).tokens
|
87
76
|
|
88
77
|
engine.retract [3, 4, 5]
|
89
|
-
expect(
|
78
|
+
expect(production).to have(1).tokens
|
90
79
|
|
91
80
|
engine.retract ["base", "is", 1]
|
92
|
-
expect(
|
93
|
-
|
81
|
+
expect(production).to have(0).tokens
|
94
82
|
end
|
95
83
|
|
96
84
|
it 'should clean up correctly' do
|
97
|
-
|
98
85
|
engine.rule :rule1 do
|
99
86
|
forall {
|
100
87
|
has :light_kitchen, :value, :on
|
101
88
|
}
|
102
89
|
make {
|
103
|
-
#trace values: true, generation: true
|
90
|
+
# trace values: true, generation: true
|
104
91
|
gen rule.name, :light_bathroom, :on
|
105
92
|
gen rule.name, :want_action_for, :light_bathroom
|
106
93
|
}
|
107
94
|
end
|
108
95
|
|
109
|
-
|
96
|
+
engine.rule "action" do
|
110
97
|
forall {
|
111
98
|
has :Requestor, :want_action_for, :Actor
|
112
99
|
has :Requestor, :Actor, :Value
|
@@ -119,7 +106,7 @@ describe Wongi::Engine::NccNode do
|
|
119
106
|
}
|
120
107
|
}
|
121
108
|
make {
|
122
|
-
#trace values: true, generation: true
|
109
|
+
# trace values: true, generation: true
|
123
110
|
gen :Actor, :value, :Value
|
124
111
|
gen :Actor, :last_user, :Requestor
|
125
112
|
}
|
@@ -130,41 +117,39 @@ describe Wongi::Engine::NccNode do
|
|
130
117
|
engine << [:poweruser, :priority, 3]
|
131
118
|
engine << [:god, :priority, 4]
|
132
119
|
|
133
|
-
engine << [
|
134
|
-
engine << [
|
135
|
-
expect(
|
136
|
-
expect(
|
120
|
+
engine << %i[user want_action_for light_bathroom]
|
121
|
+
engine << %i[user light_bathroom off]
|
122
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :off)]
|
123
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :user)]
|
137
124
|
|
138
|
-
engine << [
|
139
|
-
expect(
|
140
|
-
expect(
|
125
|
+
engine << %i[light_kitchen value on]
|
126
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :on)]
|
127
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :rule1)]
|
141
128
|
|
142
|
-
engine << [
|
143
|
-
engine << [
|
144
|
-
expect(
|
145
|
-
expect(
|
146
|
-
|
147
|
-
engine << [:god, :want_action_for, :light_bathroom]
|
148
|
-
engine << [:god, :light_bathroom, :let_there_be_light]
|
149
|
-
expect( engine.select(:light_bathroom, :value, :_) ).to be == [ Wongi::Engine::WME.new(:light_bathroom, :value, :let_there_be_light) ]
|
150
|
-
expect( engine.select(:light_bathroom, :last_user, :_) ).to be == [ Wongi::Engine::WME.new(:light_bathroom, :last_user, :god) ]
|
129
|
+
engine << %i[poweruser want_action_for light_bathroom]
|
130
|
+
engine << %i[poweruser light_bathroom super_on]
|
131
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :super_on)]
|
132
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :poweruser)]
|
151
133
|
|
134
|
+
engine << %i[god want_action_for light_bathroom]
|
135
|
+
engine << %i[god light_bathroom let_there_be_light]
|
136
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :let_there_be_light)]
|
137
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :god)]
|
152
138
|
end
|
153
139
|
|
154
140
|
it 'should clean up correctly with a different activation order' do
|
155
|
-
|
156
141
|
engine.rule :rule1 do
|
157
142
|
forall {
|
158
143
|
has :light_kitchen, :value, :on
|
159
144
|
}
|
160
145
|
make {
|
161
|
-
#trace values: true, generation: true
|
146
|
+
# trace values: true, generation: true
|
162
147
|
gen rule.name, :light_bathroom, :on
|
163
148
|
gen rule.name, :want_action_for, :light_bathroom
|
164
149
|
}
|
165
150
|
end
|
166
151
|
|
167
|
-
|
152
|
+
engine.rule "action" do
|
168
153
|
forall {
|
169
154
|
has :Requestor, :want_action_for, :Actor
|
170
155
|
has :Requestor, :Actor, :Value
|
@@ -177,7 +162,7 @@ describe Wongi::Engine::NccNode do
|
|
177
162
|
}
|
178
163
|
}
|
179
164
|
make {
|
180
|
-
#trace values: true, generation: true
|
165
|
+
# trace values: true, generation: true
|
181
166
|
gen :Actor, :value, :Value
|
182
167
|
gen :Actor, :last_user, :Requestor
|
183
168
|
}
|
@@ -188,25 +173,24 @@ describe Wongi::Engine::NccNode do
|
|
188
173
|
engine << [:poweruser, :priority, 3]
|
189
174
|
engine << [:god, :priority, 4]
|
190
175
|
|
191
|
-
engine << [
|
192
|
-
engine << [
|
193
|
-
expect(
|
194
|
-
expect(
|
176
|
+
engine << %i[user want_action_for light_bathroom]
|
177
|
+
engine << %i[user light_bathroom off]
|
178
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :off)]
|
179
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :user)]
|
195
180
|
|
196
|
-
engine << [
|
197
|
-
expect(
|
198
|
-
expect(
|
181
|
+
engine << %i[light_kitchen value on]
|
182
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :off)]
|
183
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :user)]
|
199
184
|
|
200
|
-
engine << [
|
201
|
-
engine << [
|
202
|
-
expect(
|
203
|
-
expect(
|
204
|
-
|
205
|
-
engine << [:god, :want_action_for, :light_bathroom]
|
206
|
-
engine << [:god, :light_bathroom, :let_there_be_light]
|
207
|
-
expect( engine.select(:light_bathroom, :value, :_) ).to be == [ Wongi::Engine::WME.new(:light_bathroom, :value, :let_there_be_light) ]
|
208
|
-
expect( engine.select(:light_bathroom, :last_user, :_) ).to be == [ Wongi::Engine::WME.new(:light_bathroom, :last_user, :god) ]
|
185
|
+
engine << %i[poweruser want_action_for light_bathroom]
|
186
|
+
engine << %i[poweruser light_bathroom super_on]
|
187
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :super_on)]
|
188
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :poweruser)]
|
209
189
|
|
190
|
+
engine << %i[god want_action_for light_bathroom]
|
191
|
+
engine << %i[god light_bathroom let_there_be_light]
|
192
|
+
expect(engine.select(:light_bathroom, :value, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :value, :let_there_be_light)]
|
193
|
+
expect(engine.select(:light_bathroom, :last_user, :_)).to be == [Wongi::Engine::WME.new(:light_bathroom, :last_user, :god)]
|
210
194
|
end
|
211
195
|
|
212
196
|
it 'should ncc-deactivate without destroying tokens' do
|
@@ -233,9 +217,9 @@ describe Wongi::Engine::NccNode do
|
|
233
217
|
}
|
234
218
|
}
|
235
219
|
|
236
|
-
%w
|
237
|
-
%w
|
238
|
-
engine << [
|
220
|
+
%w[math science english bio].each { |req| engine << [req, :is_a, :requirement] }
|
221
|
+
%w[CourseA CourseB CourseC].each { |course| engine << [course, :is_a, :course] }
|
222
|
+
engine << ["StudentA", :is_a, :student]
|
239
223
|
|
240
224
|
engine << ["CourseA", "math", 50]
|
241
225
|
engine << ["CourseA", "science", 50]
|
@@ -250,9 +234,9 @@ describe Wongi::Engine::NccNode do
|
|
250
234
|
engine << ["StudentA", "science", 60]
|
251
235
|
engine << ["StudentA", "bio", 40]
|
252
236
|
|
253
|
-
expect(engine.find
|
254
|
-
expect(engine.find
|
255
|
-
expect(engine.find
|
237
|
+
expect(engine.find("StudentA", :passes_for, "CourseA")).not_to be_nil
|
238
|
+
expect(engine.find("StudentA", :passes_for, "CourseB")).to be_nil
|
239
|
+
expect(engine.find("StudentA", :passes_for, "CourseC")).to be_nil
|
256
240
|
end
|
257
241
|
|
258
242
|
specify 'regression #71' do
|
@@ -270,5 +254,4 @@ describe Wongi::Engine::NccNode do
|
|
270
254
|
|
271
255
|
expect(prod).to have(1).tokens
|
272
256
|
end
|
273
|
-
|
274
257
|
end
|
@@ -1,19 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "negative rule" do
|
4
|
-
|
5
|
-
|
6
|
-
@engine = Wongi::Engine.create
|
7
|
-
end
|
8
|
-
|
9
|
-
def engine
|
10
|
-
@engine
|
11
|
-
end
|
4
|
+
include Wongi::Engine::DSL
|
5
|
+
let(:engine) { Wongi::Engine.create }
|
12
6
|
|
13
7
|
it "should not introduce variables" do
|
14
|
-
|
15
8
|
proc = lambda {
|
16
|
-
|
17
9
|
engine << rule('one-option') {
|
18
10
|
forall {
|
19
11
|
neg :Foo, :bar, :_
|
@@ -24,15 +16,12 @@ describe "negative rule" do
|
|
24
16
|
}
|
25
17
|
}
|
26
18
|
}
|
27
|
-
|
28
19
|
}
|
29
20
|
|
30
|
-
expect(
|
31
|
-
|
21
|
+
expect(&proc).to raise_error(Wongi::Engine::DefinitionError)
|
32
22
|
end
|
33
23
|
|
34
24
|
specify "variable example 1" do
|
35
|
-
|
36
25
|
prod = engine << rule {
|
37
26
|
forall {
|
38
27
|
has :x, :y, :Z
|
@@ -41,15 +30,13 @@ describe "negative rule" do
|
|
41
30
|
}
|
42
31
|
|
43
32
|
engine << [:x, :y, 1]
|
44
|
-
expect(
|
33
|
+
expect(prod).to have(1).tokens
|
45
34
|
|
46
35
|
engine << [:a, :b, 1]
|
47
|
-
expect(
|
48
|
-
|
36
|
+
expect(prod).to have(0).tokens
|
49
37
|
end
|
50
38
|
|
51
39
|
specify "variable example 1" do
|
52
|
-
|
53
40
|
prod = engine << rule {
|
54
41
|
forall {
|
55
42
|
has :x, :y, :Z
|
@@ -59,11 +46,10 @@ describe "negative rule" do
|
|
59
46
|
|
60
47
|
engine << [:a, :b, 1]
|
61
48
|
engine << [:x, :y, 1]
|
62
|
-
expect(
|
49
|
+
expect(prod).to have(0).tokens
|
63
50
|
|
64
51
|
engine.retract [:a, :b, 1]
|
65
|
-
expect(
|
66
|
-
|
52
|
+
expect(prod).to have(1).tokens
|
67
53
|
end
|
68
54
|
|
69
55
|
# it "should not create infinite feedback loops by default" do
|
@@ -82,9 +68,8 @@ describe "negative rule" do
|
|
82
68
|
# end
|
83
69
|
|
84
70
|
it "should create infinite feedback loops with unsafe option" do
|
85
|
-
|
86
71
|
counter = 0
|
87
|
-
exception = Class.new(
|
72
|
+
exception = Class.new(StandardError)
|
88
73
|
|
89
74
|
proc = lambda {
|
90
75
|
engine << rule('feedback') {
|
@@ -92,14 +77,15 @@ describe "negative rule" do
|
|
92
77
|
neg :a, :b, :_, unsafe: true
|
93
78
|
}
|
94
79
|
make {
|
95
|
-
action {
|
80
|
+
action {
|
81
|
+
counter += 1
|
82
|
+
raise exception if counter > 5
|
83
|
+
}
|
96
84
|
gen :a, :b, :c
|
97
85
|
}
|
98
86
|
}
|
99
87
|
}
|
100
88
|
|
101
|
-
expect(
|
102
|
-
|
89
|
+
expect(&proc).to raise_error(exception)
|
103
90
|
end
|
104
|
-
|
105
91
|
end
|
@@ -1,29 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "ANY rule" do
|
4
|
-
|
5
4
|
include Wongi::Engine::DSL
|
6
5
|
|
7
|
-
|
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 two options' do
|
16
|
-
|
17
9
|
let :production do
|
18
10
|
engine << rule do
|
19
11
|
forall {
|
20
12
|
any {
|
21
13
|
option {
|
22
14
|
has :A, :path1, :_
|
23
|
-
}
|
15
|
+
}
|
24
16
|
option {
|
25
17
|
has :A, :path2, :_
|
26
|
-
}
|
18
|
+
}
|
27
19
|
}
|
28
20
|
}
|
29
21
|
end
|
@@ -44,7 +36,5 @@ describe "ANY rule" do
|
|
44
36
|
engine << [:x, :path2, true]
|
45
37
|
expect(production.tokens).to have(2).items
|
46
38
|
end
|
47
|
-
|
48
39
|
end
|
49
|
-
|
50
40
|
end
|
data/spec/ruleset_spec.rb
CHANGED
@@ -1,54 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Wongi::Engine::Ruleset do
|
4
|
-
|
5
|
-
before :each do
|
4
|
+
before do
|
6
5
|
Wongi::Engine::Ruleset.reset
|
7
6
|
end
|
8
7
|
|
9
8
|
context 'initially' do
|
10
|
-
|
11
9
|
it 'should have no rules' do
|
12
|
-
expect(
|
10
|
+
expect(Wongi::Engine::Ruleset.rulesets).to be_empty
|
13
11
|
end
|
14
|
-
|
15
12
|
end
|
16
13
|
|
17
14
|
context 'when creating' do
|
18
|
-
|
19
15
|
it 'should not register itself when not given a name' do
|
20
16
|
ruleset = Wongi::Engine::Ruleset.new
|
21
|
-
expect(
|
22
|
-
expect(
|
17
|
+
expect(ruleset.name).to be_nil
|
18
|
+
expect(Wongi::Engine::Ruleset.rulesets).to be_empty
|
23
19
|
end
|
24
20
|
|
25
21
|
it 'should have a name' do
|
26
22
|
ruleset = Wongi::Engine::Ruleset.new 'testing-ruleset'
|
27
|
-
expect(
|
23
|
+
expect(ruleset.name).to be == 'testing-ruleset'
|
28
24
|
end
|
29
25
|
|
30
26
|
it 'should register itself when given a name' do
|
31
27
|
ruleset = Wongi::Engine::Ruleset.new 'testing-ruleset'
|
32
|
-
expect(
|
33
|
-
expect(
|
28
|
+
expect(Wongi::Engine::Ruleset.rulesets).not_to be_empty
|
29
|
+
expect(Wongi::Engine::Ruleset[ruleset.name]).to be == ruleset
|
34
30
|
end
|
35
|
-
|
36
31
|
end
|
37
32
|
|
38
33
|
it 'should be able to clear registered rulesets' do
|
39
|
-
|
34
|
+
_ = Wongi::Engine::Ruleset.new 'testing-ruleset'
|
40
35
|
Wongi::Engine::Ruleset.reset
|
41
|
-
expect(
|
36
|
+
expect(Wongi::Engine::Ruleset.rulesets).to be_empty
|
42
37
|
end
|
43
38
|
|
44
39
|
it 'should install creating rules into a rete' do
|
45
40
|
rete = double 'rete'
|
46
41
|
|
47
42
|
ruleset = Wongi::Engine::Ruleset.new
|
48
|
-
rule = ruleset.rule(
|
43
|
+
rule = ruleset.rule('test-rule') {}
|
49
44
|
|
50
|
-
expect(
|
45
|
+
expect(rete).to receive(:<<).with(rule).once
|
51
46
|
ruleset.install rete
|
52
47
|
end
|
53
|
-
|
54
48
|
end
|
data/spec/simple_action_spec.rb
CHANGED
@@ -1,20 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Wongi::Engine::DSL::Action::SimpleAction do
|
4
|
-
|
5
|
-
before :each do
|
6
|
-
@rete = Wongi::Engine::Network.new
|
7
|
-
end
|
8
|
-
|
9
|
-
def rete
|
10
|
-
@rete
|
11
|
-
end
|
4
|
+
let(:engine) { Wongi::Engine.create }
|
12
5
|
|
13
6
|
it 'should work with blocks' do
|
14
|
-
|
15
7
|
count = 0
|
16
8
|
|
17
|
-
|
9
|
+
engine.rule do
|
18
10
|
forall {
|
19
11
|
has 1, 2, :X
|
20
12
|
}
|
@@ -27,14 +19,12 @@ describe Wongi::Engine::DSL::Action::SimpleAction do
|
|
27
19
|
|
28
20
|
expect(count).to eq(0)
|
29
21
|
|
30
|
-
|
22
|
+
engine << [1, 2, 3]
|
31
23
|
|
32
24
|
expect(count).to eq(1)
|
33
25
|
|
34
|
-
|
26
|
+
engine << [1, 2, 4]
|
35
27
|
|
36
28
|
expect(count).to eq(2)
|
37
|
-
|
38
29
|
end
|
39
|
-
|
40
30
|
end
|