wongi-engine 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +80 -0
  4. data/.travis.yml +6 -16
  5. data/Gemfile +4 -0
  6. data/README.md +3 -3
  7. data/Rakefile +1 -2
  8. data/examples/ex01.rb +1 -1
  9. data/examples/ex02.rb +3 -7
  10. data/examples/graphviz.rb +1 -1
  11. data/examples/rdf.rb +1 -1
  12. data/examples/timeline.rb +6 -6
  13. data/lib/wongi-engine/alpha_memory.rb +5 -9
  14. data/lib/wongi-engine/beta/aggregate_node.rb +93 -0
  15. data/lib/wongi-engine/beta/assignment_node.rb +10 -18
  16. data/lib/wongi-engine/beta/beta_memory.rb +20 -9
  17. data/lib/wongi-engine/beta/beta_node.rb +14 -22
  18. data/lib/wongi-engine/beta/filter_node.rb +12 -15
  19. data/lib/wongi-engine/beta/join_node.rb +47 -61
  20. data/lib/wongi-engine/beta/ncc_node.rb +17 -20
  21. data/lib/wongi-engine/beta/ncc_partner.rb +17 -17
  22. data/lib/wongi-engine/beta/neg_node.rb +37 -37
  23. data/lib/wongi-engine/beta/optional_node.rb +53 -60
  24. data/lib/wongi-engine/beta/or_node.rb +6 -9
  25. data/lib/wongi-engine/beta/production_node.rb +6 -9
  26. data/lib/wongi-engine/beta.rb +1 -0
  27. data/lib/wongi-engine/compiler.rb +38 -22
  28. data/lib/wongi-engine/core_ext.rb +11 -20
  29. data/lib/wongi-engine/data_overlay.rb +23 -26
  30. data/lib/wongi-engine/dsl/action/assign_action.rb +1 -1
  31. data/lib/wongi-engine/dsl/action/base.rb +1 -4
  32. data/lib/wongi-engine/dsl/action/error_generator.rb +9 -9
  33. data/lib/wongi-engine/dsl/action/simple_action.rb +14 -10
  34. data/lib/wongi-engine/dsl/action/simple_collector.rb +10 -25
  35. data/lib/wongi-engine/dsl/action/statement_generator.rb +15 -14
  36. data/lib/wongi-engine/dsl/action/trace_action.rb +9 -9
  37. data/lib/wongi-engine/dsl/any_rule.rb +16 -20
  38. data/lib/wongi-engine/dsl/assuming.rb +8 -15
  39. data/lib/wongi-engine/dsl/builder.rb +13 -12
  40. data/lib/wongi-engine/dsl/clause/aggregate.rb +21 -0
  41. data/lib/wongi-engine/dsl/clause/assign.rb +4 -4
  42. data/lib/wongi-engine/dsl/clause/fact.rb +10 -6
  43. data/lib/wongi-engine/dsl/clause/gen.rb +3 -5
  44. data/lib/wongi-engine/dsl/clause/generic.rb +7 -9
  45. data/lib/wongi-engine/dsl/generated.rb +6 -12
  46. data/lib/wongi-engine/dsl/ncc_subrule.rb +6 -9
  47. data/lib/wongi-engine/dsl/query.rb +12 -15
  48. data/lib/wongi-engine/dsl/rule.rb +45 -50
  49. data/lib/wongi-engine/dsl.rb +30 -16
  50. data/lib/wongi-engine/enumerators.rb +2 -1
  51. data/lib/wongi-engine/error.rb +6 -7
  52. data/lib/wongi-engine/filter/asserting_test.rb +4 -7
  53. data/lib/wongi-engine/filter/equality_test.rb +15 -18
  54. data/lib/wongi-engine/filter/filter_test.rb +3 -6
  55. data/lib/wongi-engine/filter/greater_than_or_equal_test.rb +5 -2
  56. data/lib/wongi-engine/filter/greater_than_test.rb +15 -18
  57. data/lib/wongi-engine/filter/inequality_test.rb +15 -18
  58. data/lib/wongi-engine/filter/less_than_or_equal_test.rb +5 -2
  59. data/lib/wongi-engine/filter/less_than_test.rb +15 -18
  60. data/lib/wongi-engine/filter.rb +1 -1
  61. data/lib/wongi-engine/graph.rb +13 -20
  62. data/lib/wongi-engine/network/collectable.rb +10 -14
  63. data/lib/wongi-engine/network/debug.rb +16 -24
  64. data/lib/wongi-engine/network.rb +110 -129
  65. data/lib/wongi-engine/ruleset.rb +18 -20
  66. data/lib/wongi-engine/template.rb +31 -30
  67. data/lib/wongi-engine/token.rb +33 -33
  68. data/lib/wongi-engine/version.rb +1 -1
  69. data/lib/wongi-engine/wme.rb +17 -23
  70. data/lib/wongi-engine/wme_match_data.rb +5 -9
  71. data/lib/wongi-engine.rb +0 -4
  72. data/spec/action_class_spec.rb +43 -49
  73. data/spec/beta_node_spec.rb +2 -8
  74. data/spec/bug_specs/issue_4_spec.rb +12 -20
  75. data/spec/dataset_spec.rb +3 -6
  76. data/spec/filter_specs/assert_test_spec.rb +12 -31
  77. data/spec/filter_specs/greater_than_equality_test_spec.rb +2 -5
  78. data/spec/filter_specs/less_test_spec.rb +7 -17
  79. data/spec/filter_specs/less_than_equality_test_spec.rb +3 -6
  80. data/spec/generation_spec.rb +45 -54
  81. data/spec/high_level_spec.rb +95 -141
  82. data/spec/network_spec.rb +77 -68
  83. data/spec/overlay_spec.rb +4 -5
  84. data/spec/rule_specs/aggregate_spec.rb +197 -0
  85. data/spec/rule_specs/any_rule_spec.rb +4 -19
  86. data/spec/rule_specs/assign_spec.rb +10 -16
  87. data/spec/rule_specs/assuming_spec.rb +10 -17
  88. data/spec/rule_specs/maybe_rule_spec.rb +4 -15
  89. data/spec/rule_specs/ncc_spec.rb +48 -65
  90. data/spec/rule_specs/negative_rule_spec.rb +13 -27
  91. data/spec/rule_specs/or_rule_spec.rb +3 -13
  92. data/spec/ruleset_spec.rb +11 -17
  93. data/spec/simple_action_spec.rb +4 -14
  94. data/spec/wme_spec.rb +14 -21
  95. data/wongi-engine.gemspec +22 -22
  96. metadata +16 -37
  97. data/.hgignore +0 -7
  98. data/spec/dsl_spec.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d9f803da98de1a0ec47f26a1adc83940f6ef2d3e8dbfc3dbfb9527c9efe4daf
