wongi-engine 0.0.2 → 0.0.3
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.
- data/.gitignore +2 -0
- data/README.md +17 -5
- data/lib/wongi-engine/alpha_memory.rb +1 -1
- data/lib/wongi-engine/beta/assignment_node.rb +39 -0
- data/lib/wongi-engine/beta/beta_memory.rb +22 -8
- data/lib/wongi-engine/beta/beta_node.rb +23 -52
- data/lib/wongi-engine/beta/filter_node.rb +12 -86
- data/lib/wongi-engine/beta/join_node.rb +12 -3
- data/lib/wongi-engine/beta/ncc_node.rb +22 -3
- data/lib/wongi-engine/beta/ncc_partner.rb +13 -14
- data/lib/wongi-engine/beta/neg_node.rb +22 -3
- data/lib/wongi-engine/beta/optional_node.rb +19 -2
- data/lib/wongi-engine/beta/or_node.rb +3 -3
- data/lib/wongi-engine/beta/production_node.rb +2 -6
- data/lib/wongi-engine/beta.rb +1 -0
- data/lib/wongi-engine/dsl.rb +7 -1
- data/lib/wongi-engine/filter/asserting_test.rb +20 -0
- data/lib/wongi-engine/filter/equality_test.rb +36 -0
- data/lib/wongi-engine/filter/filter_test.rb +21 -0
- data/lib/wongi-engine/filter/inequality_test.rb +36 -0
- data/lib/wongi-engine/filter.rb +4 -0
- data/lib/wongi-engine/network/debug.rb +60 -0
- data/lib/wongi-engine/network.rb +5 -1
- data/lib/wongi-engine/token.rb +5 -41
- data/lib/wongi-engine/version.rb +1 -1
- data/lib/wongi-engine/wme.rb +4 -4
- data/lib/wongi-engine.rb +1 -0
- data/spec/filter_specs/assert_test_spec.rb +85 -0
- data/spec/high_level_spec.rb +5 -61
- data/spec/rule_specs/any_rule_spec.rb +75 -0
- data/spec/rule_specs/assign_spec.rb +52 -0
- data/spec/rule_specs/maybe_rule_spec.rb +54 -0
- data/spec/rule_specs/ncc_spec.rb +64 -0
- metadata +18 -2
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -81,7 +81,9 @@ If you don't care about a specific field's value, you can use the all-matcher `:
|
|
81
81
|
|
82
82
|
Once a variable is bound, it can be used to match further facts within a rule. Let's add another friendship:
|
83
83
|
|
84
|
-
|
84
|
+
```ruby
|
85
|
+
engine << [ "Bob", "friend", "Claire" ]
|
86
|
+
```
|
85
87
|
|
86
88
|
and another rule:
|
87
89
|
|
@@ -141,7 +143,7 @@ engine.rule "self-printer" do
|
|
141
143
|
end
|
142
144
|
```
|
143
145
|
|
144
|
-
The `make` section (also spelled `do!`, if you find it more agreeable English, because `do` is a keyword in Ruby) lists everything that happens when a rule's conditions are fully matched (we say the production node is activated). Wongi::Engine provides only a small amount of
|
146
|
+
The `make` section (also spelled `do!`, if you find it more agreeable English, because `do` is a keyword in Ruby) lists everything that happens when a rule's conditions are fully matched (we say "the production node is **activated**"). Wongi::Engine provides only a small amount of built-in actions, but you can define your own ones, and the simplest one is just `action` with a block.
|
145
147
|
|
146
148
|
### More facts!
|
147
149
|
|
@@ -163,7 +165,7 @@ engine << ["friend", "symmetric", true]
|
|
163
165
|
|
164
166
|
If you still have the "self-printer" rule installed, you will see some new friendships pop up immediately!
|
165
167
|
|
166
|
-
The built-in `gen` action creates new facts, taking either fixed values or variables as arguments. (It will complain if
|
168
|
+
The built-in `gen` action creates new facts, taking either fixed values or variables as arguments. (It will complain if you provide a variable that isn't bound by the time it's activated.) Here, it takes all relations we've defined to be [symmetric](http://en.wikipedia.org/wiki/Symmetric_relation), finds all couples in those sorts of relations and turns them around.
|
167
169
|
|
168
170
|
### Matchers
|
169
171
|
|
@@ -175,7 +177,7 @@ Passes if the specified template does *not* match anything in the dataset. Alias
|
|
175
177
|
|
176
178
|
#### `maybe subject, predicate, object`
|
177
179
|
|
178
|
-
Passes whether or not the template matches anything. It's only useful if it introduces a new variable
|
180
|
+
Passes whether or not the template matches anything. It's only useful if it introduces a new variable; you can think of `LEFT JOIN`. Alias: `optional`.
|
179
181
|
|
180
182
|
#### `none { ... }`
|
181
183
|
|
@@ -193,13 +195,23 @@ Passes if the arguments are equal. Alias: `eq`, `equal`.
|
|
193
195
|
|
194
196
|
Passes if the arguments are not equal. Alias: `ne`.
|
195
197
|
|
198
|
+
#### `assert { |token| ... }`, `assert var1, var2, ... do |val1, val2, ... | ... end`
|
199
|
+
|
200
|
+
Passes if the block evaluates to `true`. Having no arguments passes the entire token as an argument, listing some variables passes only their values.
|
201
|
+
|
202
|
+
#### `assign variable do |token| ... end`
|
203
|
+
|
204
|
+
Not a *matcher*, strictly speaking, because it always passes. What it does instead is introduce a new variable bound to the block's return value.
|
205
|
+
|
196
206
|
### Timeline
|
197
207
|
|
198
208
|
Wongi::Engine has a limited concept of timed facts: time is discrete and only extends into the past. Matchers that accept a triple specification (`has`, `neg` and `maybe`) can also accept a fourth parameter, an integer <= 0, which will make them look at a past state of the system. "0" means the current state and is the default value, "-1" means the one just before the current, and so on.
|
199
209
|
|
200
210
|
To create past states, say:
|
201
211
|
|
202
|
-
|
212
|
+
```ruby
|
213
|
+
engine.snapshot!
|
214
|
+
```
|
203
215
|
|
204
216
|
This will shift all facts one step into the past. The new current state will be a copy of the last one. You can only insert new facts into the current state, "retroactive" facts are not allowed.
|
205
217
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Wongi::Engine
|
2
|
+
|
3
|
+
class Assignment
|
4
|
+
|
5
|
+
def initialize variable, &body
|
6
|
+
@variable, @body = variable, body
|
7
|
+
end
|
8
|
+
|
9
|
+
def compile context
|
10
|
+
context.node = context.node.beta_memory.assignment_node( @variable, @body )
|
11
|
+
context.earlier << self
|
12
|
+
context
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
class AssignmentNode < BetaNode
|
18
|
+
|
19
|
+
def initialize parent, variable, body
|
20
|
+
super parent
|
21
|
+
@variable, @body = variable, body
|
22
|
+
end
|
23
|
+
|
24
|
+
def beta_activate token, wme = nil, assignments = { }
|
25
|
+
propagate_activation token, nil, { @variable => @body.call(token) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def refresh_child child
|
29
|
+
tmp = children
|
30
|
+
self.children = [ child ]
|
31
|
+
parent.tokens.each do |token|
|
32
|
+
beta_activate token
|
33
|
+
end
|
34
|
+
self.children = tmp
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Wongi::Engine
|
2
2
|
|
3
3
|
class BetaMemory < BetaNode
|
4
|
-
attr_reader :tokens
|
4
|
+
attr_reader :tokens
|
5
5
|
|
6
6
|
def initialize parent
|
7
7
|
super
|
@@ -9,35 +9,49 @@ module Wongi::Engine
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def seed assignments = {}
|
12
|
+
@seed = assignments
|
12
13
|
t = Token.new( nil, nil, assignments )
|
13
14
|
t.node = self
|
14
15
|
@tokens << t
|
15
16
|
end
|
16
17
|
|
17
18
|
def subst valuations
|
18
|
-
|
19
|
-
|
19
|
+
@tokens.first.delete
|
20
|
+
|
21
|
+
token = Token.new( nil, nil, @seed )
|
22
|
+
token.node = self
|
23
|
+
@tokens << token
|
24
|
+
|
20
25
|
valuations.each { |variable, value| token.subst variable, value }
|
21
26
|
self.children.each do |child|
|
22
|
-
child.
|
27
|
+
child.beta_activate token
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
26
|
-
def
|
31
|
+
def beta_activate token, wme, assignments
|
27
32
|
# puts "MEMORY #{@id} left-activated with #{wme}"
|
28
33
|
t = Token.new( token, wme, assignments)
|
29
34
|
t.node = self
|
30
|
-
@last_token = t
|
31
35
|
@tokens << t
|
32
36
|
self.children.each do |child|
|
33
37
|
if child.kind_of? BetaMemory
|
34
|
-
child.
|
38
|
+
child.beta_activate t, nil, {}
|
35
39
|
else
|
36
|
-
child.
|
40
|
+
child.beta_activate t
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
45
|
+
def refresh_child child
|
46
|
+
tokens.each do |token|
|
47
|
+
child.beta_activate token, nil, {}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def delete_token token
|
52
|
+
tokens.delete token
|
53
|
+
end
|
54
|
+
|
41
55
|
# => TODO: investigate if we really need this
|
42
56
|
#def beta_memory
|
43
57
|
# self
|
@@ -27,7 +27,7 @@ module Wongi::Engine
|
|
27
27
|
|
28
28
|
|
29
29
|
def rete
|
30
|
-
if parent
|
30
|
+
@rete ||= if parent
|
31
31
|
parent.rete
|
32
32
|
else
|
33
33
|
@rete
|
@@ -39,7 +39,7 @@ module Wongi::Engine
|
|
39
39
|
beta = children.find { |node| BetaMemory === node }
|
40
40
|
if beta.nil?
|
41
41
|
beta = BetaMemory.new self
|
42
|
-
beta.
|
42
|
+
beta.refresh
|
43
43
|
end
|
44
44
|
beta
|
45
45
|
end
|
@@ -67,14 +67,20 @@ module Wongi::Engine
|
|
67
67
|
return existing if existing
|
68
68
|
|
69
69
|
node = FilterNode.new self, test
|
70
|
-
node.
|
70
|
+
node.refresh
|
71
|
+
node
|
72
|
+
end
|
73
|
+
|
74
|
+
def assignment_node variable, body
|
75
|
+
node = AssignmentNode.new self, variable, body
|
76
|
+
node.refresh
|
71
77
|
node
|
72
78
|
end
|
73
79
|
|
74
80
|
def neg_node alpha, tests, alpha_deaf
|
75
81
|
node = NegNode.new self, tests, alpha
|
76
82
|
alpha.betas << node unless alpha_deaf
|
77
|
-
node.
|
83
|
+
node.refresh
|
78
84
|
node
|
79
85
|
end
|
80
86
|
|
@@ -91,8 +97,8 @@ module Wongi::Engine
|
|
91
97
|
partner.ncc = ncc
|
92
98
|
partner.divergent = self
|
93
99
|
# partner.conjuncts = condition.children.size
|
94
|
-
ncc.
|
95
|
-
partner.
|
100
|
+
ncc.refresh
|
101
|
+
partner.refresh
|
96
102
|
ncc
|
97
103
|
end
|
98
104
|
|
@@ -104,61 +110,26 @@ module Wongi::Engine
|
|
104
110
|
end.node
|
105
111
|
end
|
106
112
|
|
107
|
-
def
|
108
|
-
|
113
|
+
def refresh
|
114
|
+
parent.refresh_child self
|
115
|
+
end
|
116
|
+
|
117
|
+
def refresh_child node
|
118
|
+
raise "#{self.class} must implement refresh_child"
|
119
|
+
end
|
120
|
+
|
121
|
+
def delete_token token
|
122
|
+
# => noop
|
109
123
|
end
|
110
124
|
|
111
125
|
private
|
112
126
|
|
113
127
|
def propagate_activation token, wme, assignments
|
114
128
|
self.children.each do |child|
|
115
|
-
child.
|
129
|
+
child.beta_activate token, wme, assignments
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
119
|
-
def update_from parent
|
120
|
-
case parent
|
121
|
-
|
122
|
-
when BetaMemory
|
123
|
-
parent.tokens.each do |token|
|
124
|
-
self.left_activate token, nil, {}
|
125
|
-
end
|
126
|
-
|
127
|
-
when JoinNode, OptionalNode
|
128
|
-
tmp = parent.children
|
129
|
-
parent.children = [ self ]
|
130
|
-
parent.alpha.wmes.each do |wme|
|
131
|
-
parent.right_activate wme
|
132
|
-
end
|
133
|
-
parent.children = tmp
|
134
|
-
|
135
|
-
when FilterNode
|
136
|
-
tmp = parent.children
|
137
|
-
parent.children = [ self ]
|
138
|
-
parent.parent.tokens.each do |token|
|
139
|
-
parent.left_activate token
|
140
|
-
end
|
141
|
-
parent.children = tmp
|
142
|
-
|
143
|
-
when NegNode
|
144
|
-
parent.tokens.each do |token|
|
145
|
-
if token.neg_join_results.empty?
|
146
|
-
left_activate token, nil, {}
|
147
|
-
end
|
148
|
-
end
|
149
|
-
parent.alpha.wmes.each do |wme|
|
150
|
-
parent.right_activate wme
|
151
|
-
end
|
152
|
-
|
153
|
-
when NccNode
|
154
|
-
parent.tokens.each do |token|
|
155
|
-
if token.ncc_results.empty?
|
156
|
-
left_activate token, nil, {}
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
end # => case
|
161
|
-
end
|
162
133
|
end
|
163
134
|
|
164
135
|
end
|
@@ -1,91 +1,6 @@
|
|
1
1
|
module Wongi
|
2
2
|
module Engine
|
3
3
|
|
4
|
-
|
5
|
-
class FilterTest
|
6
|
-
|
7
|
-
def passes? token
|
8
|
-
true
|
9
|
-
end
|
10
|
-
|
11
|
-
def compile context
|
12
|
-
context.node = context.node.beta_memory.filter_node( self )
|
13
|
-
context.earlier << self
|
14
|
-
context
|
15
|
-
end
|
16
|
-
|
17
|
-
def == other
|
18
|
-
self.class == other.class
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
class EqualityTest < FilterTest
|
24
|
-
|
25
|
-
attr_reader :x, :y
|
26
|
-
|
27
|
-
def initialize x, y
|
28
|
-
@x, @y = x, y
|
29
|
-
end
|
30
|
-
|
31
|
-
def passes? token
|
32
|
-
|
33
|
-
x = if Template.variable? @x
|
34
|
-
token[@x]
|
35
|
-
else
|
36
|
-
@x
|
37
|
-
end
|
38
|
-
|
39
|
-
y = if Template.variable? @y
|
40
|
-
token[@y]
|
41
|
-
else
|
42
|
-
@y
|
43
|
-
end
|
44
|
-
|
45
|
-
return false if x == :_ || y == :_
|
46
|
-
return x == y
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
def == other
|
51
|
-
super && x == other.x && y == other.y
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
class InequalityTest < FilterTest
|
57
|
-
|
58
|
-
attr_reader :x, :y
|
59
|
-
|
60
|
-
def initialize x, y
|
61
|
-
@x, @y = x, y
|
62
|
-
end
|
63
|
-
|
64
|
-
def passes? token
|
65
|
-
|
66
|
-
x = if Template.variable? @x
|
67
|
-
token[@x]
|
68
|
-
else
|
69
|
-
@x
|
70
|
-
end
|
71
|
-
|
72
|
-
y = if Template.variable? @y
|
73
|
-
token[@y]
|
74
|
-
else
|
75
|
-
@y
|
76
|
-
end
|
77
|
-
|
78
|
-
return false if x == :_ || y == :_
|
79
|
-
return x != y
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
def == other
|
84
|
-
super && x == other.x && y == other.y
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
4
|
class FilterNode < BetaNode
|
90
5
|
|
91
6
|
attr_accessor :test
|
@@ -95,7 +10,7 @@ module Wongi
|
|
95
10
|
self.test = test
|
96
11
|
end
|
97
12
|
|
98
|
-
def
|
13
|
+
def beta_activate token, wme = nil, assignments = { }
|
99
14
|
if test.passes? token
|
100
15
|
propagate_activation token, nil, {}
|
101
16
|
end
|
@@ -104,6 +19,17 @@ module Wongi
|
|
104
19
|
def equivalent? test
|
105
20
|
test == self.test
|
106
21
|
end
|
22
|
+
|
23
|
+
def refresh_child child
|
24
|
+
tmp = children
|
25
|
+
self.children = [ child ]
|
26
|
+
parent.tokens.each do |token|
|
27
|
+
beta_activate token
|
28
|
+
end
|
29
|
+
self.children = tmp
|
30
|
+
end
|
31
|
+
|
107
32
|
end
|
33
|
+
|
108
34
|
end
|
109
35
|
end
|
@@ -51,7 +51,7 @@ module Wongi
|
|
51
51
|
# puts "\talpha = #{alpha}"
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def alpha_activate wme
|
55
55
|
ws = ' ' * depth
|
56
56
|
# puts "#{ws}JOIN #{@id} right-activated with #{wme}"
|
57
57
|
collected = collect_assignments( wme )
|
@@ -65,7 +65,7 @@ module Wongi
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
68
|
+
def beta_activate token
|
69
69
|
ws = ' ' * depth
|
70
70
|
self.alpha.wmes.uniq.each do |wme|
|
71
71
|
if matches?( token, wme )
|
@@ -74,6 +74,15 @@ module Wongi
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
def refresh_child child
|
78
|
+
tmp = children
|
79
|
+
self.children = [ child ]
|
80
|
+
alpha.wmes.each do |wme|
|
81
|
+
alpha_activate wme
|
82
|
+
end
|
83
|
+
self.children = tmp
|
84
|
+
end
|
85
|
+
|
77
86
|
def self.compile condition, earlier, parameters
|
78
87
|
tests = []
|
79
88
|
assignment = Template.new
|
@@ -114,7 +123,7 @@ module Wongi
|
|
114
123
|
return assignments if self.assignment_pattern.nil?
|
115
124
|
# puts "more assignments"
|
116
125
|
[:subject, :predicate, :object].each do |field|
|
117
|
-
if self.assignment_pattern.send(field)
|
126
|
+
if self.assignment_pattern.send(field) != :_
|
118
127
|
#puts "#{self.assignment_pattern.send(field)} = #{wme.send(field)}"
|
119
128
|
assignments[ self.assignment_pattern.send(field) ] = wme.send(field)
|
120
129
|
end
|
@@ -25,11 +25,12 @@ module Wongi
|
|
25
25
|
@tokens = []
|
26
26
|
end
|
27
27
|
|
28
|
-
# def
|
28
|
+
# def beta_activate token, wme, assignments
|
29
29
|
# t = Token.new token, wme, assignments
|
30
30
|
# t.node = self
|
31
|
-
def
|
31
|
+
def beta_activate token, wme = nil, assignments = { } # => FIXME: beta_activate has different signatures for storing and non-storing nodes...
|
32
32
|
t = Token.new token, nil, {}
|
33
|
+
t.node = self
|
33
34
|
tokens << t
|
34
35
|
partner.tokens.each do |ncc_token|
|
35
36
|
t.ncc_results << ncc_token
|
@@ -37,10 +38,28 @@ module Wongi
|
|
37
38
|
end
|
38
39
|
if t.ncc_results.empty?
|
39
40
|
children.each do |child|
|
40
|
-
child.
|
41
|
+
child.beta_activate t, nil, {}
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
45
|
+
|
46
|
+
def refresh_child child
|
47
|
+
tokens.each do |token|
|
48
|
+
if token.ncc_results.empty?
|
49
|
+
child.beta_activate token, nil, {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def delete_token token
|
55
|
+
tokens.delete token
|
56
|
+
token.ncc_results.each do |nccr|
|
57
|
+
nccr.wme.tokens.delete nccr
|
58
|
+
nccr.parent.children.delete nccr
|
59
|
+
end
|
60
|
+
token.ncc_results.clear
|
61
|
+
end
|
62
|
+
|
44
63
|
end
|
45
64
|
end
|
46
65
|
end
|
@@ -13,22 +13,11 @@ module Wongi
|
|
13
13
|
@tokens = []
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def beta_activate token
|
17
17
|
t = Token.new token, nil, {}
|
18
18
|
t.node = self
|
19
|
-
|
20
|
-
|
21
|
-
# conjuncts.times do
|
22
|
-
# # owners_w = owners_t.wme
|
23
|
-
# owners_t = owners_t.parent
|
24
|
-
# end
|
25
|
-
owner = nil
|
26
|
-
ncc.tokens.each do |ncc_token|
|
27
|
-
# if ncc_token.parent == owners_t
|
28
|
-
if ncc_token.parent.node == divergent
|
29
|
-
owner = ncc_token
|
30
|
-
break
|
31
|
-
end
|
19
|
+
owner = ncc.tokens.find do |ncc_token|
|
20
|
+
ncc_token.parent.node == divergent
|
32
21
|
end
|
33
22
|
if owner
|
34
23
|
owner.ncc_results << t
|
@@ -38,6 +27,16 @@ module Wongi
|
|
38
27
|
tokens << t
|
39
28
|
end
|
40
29
|
end
|
30
|
+
|
31
|
+
def delete_token token
|
32
|
+
token.owner.ncc_results.delete token
|
33
|
+
if token.owner.ncc_results.empty?
|
34
|
+
ncc.children.each do |node|
|
35
|
+
node.beta_activate token.owner, nil, {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -13,7 +13,7 @@ module Wongi
|
|
13
13
|
@tokens = []
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def alpha_activate wme
|
17
17
|
self.tokens.each do |token|
|
18
18
|
if matches?( token, wme )
|
19
19
|
token.delete_children if token.neg_join_results.empty?
|
@@ -22,7 +22,7 @@ module Wongi
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def beta_activate token, newwme, assignments
|
26
26
|
t = Token.new token, newwme, assignments
|
27
27
|
t.node = self
|
28
28
|
self.tokens << t
|
@@ -33,11 +33,30 @@ module Wongi
|
|
33
33
|
end
|
34
34
|
if t.neg_join_results.empty?
|
35
35
|
self.children.each do |child|
|
36
|
-
child.
|
36
|
+
child.beta_activate t, nil, {}
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def refresh_child child
|
42
|
+
tokens.each do |token|
|
43
|
+
if token.neg_join_results.empty?
|
44
|
+
child.beta_activate token, nil, {}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alpha.wmes.each do |wme|
|
48
|
+
alpha_activate wme
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete_token token
|
53
|
+
tokens.delete token
|
54
|
+
token.neg_join_results.each do |njr|
|
55
|
+
njr.wme.neg_join_results.delete njr if njr.wme
|
56
|
+
end
|
57
|
+
token.neg_join_results.clear
|
58
|
+
end
|
59
|
+
|
41
60
|
protected
|
42
61
|
|
43
62
|
def matches? token, wme
|
@@ -5,7 +5,7 @@ module Wongi
|
|
5
5
|
|
6
6
|
class OptionalNode < JoinNode
|
7
7
|
|
8
|
-
def
|
8
|
+
def alpha_activate wme
|
9
9
|
parent.tokens.each do |token|
|
10
10
|
if matches? token, wme
|
11
11
|
if token.has_optional?
|
@@ -20,7 +20,7 @@ module Wongi
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def beta_activate token
|
24
24
|
match = false
|
25
25
|
alpha.wmes.each do |wme|
|
26
26
|
assignments = collect_assignments(wme)
|
@@ -38,6 +38,23 @@ module Wongi
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def refresh_child child
|
42
|
+
tmp = children
|
43
|
+
self.children = [ child ]
|
44
|
+
alpha.wmes.each do |wme|
|
45
|
+
alpha_activate wme
|
46
|
+
end
|
47
|
+
self.children = tmp
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete_token token
|
51
|
+
tokens.delete token
|
52
|
+
token.opt_join_results.each do |ojr|
|
53
|
+
ojr.wme.opt_join_results.delete ojr
|
54
|
+
end
|
55
|
+
token.opt_join_results.clear
|
56
|
+
end
|
57
|
+
|
41
58
|
end
|
42
59
|
end
|
43
60
|
end
|
@@ -18,7 +18,7 @@ module Wongi
|
|
18
18
|
end
|
19
19
|
context.earlier += added
|
20
20
|
context.node = OrNode.new( branches )
|
21
|
-
context.node.
|
21
|
+
context.node.refresh
|
22
22
|
context
|
23
23
|
end
|
24
24
|
|
@@ -65,9 +65,9 @@ module Wongi
|
|
65
65
|
parents.map( &:depth ).max + 1
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
68
|
+
def refresh
|
69
69
|
parents.each do |parent|
|
70
|
-
|
70
|
+
parent.refresh_child self
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -11,20 +11,16 @@ module Wongi
|
|
11
11
|
@actions.each { |action| action.production = self }
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
14
|
+
def beta_activate token, wme, assignments
|
15
15
|
super
|
16
16
|
@actions.each do |action|
|
17
17
|
# @tokens.each do |t|
|
18
18
|
# action.execute t
|
19
19
|
# end
|
20
|
-
action.execute
|
20
|
+
action.execute tokens.last if action.respond_to? :execute
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
# => TODO: investigate
|
25
|
-
def deexecute token
|
26
|
-
|
27
|
-
end
|
28
24
|
end
|
29
25
|
|
30
26
|
end
|