wongi-engine 0.0.3 → 0.0.5

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/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
@@ -0,0 +1,6 @@
1
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
2
+ @prefix test: <http://test/> .
3
+
4
+ test:b test:x [
5
+ test:z test:y
6
+ ] .
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
@@ -6,6 +6,15 @@ module Wongi
6
6
  end
7
7
 
8
8
  end
9
+
10
+ # pre-declare things to avoid undefined constants
11
+ module RDF
12
+
13
+ class Document; end
14
+ class Statement; end
15
+ class Node; end
16
+
17
+ end
9
18
  end
10
19
 
11
20
  require 'wongi-engine/version'
@@ -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
- if matches?( token, wme )
72
- propagate_activation token, wme, collect_assignments( wme )
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?
@@ -5,6 +5,10 @@ module Wongi
5
5
 
6
6
  class OptionalNode < JoinNode
7
7
 
8
+ def initialize parent, tests, assignment
9
+ super parent, tests, assignment, []
10
+ end
11
+
8
12
  def alpha_activate wme
9
13
  parent.tokens.each do |token|
10
14
  if matches? token, wme
@@ -46,10 +46,10 @@ dsl {
46
46
  section :forall
47
47
 
48
48
  clause :has, :fact
49
- action Wongi::Engine::Template
49
+ accept Wongi::Engine::Template
50
50
 
51
51
  clause :missing, :neg
52
- action Wongi::Engine::NegTemplate
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
- @acceptors[@current_section] << stuff
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
- self.class == other.class
24
+ false
17
25
  end
18
26
 
19
27
  end
@@ -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
@@ -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
- raise "I don't know how to import a #{thing.class}"
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 Rete
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Wongi
2
2
  module Engine
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
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.3
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-07-18 00:00:00.000000000 Z
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