wongi-engine 0.3.2 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 31288187561162fa80c551275812a33dac1b1ce0
4
- data.tar.gz: d296f211ba4575ccab21182d03d9588e2910482f
2
+ SHA256:
3
+ metadata.gz: 5d9f803da98de1a0ec47f26a1adc83940f6ef2d3e8dbfc3dbfb9527c9efe4daf
4
+ data.tar.gz: 3d1ace03974a04999b3e4f969c64d0bad2b4da99dc11606db06b1723d056b881
5
5
  SHA512:
6
- metadata.gz: c63c6fa2e5ff49de30f6c6761c20df5c8d1935e51a460e8a9c8f4ae898e710a88810e630c127dd18ec83c73a490d718f4076b48b367961f08343f8bfba61bcc2
7
- data.tar.gz: 404bbafd48cb571a8baaa657d6af5c4cec93492f54321e61e863f009e3aed867b1165b4e1c5afff9422803de7451c7ed25ba8c9d9721ebb1c9c63cccb60b428f
6
+ metadata.gz: e7d0c9d09716e02cb60256f048b97d04742733e8587c110a8e3b80b0f641e0bc213f8a3baea543f89a3f4f454a7f9f987321b66b0ed6decd530d7ec568cdbe11
7
+ data.tar.gz: e5e3f2158f9975ad23aa7c4115886c17c4b92529967d97395f39c7a28d608dcf2adc7827cecdc9b6bcb1dd8200699c9ad61c8997e638c07cb15534bdbaa61701
data/.travis.yml CHANGED
@@ -1,10 +1,13 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.10
4
- - 2.2.6
5
- - 2.3.3
6
- - 2.4.0
7
- - jruby-9.0
3
+ - 2.1
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
9
+ - 2.7
10
+ - jruby
8
11
  sudo: false
9
12
  notifications:
10
13
  hipchat:
@@ -58,7 +58,7 @@ module Wongi
58
58
  def refresh_child child
59
59
  tokens.each do |token|
60
60
  if token.ncc_results.empty?
61
- child.beta_activate Token.new( child, t, nil, { } )
61
+ child.beta_activate Token.new( child, token, nil, { } )
62
62
  end
63
63
  end
64
64
  end
@@ -1,6 +1,6 @@
1
1
  module Wongi
2
2
  module Engine
3
-
3
+
4
4
  class ProductionNode < BetaMemory
5
5
 
6
6
  attr_accessor :tracer
@@ -49,7 +49,7 @@ module Wongi::Engine
49
49
  def join_node(condition, tests, assignment)
50
50
  alpha = rete.compile_alpha(condition)
51
51
  beta_memory
52
- self.node = if existing = node.children.find { |n| n.is_a?(JoinNode) && n.equivalent?(alpha, tests, assignment) }
52
+ self.node = if existing = node.children.find { |n| n.is_a?(JoinNode) && n.equivalent?(alpha, tests, assignment) && !n.children.map(&:class).include?(Wongi::Engine::OrNode) }
53
53
  existing
54
54
  else
55
55
  JoinNode.new(node, tests, assignment).tap do |join|
@@ -32,7 +32,7 @@ module Wongi::Engine
32
32
  elsif @deaction.respond_to? :call
33
33
  @deaction.call token
34
34
  elsif @deaction.respond_to? :deexecute
35
- @deaction.execute token
35
+ @deaction.deexecute token
36
36
  end
37
37
  end
38
38
 
@@ -43,7 +43,7 @@ module Wongi::Engine
43
43
  elsif @reaction.respond_to? :call
44
44
  @reaction.call token, newtoken
45
45
  elsif @reaction.respond_to? :reexecute
46
- @reaction.execute token, newtoken
46
+ @reaction.reexecute token, newtoken
47
47
  end
48
48
  end
49
49
 
@@ -81,9 +81,15 @@ module Wongi::Engine::DSL
81
81
  clause :less
82
82
  accept Wongi::Engine::LessThanTest
83
83
 