4
- data.tar.gz: 3d1ace03974a04999b3e4f969c64d0bad2b4da99dc11606db06b1723d056b881
3
+ metadata.gz: bf30142950fccfa0c3ecd20d55e5ac211c74c1fde464507725f262da6734f8b7
4
+ data.tar.gz: efd0a8acae7aef2510854d240e5fbe491ffcbf73986cd4e6d201cf662e912c0a
5
5
  SHA512:
6
- metadata.gz: e7d0c9d09716e02cb60256f048b97d04742733e8587c110a8e3b80b0f641e0bc213f8a3baea543f89a3f4f454a7f9f987321b66b0ed6decd530d7ec568cdbe11
7
- data.tar.gz: e5e3f2158f9975ad23aa7c4115886c17c4b92529967d97395f39c7a28d608dcf2adc7827cecdc9b6bcb1dd8200699c9ad61c8997e638c07cb15534bdbaa61701
6
+ metadata.gz: ba4e0818dff5b8d61b693e8a2974c0e2fa531736459e95aa788b7a3b79c56c0be5c1a3d5e9edd36cd0c71ce55a0bce31b41f1d39e2515c057753df873f288318
7
+ data.tar.gz: b0e6d77fa743e6d74340bc75478ce0178a72ce7e99df7cf5cebe0d60438acd779627fb1f68652ecdd3904054784c385e8684245e54dc66de6485d7e66e1a7a7a
data/.gitignore CHANGED
@@ -18,3 +18,4 @@ test/tmp
18
18
  test/version_tmp
19
19
  tmp
20
20
  .ruby-version
