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 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