84
+ clause :lte
85
+ accept Wongi::Engine::LessThanOrEqualTest
86
+
84
87
  clause :greater
85
88
  accept Wongi::Engine::GreaterThanTest
86
89
 
90
+ clause :gte
91
+ accept Wongi::Engine::GreaterThanOrEqualTest
92
+
87
93
  clause :assert, :dynamic
88
94
  accept Wongi::Engine::AssertingTest
89
95
 
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module Wongi::Engine
3
+ class GreaterThanOrEqualTest < FilterTest
4
+ attr_reader :x, :y
5
+
6
+ def initialize(x, y)
7
+ @x = x
8
+ @y = y
9
+ end
10
+
11
+ def passes?(token)
12
+ x = if Template.variable? @x
13
+ token[@x]
14
+ else
15
+ @x
16
+ end
17
+
18
+ y = if Template.variable? @y
19
+ token[@y]
20
+ else
21
+ @y
22
+ end
23
+
24
+ return false if x == :_ || y == :_
25
+ x >= y
26
+ end
27
+
28
+ def ==(other)
29
+ super && x == other.x && y == other.y
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module Wongi::Engine
3
+ class LessThanOrEqualTest < FilterTest
4
+ attr_reader :x, :y
5
+
6
+ def initialize(x, y)
7
+ @x = x
8
+ @y = y
9
+ end
10
+
11
+ def passes?(token)
12
+ x = if Template.variable? @x
13
+ token[@x]
14
+ else
15
+ @x
16
+ end
17
+
18
+ y = if Template.variable? @y
19
+ token[@y]
20
+ else
21
+ @y
22
+ end
23
+
24
+ return false if x == :_ || y == :_
25
+ x <= y
26
+ end
27
+
28
+ def ==(other)
29
+ super && x == other.x && y == other.y
30
+ end
31
+ end
32
+ end
@@ -3,4 +3,6 @@ require 'wongi-engine/filter/equality_test'
3
3
  require 'wongi-engine/filter/inequality_test'
4
4
  require 'wongi-engine/filter/asserting_test'
5
5
  require 'wongi-engine/filter/less_than_test'
6
- require 'wongi-engine/filter/greater_than_test'
6
+ require 'wongi-engine/filter/greater_than_test'
7
+ require 'wongi-engine/filter/less_than_or_equal_test'
8
+ require 'wongi-engine/filter/greater_than_or_equal_test'
@@ -1,5 +1,5 @@
1
1
  module Wongi
2
2
  module Engine
3
- VERSION = "0.3.2"
3
+ VERSION = "0.3.6"
4
4
  end
5
5
  end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe 'action classes' do