21
+ .idea
data/.rubocop.yml ADDED
@@ -0,0 +1,80 @@
1
+ require:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.7
7
+ NewCops: enable
8
+
9
+ Style/StringLiterals:
10
+ Enabled: false
11
+
12
+ Style/BlockDelimiters:
13
+ Enabled: false
14
+
15
+ Style/TrailingCommaInArguments:
16
+ EnforcedStyleForMultiline: consistent_comma
17
+
18
+ Style/TrailingCommaInArrayLiteral:
19
+ EnforcedStyleForMultiline: consistent_comma
20
+
21
+ Style/TrailingCommaInHashLiteral:
22
+ EnforcedStyleForMultiline: consistent_comma
23
+
24
+ Style/FrozenStringLiteralComment:
25
+ Enabled: false # reconsider later
26
+
27
+ Metrics:
28
+ Enabled: false
29
+
30
+ Style/Documentation:
31
+ Enabled: false
32
+
33
+ Style/ClassAndModuleChildren:
34
+ Enabled: false # temporary
35
+
36
+ Lint/EmptyClass:
37
+ Enabled: false
38
+
39
+ Naming/MethodParameterName:
40
+ Enabled: false
41
+
42
+ Layout/LineLength:
43
+ Enabled: false
44
+
45
+ RSpec:
46
+ Enabled: false
47
+
48
+ Style/SafeNavigation:
49
+ Enabled: false
50
+
51
+ Naming:
52
+ Enabled: false
53
+
54
+ Style/MixinUsage:
55
+ Exclude:
56
+ - examples/*.rb
57
+
58
+ Style/IfUnlessModifier:
59
+ Enabled: false
60
+
61
+ Style/SelectByRegexp:
62
+ Enabled: false
63
+
64
+ Lint/EmptyBlock:
65
+ Enabled: false
66
+
67
+ Security/CompoundHash:
68
+ Enabled: false # we actually need it to work
69
+
70
+ Lint/HashCompareByIdentity:
71
+ Enabled: false # investigate later
72
+
73
+ Style/AccessModifierDeclarations:
74
+ Enabled: false # maybe for the use of module_function which I think is better off being explicit instead of grouped
75
+
76
+ Style/OptionalBooleanParameter:
77
+ Enabled: false
78
+
79
+ Gemspec/RequiredRubyVersion:
80
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,22 +1,12 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
- - 2.1
4
- - 2.2
5
- - 2.3
6
- - 2.4
7
- - 2.5
8
- - 2.6
9
4
  - 2.7
5
+ - 3.0
6
+ - 3.1
10
7
  - jruby
8
+
11
9
  sudo: false
12
- notifications:
13
- hipchat:
14
- rooms:
15
- secure: OwpsmGlIxlSbLUWVZZI+xBErDkFc5XO2vmjs+ddQkNiL1E9N5SG35x75113S6EZ3qhqeNMPFBfZYDqem6jkhNOWsmH3EIH+QT1lWxnosrr0LgyJpvFosvjQaryvqJHVhT5tdBqzaWEYB6ObRLOUt7A5YrbtWHyTScB6ThpXCiR4=
16
- webhooks:
17
- urls:
18
- - secure: Xm+R/3O6iG2sDbfrR8D5Y9AYJkB7DDjLBcKZEn+xaTVjuX/XFLF7p+v9n9v7Qs/v0VtU75pVX4Z++OmNJZJzJKB3Owgb4c1rMOGmctza2JPL+1yovmhpG0/S0hjMkO5g4CsAKKcQoaDXNrubUVHpEchLPP/aCx7/F4twCan9bfc=
19
- on_success: always
20
- on_failure: always
21
- on_start: false
22
10
 
11
+ notifications:
12
+ email: true
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in wongi-engine.gemspec
4
4
  gemspec
5
+
6
+ gem 'rubocop', require: false
7
+ gem 'rubocop-rake', require: false
8
+ gem 'rubocop-rspec', require: false
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Wongi::Engine
2
2
 
3
- [![Gem](https://img.shields.io/gem/v/wongi-engine.svg)](https://rubygems.org/gems/wongi-engine/)
4
- [![Build Status](https://travis-ci.org/ulfurinn/wongi-engine.svg?branch=master)](https://travis-ci.org/ulfurinn/wongi-engine)
3
+ [![Gem](https://img.shields.io/gem/v/wongi-engine.svg)](https://rubygems.org/gems/wongi-engine/)
4
+ [![Build Status](https://travis-ci.com/ulfurinn/wongi-engine.svg?branch=master)](https://app.travis-ci.com/github/ulfurinn/wongi-engine)
5
5
 
6
- Ruby >= 2.1 and JRuby are supported. Rubinius should work but isn't actively supported.
6
+ Ruby >= 2.7 and JRuby are supported. Rubinius should work but isn't actively supported.
7
7
 
8
8
  ## [Documentation](http://ulfurinn.github.io/wongi-engine/)
9
9
 
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env rake
2
1
  require "bundler/gem_tasks"
3
2
 
4
3
  require 'rspec/core/rake_task'
@@ -6,4 +5,4 @@ require 'rspec/core/rake_task'
6
5
  RSpec::Core::RakeTask.new('spec')
7
6
 
8
7
  # If you want to make this the default task
9
- task :default => :spec
8
+ task default: :spec
data/examples/ex01.rb CHANGED
@@ -2,7 +2,7 @@ include Wongi::Engine
2
2
 
3
3
  ds = Network.new
4
4
 
5
- ds << WME.new( "Alice", "friend", "Bob" )
5
+ ds << WME.new("Alice", "friend", "Bob")
6
6
 
7
7
  puts "Enumerate all:"
8
8
 
data/examples/ex02.rb CHANGED
@@ -4,7 +4,6 @@ include Wongi::Engine::DSL
4
4
  ds = Network.new
5
5
 
6
6
  ds << ruleset {
7
-
8
7
  name "Example"
9
8
 
10
9
  rule "symmetric" do
@@ -16,22 +15,19 @@ ds << ruleset {
16
15
  gen :B, :P, :A
17
16
  }
18
17
  end
19
-
20
18
  }
21
19
 
22
20
  puts "Installed ruleset"
23
21
 
24
- ds << WME.new( "friend", "symmetric", true )
25
- ds << WME.new( "Alice", "friend", "Bob" )
22
+ ds << WME.new("friend", "symmetric", true)
23
+ ds << WME.new("Alice", "friend", "Bob")
26
24
 
27
25
  puts "Asserted facts:"
28
26
 
29
27
  puts "Should print 3 facts:"
30
28
  puts ds.wmes.to_a
31
29
 
32
-
33
- ds.retract WME.new( "Alice", "friend", "Bob" )
30
+ ds.retract WME.new("Alice", "friend", "Bob")
34
31
 
35
32
  puts "Should print 1 fact:"
36
33
  puts ds.wmes.to_a
37
-
data/examples/graphviz.rb CHANGED
@@ -12,5 +12,5 @@ ds << rule('demo') {
12
12
  }
13
13
 
14
14
  File.open "rete.dot", "w" do |io|
15
- Graph.new( ds ).dot( io )
15
+ Graph.new(ds).dot(io)
16
16
  end
data/examples/rdf.rb CHANGED
@@ -4,7 +4,7 @@ require 'wongi-engine'
4
4
  engine = Wongi::Engine.create
5
5
  engine.rdf!
6
6
  parser = Wongi::RDF::Parser.new
7
- parser.parse_file File.expand_path( "rdf.n3", File.dirname(__FILE__) ), engine
7
+ parser.parse_file File.expand_path("rdf.n3", File.dirname(__FILE__)), engine
8
8
 
9
9
  engine.each do |wme|
10
10
  puts wme
data/examples/timeline.rb CHANGED
@@ -8,12 +8,12 @@ engine = Wongi::Engine.create
8
8
 
9
9
  engine.debug!
10
10
 
11
- engine.compile_alpha Wongi::Engine::Template.new( :_, :_, :_, 0 )
12
- engine.compile_alpha Wongi::Engine::Template.new( :_, :_, :_, -1 )
13
- engine.compile_alpha Wongi::Engine::Template.new( :_, :_, :_, -2 )
14
- engine.compile_alpha Wongi::Engine::Template.new( :_, :_, :_, -3 )
15
- engine.compile_alpha Wongi::Engine::Template.new( :_, :_, :_, -4 )
16
- engine.compile_alpha Wongi::Engine::Template.new( :_, :_, :_, -5 )
11
+ engine.compile_alpha Wongi::Engine::Template.new(:_, :_, :_, 0)
12
+ engine.compile_alpha Wongi::Engine::Template.new(:_, :_, :_, -1)
13
+ engine.compile_alpha Wongi::Engine::Template.new(:_, :_, :_, -2)
14
+ engine.compile_alpha Wongi::Engine::Template.new(:_, :_, :_, -3)
15
+ engine.compile_alpha Wongi::Engine::Template.new(:_, :_, :_, -4)
16
+ engine.compile_alpha Wongi::Engine::Template.new(:_, :_, :_, -5)
17
17
 
18
18
  engine.full_wme_dump
19
19
 
@@ -1,10 +1,8 @@
1
1
  module Wongi::Engine
2
-
3
2
  class AlphaMemory
4
-
5
3
  attr_reader :betas, :template, :rete
6
4
 
7
- def initialize template, rete = nil
5
+ def initialize(template, rete = nil)
8
6
  @template = template
9
7
  @rete = rete
10
8
  @betas = []
@@ -12,7 +10,7 @@ module Wongi::Engine
12
10
  @frozen = false
13
11
  end
14
12
 
15
- def activate wme
13
+ def activate(wme)
16
14
  wme.overlay.add_wme(wme, self)
17
15
  # 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
18
16
  betas.each do |beta|
@@ -20,15 +18,15 @@ module Wongi::Engine
20
18
  end
21
19
  end
22
20
 
23
- def deactivate wme
21
+ def deactivate(wme)
24
22
  wme.overlay.remove_wme(wme, self)
25
23
  betas.each do |beta|
26
24
  beta.alpha_deactivate wme
27
25
  end
28
26
  end
29
27
 
30
- def snapshot! alpha
31
- alpha.wmes.map( &:dup ).each do |wme|
28
+ def snapshot!(alpha)
29
+ alpha.wmes.map(&:dup).each do |wme|
32
30
  activate wme
33
31
  end
34
32
  end
@@ -54,7 +52,5 @@ module Wongi::Engine
54
52
  end
55
53
  end
56
54
  end
57
-
58
55
  end
59
-
60
56
  end
@@ -0,0 +1,93 @@
1
+ module Wongi::Engine
2
+ class AggregateNode < BetaNode
3
+ attr_reader :alpha, :tests, :assignment_pattern, :map, :function, :assign
4
+
5
+ def initialize(parent, alpha, tests, assignment, map, function, assign)
6
+ super(parent)
7
+ @alpha = alpha
8
+ @tests = tests
9
+ @assignment_pattern = assignment
10
+ @map = map
11
+ @function = function
12
+ @assign = assign
13
+ end
14
+
15
+ def equivalent?(alpha, tests, assignment_pattern)
16
+ return false if self.alpha != alpha
17
+ return false if self.assignment_pattern != assignment_pattern
18
+ return true if self.tests.empty? && tests.empty?
19
+ return false if self.tests.length != tests.length
20
+
21
+ self.tests.all? { |my_test|
22
+ tests.any? { |new_test|
23
+ my_test.equivalent? new_test
24
+ }
25
+ }
26
+ end
27
+
28
+ def alpha_activate(wme)
29
+ # we need to re-run all WMEs through the aggregator, so the new incoming one doesn't matter
30
+ parent.tokens.each do |token|
31
+ evaluate(wme, token)
32
+ end
33
+ end
34
+
35
+ def alpha_deactivate(wme)
36
+ # we need to re-run all WMEs through the aggregator, so the new incoming one doesn't matter
37
+ parent.tokens.each do |token|
38
+ evaluate(wme, token)
39
+ end
40
+ end
41
+
42
+ def beta_activate(token)
43
+ evaluate(nil, token)
44
+ end
45
+
46
+ def beta_deactivate(token)
47
+ children.each do |child|
48
+ child.tokens.each do |t|
49
+ child.beta_deactivate t if t.parent == token
50
+ end
51
+ end
52
+ end
53
+
54
+ def refresh_child(child)
55
+ parent.tokens.each do |token|
56
+ evaluate(nil, token, child)
57
+ end
58
+ end
59
+
60
+ def evaluate(wme, token, child = nil)
61
+ # clean up previous decisions
62
+ beta_deactivate(token)
63
+
64
+ candidates = alpha.wmes.select { |asserted_wme| matches?(token, asserted_wme) }
65
+
66
+ return if candidates.empty?
67
+
68
+ mapped = candidates.map(&map)
69
+ value = if function.is_a?(Symbol) && mapped.respond_to?(function)
70
+ mapped.send(function)
71
+ else
72
+ function.call(mapped)
73
+ end
74
+ assignments = { assign => value }
75
+ if child
76
+ child.beta_activate(Token.new(child, token, wme, assignments))
77
+ else
78
+ children.each do |beta|
79
+ beta.beta_activate(Token.new(beta, token, wme, assignments))
80
+ end
81
+ end
82
+ end
83
+
84
+ protected
85
+
86
+ def matches?(token, wme)
87
+ @tests.each do |test|
88
+ return false unless test.matches?(token, wme)
89
+ end
90
+ true
91
+ end
92
+ end
93
+ end
@@ -1,40 +1,32 @@
1
1
  module Wongi::Engine
2
-
3
2
  class AssignmentNode < BetaNode
4
-
5
- def initialize parent, variable, body
6
- super parent
7
- @variable, @body = variable, body
3
+ def initialize(parent, variable, body)
4
+ super(parent)
5
+ @variable = variable
6
+ @body = body
8
7
  end
9
8
 
10
- def beta_activate token, wme = nil, assignments = { }
9
+ def beta_activate(token, _wme = nil, _assignments = {})
11
10
  children.each do |child|
12
- child.beta_activate Token.new( child, token, nil, { @variable => @body.respond_to?(:call) ? @body.call(token) : @body } )
11
+ child.beta_activate Token.new(child, token, nil, { @variable => @body.respond_to?(:call) ? @body.call(token) : @body })
13
12
  end
14
13
  end
15
14
 
16
- def beta_deactivate token
15
+ def beta_deactivate(token)
17
16
  children.each do |child|
18
17
  child.tokens.each do |t|
19
18
  if t.parent == token
20
19
  child.beta_deactivate t
21
- #token.destroy
20
+ # token.destroy
22
21
  end
23
22
  end
24
23
  end
25
24
  end
26
25
 
27
- def refresh_child child
28
- tmp = children
29
- self.children = [ child ]
26
+ def refresh_child(child)
30
27
  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
28
+ child.beta_activate Token.new(child, token, nil, { @variable => @body.respond_to?(:call) ? @body.call(token) : @body })
34
29
  end
35
- self.children = tmp
36
30
  end
37
-
38
31
  end
39
-
40
32
  end
@@ -1,24 +1,24 @@
1
1
  module Wongi::Engine
2
-
3
2
  class BetaMemory < BetaNode
4
3
  include TokenContainer
5
4
 
6
- def seed assignments = {}
5
+ def seed(assignments = {})
7
6
  @seed = assignments
8
- t = Token.new( self, nil, nil, assignments )
7
+ t = Token.new(self, nil, nil, assignments)
9
8
  rete.default_overlay.add_token(t, self)
10
9
  end
11
10
 
12
- def subst valuations
11
+ def subst(valuations)
13
12
  beta_deactivate(tokens.first)
14
- token = Token.new( self, nil, nil, @seed )
13
+ token = Token.new(self, nil, nil, @seed)
15
14
  valuations.each { |variable, value| token.subst variable, value }
16
15
  beta_activate(token)
17
16
  end
18
17
 
19
- def beta_activate token
18
+ def beta_activate(token)
20
19
  existing = tokens.find { |et| et.duplicate? token }
21
- return if existing # TODO really?
20
+ return if existing # TODO: really?
21
+
22
22
  token.overlay.add_token(token, self)
23
23
  children.each do |child|
24
24
  child.beta_activate token
@@ -26,8 +26,9 @@ module Wongi::Engine
26
26
  token
27
27
  end
28
28
 
29
- def beta_deactivate token
29
+ def beta_deactivate(token)
30
30
  return nil unless tokens.find token
31
+
31
32
  token.overlay.remove_token(token, self)
32
33
  token.deleted!
33
34
  if token.parent
@@ -39,11 +40,21 @@ module Wongi::Engine
39
40
  token
40
41
  end
41
42
 
42
- def refresh_child child
43
+ def refresh_child(child)
43
44
  tokens.each do |token|
44
45
  child.beta_activate token
45
46
  end
46
47
  end
48
+ end
47
49
 
50
+ # SingletonBetaMemory is a memory node that only holds one token at a time.
51
+ # It should only be used after aggregate nodes.
52
+ class SingletonBetaMemory < BetaMemory
53
+ def beta_activate(token)
54
+ if (t = tokens.first)
55
+ beta_deactivate(t)
56
+ end
57
+ super
58
+ end
48
59
  end
49
60
  end
@@ -1,7 +1,5 @@
1
1
  module Wongi::Engine
2
-
3
2
  class BetaNode
4
-
5
3
  module TokenContainer
6
4
  def tokens
7
5
  Enumerator.new do |y|
@@ -9,7 +7,7 @@ module Wongi::Engine
9
7
  overlay.raw_tokens(self).dup.each do |token|
10
8
  y << token unless token.deleted?
11
9
  end
12
- overlay.raw_tokens(self).reject! &:deleted?
10
+ overlay.raw_tokens(self).reject!(&:deleted?)
13
11
  end
14
12
  end
15
13
  end
@@ -26,16 +24,16 @@ module Wongi::Engine
26
24
  include CoreExt
27
25
 
28
26
  attr_writer :rete
27
+ # @return [Wongi::Engine::BetaNode]
29
28
  attr_reader :parent
30
29
  attr_accessor :children
30
+
31
31
  attr_predicate :debug
32
32
 
33
- def initialize parent = nil
33
+ def initialize(parent = nil)
34
34
  @parent = parent
35
35
  @children = []
36
- if parent
37
- parent.children << self
38
- end
36
+ parent.children << self if parent
39
37
  end
40
38
 
41
39
  def root?
@@ -44,16 +42,14 @@ module Wongi::Engine
44
42
 
45
43
  def depth
46
44
  @depth ||= if parent.nil?
47
- 0
48
- else
49
- parent.depth + 1
50
- end
45
+ 0
46
+ else
47
+ parent.depth + 1
48
+ end
51
49
  end
52
50
 
53
51
  def rete
54
- @rete ||= if parent
55
- parent.rete
56
- end
52
+ @rete ||= (parent.rete if parent)
57
53
  end
58
54
 
59
55
  abstract :alpha_activate
@@ -63,7 +59,7 @@ module Wongi::Engine
63
59
  abstract :beta_deactivate
64
60
  abstract :beta_reactivate
65
61
 
66
- def assignment_node variable, body
62
+ def assignment_node(variable, body)
67
63
  node = AssignmentNode.new self, variable, body
68
64
  node.refresh
69
65
  node
@@ -73,22 +69,18 @@ module Wongi::Engine
73
69
  parent.refresh_child self
74
70
  end
75
71
 
76
- def refresh_child node
72
+ def refresh_child(_node)
77
73
  raise "#{self.class} must implement refresh_child"
78
74
  end
79
75
 
80
76
  private
81
77
 
82
- def dp message
83
- if debug?
84
- puts "#{indent}#{message}"
85
- end
78
+ def dp(message)
79
+ puts "#{indent}#{message}" if debug?
86
80
  end
87
81
 
88
82
  def indent
89
83
  ' ' * depth
90
84
  end
91
-
92
85
  end
93
-
94
86
  end
@@ -1,48 +1,45 @@
1
1
  module Wongi
2
2
  module Engine
3
-
4
3
  class FilterNode < BetaNode
5
-
4
+ # @return [Wongi::Engine::FilterTest]
6
5
  attr_accessor :test
7
6
 
8
- def initialize parent, test
7
+ def initialize(parent, test)
9
8
  super parent
10
9
  self.test = test
11
10
  end
12
11
 
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
12
+ def beta_activate(token)
13
+ return unless test.passes?(token)
14
+
15
+ children.each do |child|
16
+ child.beta_activate Token.new(child, token, nil, {})
18
17
  end
19
18
  end
20
19
 
21
- def beta_deactivate token
20
+ def beta_deactivate(token)
22
21
  children.each do |child|
23
22
  child.tokens.each do |t|
24
23
  if t.parent == token
25
24
  child.beta_deactivate t
26
- #token.destroy
25
+ # token.destroy
27
26
  end
28
27
  end
29
28
  end
30
29
  end
31
30
 
32
- def equivalent? test
31
+ def equivalent?(test)
33
32
  test == self.test
34
33
  end
35
34
 
36
- def refresh_child child
35
+ def refresh_child(child)
37
36
  tmp = children
38
- self.children = [ child ]
37
+ self.children = [child]
39
38
  parent.tokens.each do |token|
40
39
  beta_activate token
41
40
  end
42
41
  self.children = tmp
43
42
  end
44
-
45
43
  end
46
-
47
44
  end
48
45
  end