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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af6f8430d35f36788bb67f833fe4770977a58d74
4
- data.tar.gz: 422a1b976bc9305efbabbc6c2b6fd948c365e525
3
+ metadata.gz: ba0f7c9c09df2f3f379bc1983b32807770014d54
4
+ data.tar.gz: 12b8b964c0b03c205ac0e44cdcfe8f10f14c7f34
5
5
  SHA512:
6
- metadata.gz: f3e5c7893e0da05c41dca1de9c670d45ca164cfc8588477e9af76a26e21e264f30e9e28918f2fa633af2cf4a7d114898c191f04ecad7067bc385b74fd4077740
7
- data.tar.gz: a3cf8390e7c706612e1862c4b73633dac0d11f78f469929ad09d0d89c9d39a200f2ff2f1644e3ad325d05ad99d7a7a0aaf5d7904790dff07800e4f43992c2390
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.each do |wme|
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
- # puts "MEMORY #{@id} left-activated with #{wme}"
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 << t
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
- ws = ' ' * depth
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
- # puts "#{ws}matching with token"
63
+ dp "-MATCHING #{token}"
66
64
  if matches?( token, wme ) && passes_filters?( token, wme, collected )
67
- # puts "#{ws}JOIN RIGHT-MATCHED, PROPAGATING"
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
- ws = ' ' * depth
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
- ! ec.kind_of?( NegTemplate ) and ec.contains?( member )
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
@@ -55,7 +55,7 @@ module Wongi
55
55
  def delete_token token
56
56
  tokens.delete token
57
57
  token.ncc_results.each do |nccr|
58
- nccr.wme.tokens.delete nccr
58
+ nccr.wme.tokens.delete( nccr ) if nccr.wme
59
59
  nccr.parent.children.delete nccr
60
60
  end
61
61
  token.ncc_results.clear
@@ -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
- self.tokens << t
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
@@ -13,7 +13,7 @@ module Wongi
13
13
 
14
14
  def beta_activate token, wme, assignments
15
15
  super
16
- generated = tokens.last
16
+ generated = @tokens.last
17
17
  @actions.each do |action|
18
18
  # @tokens.each do |t|
19
19
  # action.execute t
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Wongi
2
2
  module Engine
3
- VERSION = "0.0.13"
3
+ VERSION = "0.0.14"
4
4
  end
5
5
  end
@@ -59,7 +59,7 @@ module Wongi::Engine
59
59
  end
60
60
 
61
61
  def destroy
62
-
62
+ return if deleted?
63
63
  @deleted = true
64
64
  alphas.each { |alpha| alpha.remove self }.clear
65
65
  while tokens.first
data/spec/dataset_spec.rb CHANGED
@@ -15,7 +15,7 @@ describe Wongi::Engine::Network do
15
15
  production = ds.productions['test-rule']
16
16
  production.should_not be_nil
17
17
 
18
- production.tokens.should be_empty
18
+ production.should be_empty
19
19
 
20
20
  ds << [1, 2, 3]
21
21
 
@@ -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
- engine << rule('feedback') {
37
- forall {
38
- neg :a, :b, :_
39
- }
40
- make {
41
- gen :a, :b, :c
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
- engine.should have(1).facts
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( SystemStackError )
66
+ proc.should raise_error( exception )
63
67
 
64
68
  end
65
69
 
data/wongi-engine.gemspec CHANGED
@@ -15,5 +15,5 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Wongi::Engine::VERSION
17
17
 
18
- #gem.add_dependency "wongi-rdf"
18
+ gem.add_development_dependency 'rspec', '~> 2.14.1', '< 3.0.0'
19
19
  end
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.13
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: 2013-10-24 00:00:00.000000000 Z
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.3
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