5
+
6
+ include Wongi::Engine::DSL
7
+
8
+ let :engine do
9
+ Wongi::Engine.create
10
+ end
11
+
12
+ let :action_class do
13
+ Class.new do
14
+ class << self
15
+ attr_accessor :execute_body
16
+ attr_accessor :deexecute_body
17
+ end
18
+
19
+ def execute(token)
20
+ self.class.execute_body.call(token)
21
+ end
22
+
23
+ def deexecute(token)
24
+ self.class.deexecute_body.call(token)
25
+ end
26
+ end
27
+ end
28
+
29
+ it 'should have appropriate callbacks executed' do
30
+
31
+ executed = 0
32
+ deexecuted = 0
33
+
34
+ klass = action_class
35
+
36
+ klass.execute_body = lambda do |token|
37
+ executed += 1
38
+ end
39
+ klass.deexecute_body = lambda do |token|
40
+ deexecuted += 1
41
+ end
42
+
43
+ engine << rule {
44
+ forall {
45
+ has :A, :x, :B
46
+ }
47
+ make {
48
+ action klass
49
+ }
50
+ }
51
+
52
+ engine << [1, :x, 2]
53
+ expect(executed).to be == 1
54
+ expect(deexecuted).to be == 0
55
+
56
+ engine.retract [1, :x, 2]
57
+ expect(executed).to be == 1
58
+ expect(deexecuted).to be == 1
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Greater Than Or Equal test' do
6
+ before :each do
7
+ @engine = Wongi::Engine.create
8
+ end
9
+
10
+ attr_reader :engine
11
+
12
+ attr_reader :production
13
+
14
+ def test_rule(&block)
15
+ @production = (engine << rule('test-rule', &block))
16
+ end
17
+
18
+ it 'should interact with optional node correctly' do
19
+ # before the fix, filters would try to piggy-back on optional templates
20
+
21
+ test_rule do
22
+ forall do
23
+ has :Number, :assign_check, :_
24
+ gte :Number, 6
25
+ end
26
+ end
27
+
28
+ engine << [6, :assign_check, nil]
29
+ engine << [7, :assign_check, nil]
30
+ engine << [5, :assign_check, nil]
31
+ expect(@production.size).to eq(2)
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Less Than Or Equal test' do
6
+ before :each do
7
+ @engine = Wongi::Engine.create
8
+ end
9
+
10
+ attr_reader :engine
11
+
12
+ attr_reader :production
13
+
14
+ def test_rule(&block)
15
+ @production = (engine << rule('test-rule', &block))
16
+ end
17
+
18
+ it 'should interact with optional node correctly' do
19
+ # before the fix, filters would try to piggy-back on optional templates
20
+
21
+ test_rule do
22
+ forall do
23
+ has :Number, :assign_check, :_
24
+ lte :Number, 6
25
+ end
26
+ end
27
+
28
+ engine << [5, :assign_check, nil]
29
+ engine << [6, :assign_check, nil]
30
+ engine << [7, :assign_check, nil] #should not pass
31
+ expect(@production.size).to eq(2)
32
+ end
33
+ end
@@ -106,4 +106,73 @@ describe "ANY rule" do
106
106
  end
107
107
  end
108
108
 
109
+ describe "ordering rules" do
110
+ let :any_stale_pastry_rule do
111
+ rule do
112
+ forall {
113
+ # has :A, :name, :Name # uncomment this line will make test pass
114
+ any {
115
+ option {
116
+ has :A, :name, 'Donut'
117
+ }
118
+ option {
119
+ has :A, :name, 'Cookie'
120
+ }
121
+ }
122
+ has :A, :condition, 'stale' # moving this line above 'any' will make test pass
123
+ }
124
+ make {
125
+ collect :A, :stale_pastries
126
+ }
127
+ end
128
+ end
129
+
130
+ let :fresh_donut_rule do
131
+ rule do
132
+ forall {
133
+ has :A, :name, 'Donut'
134
+ has :A, :condition, 'fresh'
135
+ }
136
+ make {
137
+ collect :A, :fresh_donuts
138
+ }
139
+ end
140
+ end
141
+
142
+ let :fresh_cookie_rule do
143
+ rule do
144
+ forall {
145
+ # swapping the following lines will make test pass
146
+ has :A, :name, 'Cookie'
147
+ has :A, :condition, 'fresh'
148
+ }
149
+ make {
150
+ collect :A, :fresh_cookies
151
+ }
152
+ end
153
+ end
154
+
155
+ before do
156
+ engine << any_stale_pastry_rule # commenting this rule, or moving it to end of rules will make test pass
157
+
158
+ engine << fresh_donut_rule
159
+ engine << fresh_cookie_rule # commenting this rule will make test pass
160
+
161
+ engine << [:donut, :name, 'Donut']
162
+ engine << [:donut, :condition, 'fresh']
163
+ end
164
+
165
+ it 'has no fresh cookies' do
166
+ # this expectation fails; the collection contains [:donut]!
167
+ expect(engine.collection(:fresh_cookies)).to match_array([])
168
+ end
169
+
170
+ it 'has one fresh donut' do
171
+ expect(engine.collection(:fresh_donuts)).to match_array([:donut])
172
+ end
173
+
174
+ it 'has no stale pastries' do
175
+ expect(engine.collection(:stale_pastries)).to match_array([])
176
+ end
177
+ end
109
178
  end
