mort666-wongi-engine 0.2.9
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 +7 -0
- data/.gitignore +20 -0
- data/.hgignore +6 -0
- data/.hgtags +13 -0
- data/.ruby-gemset +1 -0
- data/.travis.yml +19 -0
- data/CHANGELOG.md +106 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +27 -0
- data/Rakefile +9 -0
- data/examples/ex01.rb +23 -0
- data/examples/ex02.rb +37 -0
- data/examples/graphviz.rb +16 -0
- data/examples/rdf.n3 +6 -0
- data/examples/rdf.rb +14 -0
- data/examples/timeline.rb +48 -0
- data/lib/wongi-engine.rb +36 -0
- data/lib/wongi-engine/alpha_memory.rb +60 -0
- data/lib/wongi-engine/beta.rb +11 -0
- data/lib/wongi-engine/beta/assignment_node.rb +40 -0
- data/lib/wongi-engine/beta/beta_memory.rb +49 -0
- data/lib/wongi-engine/beta/beta_node.rb +94 -0
- data/lib/wongi-engine/beta/filter_node.rb +48 -0
- data/lib/wongi-engine/beta/join_node.rb +140 -0
- data/lib/wongi-engine/beta/ncc_node.rb +67 -0
- data/lib/wongi-engine/beta/ncc_partner.rb +40 -0
- data/lib/wongi-engine/beta/neg_node.rb +115 -0
- data/lib/wongi-engine/beta/optional_node.rb +142 -0
- data/lib/wongi-engine/beta/or_node.rb +37 -0
- data/lib/wongi-engine/beta/production_node.rb +31 -0
- data/lib/wongi-engine/compiler.rb +115 -0
- data/lib/wongi-engine/core_ext.rb +63 -0
- data/lib/wongi-engine/data_overlay.rb +144 -0
- data/lib/wongi-engine/dsl.rb +132 -0
- data/lib/wongi-engine/dsl/action/base.rb +11 -0
- data/lib/wongi-engine/dsl/action/error_generator.rb +31 -0
- data/lib/wongi-engine/dsl/action/simple_action.rb +60 -0
- data/lib/wongi-engine/dsl/action/simple_collector.rb +52 -0
- data/lib/wongi-engine/dsl/action/statement_generator.rb +46 -0
- data/lib/wongi-engine/dsl/action/trace_action.rb +49 -0
- data/lib/wongi-engine/dsl/any_rule.rb +33 -0
- data/lib/wongi-engine/dsl/assuming.rb +31 -0
- data/lib/wongi-engine/dsl/builder.rb +44 -0
- data/lib/wongi-engine/dsl/clause/assign.rb +15 -0
- data/lib/wongi-engine/dsl/clause/fact.rb +71 -0
- data/lib/wongi-engine/dsl/clause/gen.rb +17 -0
- data/lib/wongi-engine/dsl/clause/generic.rb +38 -0
- data/lib/wongi-engine/dsl/generated.rb +43 -0
- data/lib/wongi-engine/dsl/ncc_subrule.rb +17 -0
- data/lib/wongi-engine/dsl/query.rb +24 -0
- data/lib/wongi-engine/dsl/rule.rb +84 -0
- data/lib/wongi-engine/enumerators.rb +21 -0
- data/lib/wongi-engine/error.rb +22 -0
- data/lib/wongi-engine/filter.rb +6 -0
- 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 +18 -0
- data/lib/wongi-engine/filter/greater_than_test.rb +36 -0
- data/lib/wongi-engine/filter/inequality_test.rb +36 -0
- data/lib/wongi-engine/filter/less_than_test.rb +36 -0
- data/lib/wongi-engine/graph.rb +73 -0
- data/lib/wongi-engine/network.rb +416 -0
- data/lib/wongi-engine/network/collectable.rb +42 -0
- data/lib/wongi-engine/network/debug.rb +85 -0
- data/lib/wongi-engine/ruleset.rb +74 -0
- data/lib/wongi-engine/template.rb +78 -0
- data/lib/wongi-engine/token.rb +114 -0
- data/lib/wongi-engine/version.rb +5 -0
- data/lib/wongi-engine/wme.rb +89 -0
- data/lib/wongi-engine/wme_match_data.rb +34 -0
- data/spec/beta_node_spec.rb +29 -0
- data/spec/bug_specs/issue_4_spec.rb +141 -0
- data/spec/dataset_spec.rb +27 -0
- data/spec/dsl_spec.rb +9 -0
- data/spec/filter_specs/assert_test_spec.rb +102 -0
- data/spec/filter_specs/less_test_spec.rb +41 -0
- data/spec/generation_spec.rb +116 -0
- data/spec/high_level_spec.rb +378 -0
- data/spec/network_spec.rb +182 -0
- data/spec/overlay_spec.rb +61 -0
- data/spec/rule_specs/any_rule_spec.rb +75 -0
- data/spec/rule_specs/assign_spec.rb +88 -0
- data/spec/rule_specs/assuming_spec.rb +66 -0
- data/spec/rule_specs/maybe_rule_spec.rb +101 -0
- data/spec/rule_specs/ncc_spec.rb +258 -0
- data/spec/rule_specs/negative_rule_spec.rb +105 -0
- data/spec/ruleset_spec.rb +54 -0
- data/spec/simple_action_spec.rb +40 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/wme_spec.rb +83 -0
- data/wongi-engine.gemspec +40 -0
- metadata +212 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'wongi-engine/beta/beta_node'
|
2
|
+
require 'wongi-engine/beta/beta_memory'
|
3
|
+
require 'wongi-engine/beta/filter_node'
|
4
|
+
require 'wongi-engine/beta/assignment_node'
|
5
|
+
require 'wongi-engine/beta/join_node'
|
6
|
+
require 'wongi-engine/beta/ncc_partner'
|
7
|
+
require 'wongi-engine/beta/ncc_node'
|
8
|
+
require 'wongi-engine/beta/neg_node'
|
9
|
+
require 'wongi-engine/beta/optional_node'
|
10
|
+
require 'wongi-engine/beta/or_node'
|
11
|
+
require 'wongi-engine/beta/production_node'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Wongi::Engine
|
2
|
+
|
3
|
+
class AssignmentNode < BetaNode
|
4
|
+
|
5
|
+
def initialize parent, variable, body
|
6
|
+
super parent
|
7
|
+
@variable, @body = variable, body
|
8
|
+
end
|
9
|
+
|
10
|
+
def beta_activate token, wme = nil, assignments = { }
|
11
|
+
children.each do |child|
|
12
|
+
child.beta_activate Token.new( child, token, nil, { @variable => @body.respond_to?(:call) ? @body.call(token) : @body } )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def beta_deactivate token
|
17
|
+
children.each do |child|
|
18
|
+
child.tokens.each do |t|
|
19
|
+
if t.parent == token
|
20
|
+
child.beta_deactivate t
|
21
|
+
#token.destroy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def refresh_child child
|
28
|
+
tmp = children
|
29
|
+
self.children = [ child ]
|
30
|
+
parent.tokens.each do |token|
|
31
|
+
children.each do |child|
|
32
|
+
child.beta_activate Token.new( child, token, nil, { @variable => @body.respond_to?(:call) ? @body.call(token) : @body } )
|
33
|
+
end
|
34
|
+
end
|
35
|
+
self.children = tmp
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Wongi::Engine
|
2
|
+
|
3
|
+
class BetaMemory < BetaNode
|
4
|
+
include TokenContainer
|
5
|
+
|
6
|
+
def seed assignments = {}
|
7
|
+
@seed = assignments
|
8
|
+
t = Token.new( self, nil, nil, assignments )
|
9
|
+
rete.default_overlay.add_token(t, self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def subst valuations
|
13
|
+
beta_deactivate(tokens.first)
|
14
|
+
token = Token.new( self, nil, nil, @seed )
|
15
|
+
valuations.each { |variable, value| token.subst variable, value }
|
16
|
+
beta_activate(token)
|
17
|
+
end
|
18
|
+
|
19
|
+
def beta_activate token
|
20
|
+
existing = tokens.find { |et| et.duplicate? token }
|
21
|
+
return if existing # TODO really?
|
22
|
+
token.overlay.add_token(token, self)
|
23
|
+
children.each do |child|
|
24
|
+
child.beta_activate token
|
25
|
+
end
|
26
|
+
token
|
27
|
+
end
|
28
|
+
|
29
|
+
def beta_deactivate token
|
30
|
+
return nil unless tokens.find token
|
31
|
+
token.overlay.remove_token(token, self)
|
32
|
+
token.deleted!
|
33
|
+
if token.parent
|
34
|
+
token.parent.children.delete token # should this go into Token#destroy?
|
35
|
+
end
|
36
|
+
children.each do |child|
|
37
|
+
child.beta_deactivate token
|
38
|
+
end
|
39
|
+
token
|
40
|
+
end
|
41
|
+
|
42
|
+
def refresh_child child
|
43
|
+
tokens.each do |token|
|
44
|
+
child.beta_activate token
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Wongi::Engine
|
2
|
+
|
3
|
+
class BetaNode
|
4
|
+
|
5
|
+
module TokenContainer
|
6
|
+
def tokens
|
7
|
+
Enumerator.new do |y|
|
8
|
+
rete.overlays.each do |overlay|
|
9
|
+
overlay.raw_tokens(self).dup.each do |token|
|
10
|
+
y << token unless token.deleted?
|
11
|
+
end
|
12
|
+
overlay.raw_tokens(self).reject! &:deleted?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def empty?
|
18
|
+
tokens.first.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def size
|
22
|
+
tokens.count
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
include CoreExt
|
27
|
+
|
28
|
+
attr_writer :rete
|
29
|
+
attr_reader :parent
|
30
|
+
attr_accessor :children
|
31
|
+
attr_predicate :debug
|
32
|
+
|
33
|
+
def initialize parent = nil
|
34
|
+
@parent = parent
|
35
|
+
@children = []
|
36
|
+
if parent
|
37
|
+
parent.children << self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def root?
|
42
|
+
parent.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def depth
|
46
|
+
@depth ||= if parent.nil?
|
47
|
+
0
|
48
|
+
else
|
49
|
+
parent.depth + 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def rete
|
54
|
+
@rete ||= if parent
|
55
|
+
parent.rete
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
abstract :alpha_activate
|
60
|
+
abstract :alpha_deactivate
|
61
|
+
abstract :alpha_reactivate
|
62
|
+
abstract :beta_activate
|
63
|
+
abstract :beta_deactivate
|
64
|
+
abstract :beta_reactivate
|
65
|
+
|
66
|
+
def assignment_node variable, body
|
67
|
+
node = AssignmentNode.new self, variable, body
|
68
|
+
node.refresh
|
69
|
+
node
|
70
|
+
end
|
71
|
+
|
72
|
+
def refresh
|
73
|
+
parent.refresh_child self
|
74
|
+
end
|
75
|
+
|
76
|
+
def refresh_child node
|
77
|
+
raise "#{self.class} must implement refresh_child"
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def dp message
|
83
|
+
if debug?
|
84
|
+
puts "#{indent}#{message}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def indent
|
89
|
+
' ' * depth
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Wongi
|
2
|
+
module Engine
|
3
|
+
|
4
|
+
class FilterNode < BetaNode
|
5
|
+
|
6
|
+
attr_accessor :test
|
7
|
+
|
8
|
+
def initialize parent, test
|
9
|
+
super parent
|
10
|
+
self.test = test
|
11
|
+
end
|
12
|
+
|
13
|
+
def beta_activate token
|
14
|
+
if test.passes? token
|
15
|
+
children.each do |child|
|
16
|
+
child.beta_activate Token.new( child, token, nil, {} )
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def beta_deactivate token
|
22
|
+
children.each do |child|
|
23
|
+
child.tokens.each do |t|
|
24
|
+
if t.parent == token
|
25
|
+
child.beta_deactivate t
|
26
|
+
#token.destroy
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def equivalent? test
|
33
|
+
test == self.test
|
34
|
+
end
|
35
|
+
|
36
|
+
def refresh_child child
|
37
|
+
tmp = children
|
38
|
+
self.children = [ child ]
|
39
|
+
parent.tokens.each do |token|
|
40
|
+
beta_activate token
|
41
|
+
end
|
42
|
+
self.children = tmp
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Wongi
|
2
|
+
module Engine
|
3
|
+
|
4
|
+
TokenAssignment = Struct.new(:wme, :field) do
|
5
|
+
def call token = nil
|
6
|
+
wme.send field
|
7
|
+
end
|
8
|
+
def inspect
|
9
|
+
"#{field} of #{wme}"
|
10
|
+
end
|
11
|
+
def to_s
|
12
|
+
inspect
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class BetaTest
|
17
|
+
|
18
|
+
attr_reader :field
|
19
|
+
attr_reader :variable
|
20
|
+
|
21
|
+
def initialize field, variable
|
22
|
+
@field, @variable = field, variable
|
23
|
+
end
|
24
|
+
|
25
|
+
def matches? token, wme
|
26
|
+
assignment = token[ self.variable ]
|
27
|
+
field = wme.send( self.field )
|
28
|
+
#field.nil? ||
|
29
|
+
assignment && field == assignment
|
30
|
+
end
|
31
|
+
|
32
|
+
def equivalent? other
|
33
|
+
other.field == self.field && other.variable == self.variable
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
class JoinNode < BetaNode
|
39
|
+
|
40
|
+
attr_accessor :alpha
|
41
|
+
attr_reader :tests
|
42
|
+
attr_reader :assignment_pattern
|
43
|
+
|
44
|
+
def initialize parent, tests, assignment
|
45
|
+
super(parent)
|
46
|
+
@tests = tests
|
47
|
+
@assignment_pattern = assignment
|
48
|
+
end
|
49
|
+
|
50
|
+
def equivalent? alpha, tests, assignment_pattern
|
51
|
+
return false unless self.alpha == alpha
|
52
|
+
return false unless self.assignment_pattern == assignment_pattern
|
53
|
+
return false unless (self.tests.empty? && tests.empty?) || self.tests.length == tests.length && self.tests.all? { |my_test|
|
54
|
+
tests.any? { |new_test|
|
55
|
+
my_test.equivalent? new_test
|
56
|
+
}
|
57
|
+
}
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def alpha_activate wme
|
62
|
+
assignments = collect_assignments( wme )
|
63
|
+
parent.tokens.each do |token|
|
64
|
+
if matches?( token, wme )
|
65
|
+
children.each do |beta|
|
66
|
+
beta.beta_activate Token.new( beta, token, wme, assignments )
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def alpha_deactivate wme
|
73
|
+
children.each do |child|
|
74
|
+
child.tokens.each do |token|
|
75
|
+
if token.wme == wme
|
76
|
+
child.beta_deactivate token
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def beta_activate token
|
83
|
+
self.alpha.wmes.each do |wme|
|
84
|
+
if matches?( token, wme )
|
85
|
+
assignments = collect_assignments( wme )
|
86
|
+
children.each do |beta|
|
87
|
+
beta.beta_activate Token.new( beta, token, wme, assignments )
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def beta_deactivate token
|
94
|
+
children.each do |child|
|
95
|
+
child.tokens.each do |t|
|
96
|
+
if t.parent == token
|
97
|
+
child.beta_deactivate t
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def refresh_child child
|
104
|
+
alpha.wmes.each do |wme|
|
105
|
+
assignments = collect_assignments( wme )
|
106
|
+
parent.tokens.each do |token|
|
107
|
+
if matches?( token, wme )
|
108
|
+
child.beta_activate Token.new( child, token, wme, assignments )
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
protected
|
115
|
+
|
116
|
+
def matches? token, wme
|
117
|
+
@tests.each do |test|
|
118
|
+
return false unless test.matches?( token, wme )
|
119
|
+
end
|
120
|
+
true
|
121
|
+
end
|
122
|
+
|
123
|
+
def collect_assignments wme
|
124
|
+
assignments = {}
|
125
|
+
return assignments if assignment_pattern.nil?
|
126
|
+
if assignment_pattern.subject != :_
|
127
|
+
assignments[ assignment_pattern.subject ] = TokenAssignment.new(wme, :subject)
|
128
|
+
end
|
129
|
+
if assignment_pattern.predicate != :_
|
130
|
+
assignments[ assignment_pattern.predicate ] = TokenAssignment.new(wme, :predicate)
|
131
|
+
end
|
132
|
+
if assignment_pattern.object != :_
|
133
|
+
assignments[ assignment_pattern.object ] = TokenAssignment.new(wme, :object)
|
134
|
+
end
|
135
|
+
assignments
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Wongi
|
2
|
+
module Engine
|
3
|
+
class NccNode < BetaNode
|
4
|
+
include TokenContainer
|
5
|
+
|
6
|
+
attr_accessor :partner
|
7
|
+
|
8
|
+
def initialize parent
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def beta_activate token
|
13
|
+
return if tokens.find { |t| t.parent == token }
|
14
|
+
t = Token.new self, token, nil, {}
|
15
|
+
t.overlay.add_token(t, self)
|
16
|
+
partner.tokens.each do |ncc_token|
|
17
|
+
next unless ncc_token.ancestors.find { |a| a.equal? token }
|
18
|
+
t.ncc_results << ncc_token
|
19
|
+
ncc_token.owner = t
|
20
|
+
end
|
21
|
+
if t.ncc_results.empty?
|
22
|
+
children.each do |child|
|
23
|
+
child.beta_activate Token.new( child, t, nil, { } )
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def beta_deactivate token
|
29
|
+
t = tokens.find { |tok| tok.parent == token }
|
30
|
+
return unless t
|
31
|
+
t.overlay.remove_token(t, self)
|
32
|
+
t.deleted!
|
33
|
+
partner.tokens.select { |ncc| ncc.owner == t }.each do |ncc_token|
|
34
|
+
ncc_token.owner = nil
|
35
|
+
t.ncc_results.delete ncc_token
|
36
|
+
end
|
37
|
+
children.each do |beta|
|
38
|
+
beta.tokens.select { |token| token.parent == t }.each do |token|
|
39
|
+
beta.beta_deactivate token
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def ncc_activate token
|
45
|
+
children.each do |child|
|
46
|
+
child.beta_activate Token.new( child, token, nil, { } )
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def ncc_deactivate token
|
51
|
+
children.each do |beta|
|
52
|
+
beta.tokens.select { |t| t.parent == token }.each do |t|
|
53
|
+
beta.beta_deactivate t
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def refresh_child child
|
59
|
+
tokens.each do |token|
|
60
|
+
if token.ncc_results.empty?
|
61
|
+
child.beta_activate Token.new( child, token, nil, { } )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|