wongi-engine 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +10 -0
- data/examples/rdf.n3 +6 -0
- data/examples/rdf.rb +14 -0
- data/lib/wongi-engine.rb +9 -0
- data/lib/wongi-engine/beta/beta_node.rb +3 -3
- data/lib/wongi-engine/beta/join_node.rb +17 -6
- data/lib/wongi-engine/beta/optional_node.rb +4 -0
- data/lib/wongi-engine/dsl.rb +2 -2
- data/lib/wongi-engine/dsl/generic_production_rule.rb +5 -1
- data/lib/wongi-engine/filter/filter_test.rb +9 -1
- data/lib/wongi-engine/graph.rb +5 -3
- data/lib/wongi-engine/network.rb +27 -3
- data/lib/wongi-engine/template.rb +6 -2
- data/lib/wongi-engine/token.rb +11 -0
- data/lib/wongi-engine/version.rb +1 -1
- metadata +4 -2
data/README.md
CHANGED
@@ -411,6 +411,16 @@ The Rete implementation in this library largely follows the outline presented in
|
|
411
411
|
|
412
412
|
## Changelog
|
413
413
|
|
414
|
+
### 0.0.4
|
415
|
+
|
416
|
+
* reintegrated RDF support
|
417
|
+
* collapsible filter matchers
|
418
|
+
|
419
|
+
### 0.0.3
|
420
|
+
|
421
|
+
* bug fixes
|
422
|
+
* `assert`, `assign`
|
423
|
+
|
414
424
|
### 0.0.1
|
415
425
|
|
416
426
|
* initial repackaged release
|
data/examples/rdf.n3
ADDED
data/examples/rdf.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'wongi-rdf'
|
2
|
+
require 'wongi-engine'
|
3
|
+
|
4
|
+
engine = Wongi::Engine.create
|
5
|
+
engine.rdf!
|
6
|
+
parser = Wongi::RDF::Parser.new
|
7
|
+
parser.parse_file File.expand_path( "rdf.n3", File.dirname(__FILE__) ), engine
|
8
|
+
|
9
|
+
engine.each do |wme|
|
10
|
+
puts wme
|
11
|
+
end
|
12
|
+
|
13
|
+
serializer = Wongi::RDF::Serializer.new engine
|
14
|
+
puts serializer.serialize
|
data/lib/wongi-engine.rb
CHANGED
@@ -44,11 +44,11 @@ module Wongi::Engine
|
|
44
44
|
beta
|
45
45
|
end
|
46
46
|
|
47
|
-
def join_node alpha, tests, assignment, alpha_deaf
|
48
|
-
existing = children.find{ |node| JoinNode === node && node.equivalent?( alpha, tests, assignment ) }
|
47
|
+
def join_node alpha, tests, assignment, filters, alpha_deaf
|
48
|
+
existing = children.find{ |node| JoinNode === node && node.equivalent?( alpha, tests, assignment, filters ) }
|
49
49
|
return existing if existing
|
50
50
|
|
51
|
-
node = JoinNode.new self, tests, assignment
|
51
|
+
node = JoinNode.new self, tests, assignment, filters
|
52
52
|
node.alpha = alpha
|
53
53
|
alpha.betas << node unless alpha_deaf
|
54
54
|
|
@@ -28,21 +28,26 @@ module Wongi
|
|
28
28
|
attr_accessor :alpha
|
29
29
|
attr_reader :tests
|
30
30
|
attr_reader :assignment_pattern
|
31
|
+
attr_reader :filters
|
31
32
|
|
32
|
-
def initialize parent, tests, assignment
|
33
|
+
def initialize parent, tests, assignment, filters
|
33
34
|
super(parent)
|
34
35
|
@tests = tests
|
35
36
|
@assignment_pattern = assignment
|
37
|
+
@filters = filters
|
36
38
|
end
|
37
39
|
|
38
|
-
def equivalent? alpha, tests, assignment_pattern
|
40
|
+
def equivalent? alpha, tests, assignment_pattern, filters
|
39
41
|
return false unless self.alpha == alpha
|
40
42
|
return false unless self.assignment_pattern == assignment_pattern
|
41
|
-
return false unless (self.tests.empty? && tests.empty?) || self.tests.all? { |my_test|
|
43
|
+
return false unless (self.tests.empty? && tests.empty?) || self.tests.length == tests.length && self.tests.all? { |my_test|
|
42
44
|
tests.any? { |new_test|
|
43
45
|
my_test.equivalent? new_test
|
44
46
|
}
|
45
47
|
}
|
48
|
+
return false unless (self.filters.empty? && filters.empty?) || self.filters.length == filters.length && self.filters.all? { |my_filter|
|
49
|
+
filters.include? my_filter
|
50
|
+
}
|
46
51
|
true
|
47
52
|
end
|
48
53
|
|
@@ -58,7 +63,7 @@ module Wongi
|
|
58
63
|
# puts "PARENT HAS #{parent.tokens.length} TOKENS"
|
59
64
|
self.parent.tokens.each do |token|
|
60
65
|
# puts "#{ws}matching with token"
|
61
|
-
if matches?( token, wme )
|
66
|
+
if matches?( token, wme ) && passes_filters?( token, wme, collected )
|
62
67
|
# puts "#{ws}JOIN RIGHT-MATCHED, PROPAGATING"
|
63
68
|
propagate_activation token, wme, collected
|
64
69
|
end
|
@@ -68,8 +73,9 @@ module Wongi
|
|
68
73
|
def beta_activate token
|
69
74
|
ws = ' ' * depth
|
70
75
|
self.alpha.wmes.uniq.each do |wme|
|
71
|
-
|
72
|
-
|
76
|
+
collected = collect_assignments( wme )
|
77
|
+
if matches?( token, wme ) && passes_filters?( token, wme, collected )
|
78
|
+
propagate_activation token, wme, collected
|
73
79
|
end
|
74
80
|
end
|
75
81
|
end
|
@@ -118,6 +124,11 @@ module Wongi
|
|
118
124
|
true
|
119
125
|
end
|
120
126
|
|
127
|
+
def passes_filters? token, wme, assignments
|
128
|
+
t = FakeToken.new token, wme, assignments
|
129
|
+
@filters.all? { |filter| filter.passes? t }
|
130
|
+
end
|
131
|
+
|
121
132
|
def collect_assignments wme
|
122
133
|
assignments = {}
|
123
134
|
return assignments if self.assignment_pattern.nil?
|
data/lib/wongi-engine/dsl.rb
CHANGED
@@ -46,10 +46,10 @@ dsl {
|
|
46
46
|
section :forall
|
47
47
|
|
48
48
|
clause :has, :fact
|
49
|
-
|
49
|
+
accept Wongi::Engine::Template
|
50
50
|
|
51
51
|
clause :missing, :neg
|
52
|
-
|
52
|
+
accept Wongi::Engine::NegTemplate
|
53
53
|
|
54
54
|
clause :none, :ncc
|
55
55
|
accept Wongi::Engine::NccProductionRule
|
@@ -68,7 +68,11 @@ module Wongi::Engine
|
|
68
68
|
attr_writer :conditions, :actions
|
69
69
|
|
70
70
|
def accept stuff
|
71
|
-
|
71
|
+
if stuff.respond_to? :accept_into
|
72
|
+
stuff.accept_into @acceptors[@current_section]
|
73
|
+
else
|
74
|
+
@acceptors[@current_section] << stuff
|
75
|
+
end
|
72
76
|
end
|
73
77
|
|
74
78
|
|
@@ -6,6 +6,14 @@ module Wongi::Engine
|
|
6
6
|
raise "#{self.class} must implement #passes?"
|
7
7
|
end
|
8
8
|
|
9
|
+
def accept_into acceptors
|
10
|
+
if acceptors.last && acceptors.last.respond_to?( :filters )
|
11
|
+
acceptors.last.filters << self
|
12
|
+
else
|
13
|
+
acceptors << self
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
9
17
|
def compile context
|
10
18
|
context.node = context.node.beta_memory.filter_node( self )
|
11
19
|
context.earlier << self
|
@@ -13,7 +21,7 @@ module Wongi::Engine
|
|
13
21
|
end
|
14
22
|
|
15
23
|
def == other
|
16
|
-
|
24
|
+
false
|
17
25
|
end
|
18
26
|
|
19
27
|
end
|
data/lib/wongi-engine/graph.rb
CHANGED
@@ -8,6 +8,8 @@ module Wongi::Engine
|
|
8
8
|
|
9
9
|
def dot io, opts = { }
|
10
10
|
|
11
|
+
@seen_betas = []
|
12
|
+
|
11
13
|
if String === io
|
12
14
|
File.open io, "w" do |actual_io|
|
13
15
|
dot actual_io
|
@@ -47,10 +49,9 @@ module Wongi::Engine
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def dump_beta beta, opts
|
52
|
+
return if @seen_betas.include? beta
|
53
|
+
@seen_betas << beta
|
50
54
|
@io.puts "node#{print_hash beta.hash} [label=\"#{beta.class.name.split('::').last}\"];"
|
51
|
-
if beta.parent
|
52
|
-
@io.puts "node#{print_hash beta.parent.hash} -> node#{print_hash beta.hash};"
|
53
|
-
end
|
54
55
|
if beta.is_a? NccNode
|
55
56
|
@io.puts "node#{print_hash beta.partner.hash} -> node#{print_hash beta.hash};"
|
56
57
|
@io.puts "{ rank=same; node#{print_hash beta.partner.hash} node#{print_hash beta.hash} }"
|
@@ -62,6 +63,7 @@ module Wongi::Engine
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
beta.children.each do |child|
|
66
|
+
@io.puts "node#{print_hash beta.hash} -> node#{print_hash child.hash};"
|
65
67
|
dump_beta child, opts
|
66
68
|
end
|
67
69
|
end
|
data/lib/wongi-engine/network.rb
CHANGED
@@ -21,6 +21,28 @@ module Wongi::Engine
|
|
21
21
|
extend NetworkParts::Debug
|
22
22
|
end
|
23
23
|
|
24
|
+
def rdf!
|
25
|
+
if ! defined? Wongi::RDF::DocumentSupport
|
26
|
+
begin
|
27
|
+
require 'wongi-rdf'
|
28
|
+
rescue LoadError => e
|
29
|
+
raise "'wongi-rdf' is required for RDF support"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
extend Wongi::RDF::DocumentSupport
|
34
|
+
class << self
|
35
|
+
def statements
|
36
|
+
alpha_top.wmes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
@namespaces = { }
|
41
|
+
@blank_counter = 1
|
42
|
+
@ns_counter = 0
|
43
|
+
@used_blanks = { }
|
44
|
+
end
|
45
|
+
|
24
46
|
def initialize
|
25
47
|
@timeline = []
|
26
48
|
self.alpha_top = AlphaMemory.new( Template.new( :_, :_, :_ ), self )
|
@@ -51,12 +73,12 @@ module Wongi::Engine
|
|
51
73
|
|
52
74
|
def import thing
|
53
75
|
case thing
|
54
|
-
when String, Numeric, TrueClass, FalseClass, NilClass
|
76
|
+
when String, Numeric, TrueClass, FalseClass, NilClass, Wongi::RDF::Node
|
55
77
|
thing
|
56
78
|
when Symbol
|
57
79
|
thing
|
58
80
|
else
|
59
|
-
|
81
|
+
thing
|
60
82
|
end
|
61
83
|
end
|
62
84
|
|
@@ -154,11 +176,13 @@ module Wongi::Engine
|
|
154
176
|
something.install self
|
155
177
|
when WME
|
156
178
|
assert something
|
179
|
+
when Wongi::RDF::Statement
|
180
|
+
assert WME.new( something.subject, something.predicate, something.object, self )
|
157
181
|
#when Wongi::RDF::Document
|
158
182
|
# something.statements.each do |st|
|
159
183
|
# assert WME.new( st.subject, st.predicate, st.object, self )
|
160
184
|
# end
|
161
|
-
when
|
185
|
+
when Network
|
162
186
|
something.each do |st|
|
163
187
|
assert st.import_into( self )
|
164
188
|
end
|
@@ -4,6 +4,7 @@ module Wongi::Engine
|
|
4
4
|
|
5
5
|
include CoreExt
|
6
6
|
|
7
|
+
attr_reader :filters
|
7
8
|
attr_predicate debug: false
|
8
9
|
|
9
10
|
def self.variable? thing
|
@@ -14,10 +15,13 @@ module Wongi::Engine
|
|
14
15
|
raise "Cannot work with continuous time" unless time.integer?
|
15
16
|
raise "Cannot look into the future" if time > 0
|
16
17
|
super
|
18
|
+
@filters = []
|
17
19
|
end
|
18
20
|
|
19
21
|
def import_into r
|
20
|
-
self.class.new r.import( subject ), r.import( predicate ), r.import( object ), time
|
22
|
+
copy = self.class.new r.import( subject ), r.import( predicate ), r.import( object ), time
|
23
|
+
@filters.each { |f| copy.filters << f }
|
24
|
+
copy
|
21
25
|
end
|
22
26
|
|
23
27
|
def root?
|
@@ -60,7 +64,7 @@ module Wongi::Engine
|
|
60
64
|
def compile context
|
61
65
|
tests, assignment = *JoinNode.compile( self, context.earlier, context.parameters )
|
62
66
|
alpha = context.rete.compile_alpha( self )
|
63
|
-
context.node = context.node.beta_memory.join_node( alpha, tests, assignment, context.alpha_deaf )
|
67
|
+
context.node = context.node.beta_memory.join_node( alpha, tests, assignment, @filters, context.alpha_deaf )
|
64
68
|
context.earlier << self
|
65
69
|
context
|
66
70
|
end
|
data/lib/wongi-engine/token.rb
CHANGED
@@ -98,4 +98,15 @@ module Wongi::Engine
|
|
98
98
|
|
99
99
|
end
|
100
100
|
|
101
|
+
class FakeToken < Token
|
102
|
+
def initialize token, wme, assignments
|
103
|
+
@parent, @wme, @assignments = token, wme, assignments
|
104
|
+
@children = []
|
105
|
+
@neg_join_results = []
|
106
|
+
@opt_join_results = []
|
107
|
+
@ncc_results = []
|
108
|
+
@generated_wmes = []
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
101
112
|
end
|
data/lib/wongi-engine/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-13 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A rule engine.
|
15
15
|
email:
|
@@ -26,6 +26,8 @@ files:
|
|
26
26
|
- examples/ex01.rb
|
27
27
|
- examples/ex02.rb
|
28
28
|
- examples/graphviz.rb
|
29
|
+
- examples/rdf.n3
|
30
|
+
- examples/rdf.rb
|
29
31
|
- examples/timeline.rb
|
30
32
|
- lib/wongi-engine.rb
|
31
33
|
- lib/wongi-engine/alpha_memory.rb
|