@@ -255,4 +255,20 @@ describe Wongi::Engine::NccNode do
255
255
  expect(engine.find "StudentA", :passes_for, "CourseC").to be_nil
256
256
  end
257
257
 
258
+ specify 'regression #71' do
259
+ prod = engine << rule {
260
+ forall {
261
+ none {
262
+ has "TestSet", :contains, :B
263
+ has "MatchSet", :contains, :B
264
+ }
265
+ }
266
+ }
267
+ engine << ["TestSet", :contains, "not matching"]
268
+ engine << ["MatchSet", :contains, "match 1"]
269
+ engine << ["MatchSet", :contains, "match 2"]
270
+
271
+ expect(prod).to have(1).tokens
272
+ end
273
+
258
274
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wongi-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valeri Sokolov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-21 00:00:00.000000000 Z
11
+ date: 2021-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -131,8 +131,10 @@ files:
131
131
  - lib/wongi-engine/filter/asserting_test.rb
132
132
  - lib/wongi-engine/filter/equality_test.rb
133
133
  - lib/wongi-engine/filter/filter_test.rb
134
+ - lib/wongi-engine/filter/greater_than_or_equal_test.rb
134
135
  - lib/wongi-engine/filter/greater_than_test.rb
135
136
  - lib/wongi-engine/filter/inequality_test.rb
137
+ - lib/wongi-engine/filter/less_than_or_equal_test.rb
136
138
  - lib/wongi-engine/filter/less_than_test.rb
137
139
  - lib/wongi-engine/graph.rb
138
140
  - lib/wongi-engine/network.rb
@@ -144,12 +146,15 @@ files:
144
146
  - lib/wongi-engine/version.rb
145
147
  - lib/wongi-engine/wme.rb
146
148
  - lib/wongi-engine/wme_match_data.rb
149
+ - spec/action_class_spec.rb
147
150
  - spec/beta_node_spec.rb
148
151
  - spec/bug_specs/issue_4_spec.rb
149
152
  - spec/dataset_spec.rb
150
153
  - spec/dsl_spec.rb
151
154
  - spec/filter_specs/assert_test_spec.rb
155
+ - spec/filter_specs/greater_than_equality_test_spec.rb
152
156
  - spec/filter_specs/less_test_spec.rb
157
+ - spec/filter_specs/less_than_equality_test_spec.rb
153
158
  - spec/generation_spec.rb
154
159
  - spec/high_level_spec.rb
155
160
  - spec/network_spec.rb
@@ -170,7 +175,7 @@ homepage: https://github.com/ulfurinn/wongi-engine
170
175
  licenses:
171
176
  - MIT
172
177
  metadata: {}
173
- post_install_message:
178
+ post_install_message:
174
179
  rdoc_options: []
175
180
  require_paths:
176
181
  - lib
@@ -185,18 +190,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
190
  - !ruby/object:Gem::Version
186
191
  version: '0'
187
192
  requirements: []
188
- rubyforge_project:
189
- rubygems_version: 2.6.10
190
- signing_key:
193
+ rubygems_version: 3.1.4
194
+ signing_key:
191
195
  specification_version: 4
192
196
  summary: A forward-chaining rule engine in pure Ruby.
193
197
  test_files:
198
+ - spec/action_class_spec.rb
194
199
  - spec/beta_node_spec.rb
195
200
  - spec/bug_specs/issue_4_spec.rb
196
201
  - spec/dataset_spec.rb
197
202
  - spec/dsl_spec.rb
198
203
  - spec/filter_specs/assert_test_spec.rb
204
+ - spec/filter_specs/greater_than_equality_test_spec.rb
199
205
  - spec/filter_specs/less_test_spec.rb
206
+ - spec/filter_specs/less_than_equality_test_spec.rb
200
207
  - spec/generation_spec.rb
201
208
  - spec/high_level_spec.rb
202
209
  - spec/network_spec.rb