wongi-engine 0.0.13 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
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