wongi-engine 0.3.6 → 0.3.7

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.
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
@@ -1,20 +1,17 @@
1
1
  module Wongi::Engine
2
-
3
2
  class AssertingTest < FilterTest
4
-
5
- def initialize *vars, &body
3
+ def initialize(*vars, &body)
4
+ super()
6
5
  @vars = vars
7
6
  @body = body
8
7
  end
9
8
 
10
- def passes? token
9
+ def passes?(token)
11
10
  if @vars.empty?
12
11
  @body.call token
13
12
  else
14
- @body.call *( @vars.map { |var| token[var] } )
13
+ @body.call(*(@vars.map { |var| token[var] }))
15
14
  end
16
15
  end
17
-
18
16
  end
19
-
20
17
  end
@@ -1,36 +1,33 @@
1
1
  module Wongi::Engine
2
-
3
2
  class EqualityTest < FilterTest
4
-
5
3
  attr_reader :x, :y
6
4
 
7
- def initialize x, y
8
- @x, @y = x, y
5
+ def initialize(x, y)
6
+ super()
7
+ @x = x
8
+ @y = y
9
9
  end
10
10
 
11
- def passes? token
12
-
11
+ def passes?(token)
13
12
  x = if Template.variable? @x
14
- token[@x]
15
- else
16
- @x
17
- end
13
+ token[@x]
14
+ else
15
+ @x
16
+ end
18
17
 
19
18
  y = if Template.variable? @y
20
- token[@y]
21
- else
22
- @y
23
- end
19
+ token[@y]
20
+ else
21
+ @y
22
+ end
24
23
 
25
24
  return false if x == :_ || y == :_
26
- return x == y
27
25
 
26
+ x == y
28
27
  end
29
28
 
30
- def == other
29
+ def ==(other)
31
30
  super && x == other.x && y == other.y
32
31
  end
33
-
34
32
  end
35
-
36
33
  end
@@ -1,18 +1,15 @@
1
1
  module Wongi::Engine
2
-
3
2
  class FilterTest
4
-
5
- def passes? token
3
+ def passes?(_token)
6
4
  raise "#{self.class} must implement #passes?"
7
5
  end
8
6
 
9
- def compile context
7
+ def compile(context)
10
8
  context.tap { |c| c.filter_node(self) }
11
9
  end
12
10
 
13
- def == other
11
+ def ==(_other)
14
12
  false
15
13
  end
16
14
  end
17
-
18
15
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Wongi::Engine
3
4
  class GreaterThanOrEqualTest < FilterTest
4
5
  attr_reader :x, :y
5
6
 
6
7
  def initialize(x, y)
8
+ super()
7
9
  @x = x
8
10
  @y = y
9
11
  end
@@ -13,15 +15,16 @@ module Wongi::Engine
13
15
  token[@x]
14
16
  else
15
17
  @x
16
- end
18
+ end
17
19
 
18
20
  y = if Template.variable? @y
19
21
  token[@y]
20
22
  else
21
23
  @y
22
- end
24
+ end
23
25
 
24
26
  return false if x == :_ || y == :_
27
+
25
28
  x >= y
26
29
  end
27
30
 
@@ -1,36 +1,33 @@
1
1
  module Wongi::Engine
2
-
3
2
  class GreaterThanTest < FilterTest
4
-
5
3
  attr_reader :x, :y
6
4
 
7
- def initialize x, y
8
- @x, @y = x, y
5
+ def initialize(x, y)
6
+ super()
7
+ @x = x
8
+ @y = y
9
9
  end
10
10
 
11
- def passes? token
12
-
11
+ def passes?(token)
13
12
  x = if Template.variable? @x
14
- token[@x]
15
- else
16
- @x
17
- end
13
+ token[@x]
14
+ else
15
+ @x
16
+ end
18
17
 
19
18
  y = if Template.variable? @y
20
- token[@y]
21
- else
22
- @y
23
- end
19
+ token[@y]
20
+ else
21
+ @y
22
+ end
24
23
 
25
24
  return false if x == :_ || y == :_
26
- return x > y
27
25
 
26
+ x > y
28
27
  end
29
28
 
30
- def == other
29
+ def ==(other)
31
30
  super && x == other.x && y == other.y
32
31
  end
33
-
34
32
  end
35
-
36
33
  end
@@ -1,36 +1,33 @@
1
1
  module Wongi::Engine
2
-
3
2
  class InequalityTest < FilterTest
4
-
5
3
  attr_reader :x, :y
6
4
 
7
- def initialize x, y
8
- @x, @y = x, y
5
+ def initialize(x, y)
6
+ super()
7
+ @x = x
8
+ @y = y
9
9
  end
10
10
 
11
- def passes? token
12
-
11
+ def passes?(token)
13
12
  x = if Template.variable? @x
14
- token[@x]
15
- else
16
- @x
17
- end
13
+ token[@x]
14
+ else
15
+ @x
16
+ end
18
17
 
19
18
  y = if Template.variable? @y
20
- token[@y]
21
- else
22
- @y
23
- end
19
+ token[@y]
20
+ else
21
+ @y
22
+ end
24
23
 
25
24
  return false if x == :_ || y == :_
26
- return x != y
27
25
 
26
+ x != y
28
27
  end
29
28
 
30
- def == other
29
+ def ==(other)
31
30
  super && x == other.x && y == other.y
32
31
  end
33
-
34
32
  end
35
-
36
33
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Wongi::Engine
3
4
  class LessThanOrEqualTest < FilterTest
4
5
  attr_reader :x, :y
5
6
 
6
7
  def initialize(x, y)
8
+ super()
7
9
  @x = x
8
10
  @y = y
9
11
  end
@@ -13,15 +15,16 @@ module Wongi::Engine
13
15
  token[@x]
14
16
  else
15
17
  @x
16
- end
18
+ end
17
19
 
18
20
  y = if Template.variable? @y
19
21
  token[@y]
20
22
  else
21
23
  @y
22
- end
24
+ end
23
25
 
24
26
  return false if x == :_ || y == :_
27
+
25
28
  x <= y
26
29
  end
27
30
 
@@ -1,36 +1,33 @@
1
1
  module Wongi::Engine
2
-
3
2
  class LessThanTest < FilterTest
4
-
5
3
  attr_reader :x, :y
6
4
 
7
- def initialize x, y
8
- @x, @y = x, y
5
+ def initialize(x, y)
6
+ super()
7
+ @x = x
8
+ @y = y
9
9
  end
10
10
 
11
- def passes? token
12
-
11
+ def passes?(token)
13
12
  x = if Template.variable? @x
14
- token[@x]
15
- else
16
- @x
17
- end
13
+ token[@x]
14
+ else
15
+ @x
16
+ end
18
17
 
19
18
  y = if Template.variable? @y
20
- token[@y]
21
- else
22
- @y
23
- end
19
+ token[@y]
20
+ else
21
+ @y
22
+ end
24
23
 
25
24
  return false if x == :_ || y == :_
26
- return x < y
27
25
 
26
+ x < y
28
27
  end
29
28
 
30
- def == other
29
+ def ==(other)
31
30
  super && x == other.x && y == other.y
32
31
  end
33
-
34
32
  end
35
-
36
33
  end
@@ -5,4 +5,4 @@ require 'wongi-engine/filter/asserting_test'
5
5
  require 'wongi-engine/filter/less_than_test'
6
6
  require 'wongi-engine/filter/greater_than_test'
7
7
  require 'wongi-engine/filter/less_than_or_equal_test'
8
- require 'wongi-engine/filter/greater_than_or_equal_test'
8
+ require 'wongi-engine/filter/greater_than_or_equal_test'
@@ -1,16 +1,13 @@
1
1
  module Wongi::Engine
2
-
3
2
  class Graph
4
-
5
- def initialize rete
3
+ def initialize(rete)
6
4
  @rete = rete
7
5
  end
8
6
 
9
- def dot io, opts = { }
10
-
7
+ def dot(io, opts = {})
11
8
  @seen_betas = []
12
9
 
13
- if String === io
10
+ if io.is_a?(String)
14
11
  File.open io, "w" do |actual_io|
15
12
  dot actual_io
16
13
  end
@@ -25,49 +22,45 @@ module Wongi::Engine
25
22
  dump_betas(opts)
26
23
 
27
24
  @io.puts "}"
28
-
29
25
  ensure
30
26
  @io = nil
31
27
  end
32
28
 
33
29
  private
34
30
 
35
- def print_hash h
36
- h.to_s.gsub /-/, '_'
31
+ def print_hash(h)
32
+ h.to_s.gsub(/-/, '_')
37
33
  end
38
34
 
39
- def dump_alphas opts
35
+ def dump_alphas(_opts)
40
36
  @io.puts "subgraph cluster_alphas {"
41
- @rete.alphas.select { |alpha| not alpha.betas.empty? }.each do |alpha|
42
- @io.puts "node#{print_hash alpha.object_id} [shape=box label=\"#{alpha.template.to_s.gsub /"/, "\\\""}\"];"
37
+ @rete.alphas.reject { |alpha| alpha.betas.empty? }.each do |alpha|
38
+ @io.puts "node#{print_hash alpha.object_id} [shape=box label=\"#{alpha.template.to_s.gsub(/"/, '"')}\"];"
43
39
  end
44
40
  @io.puts "};"
45
41
  end
46
42
 
47
- def dump_betas opts
43
+ def dump_betas(opts)
48
44
  dump_beta @rete.beta_top, opts
49
45
  end
50
46
 
51
- def dump_beta beta, opts
47
+ def dump_beta(beta, opts)
52
48
  return if @seen_betas.include? beta
49
+
53
50
  @seen_betas << beta
54
51
  @io.puts "node#{print_hash beta.object_id} [label=\"#{beta.class.name.split('::').last}\"];"
55
52
  if beta.is_a? NccNode
56
53
  @io.puts "node#{print_hash beta.partner.object_id} -> node#{print_hash beta.object_id};"
57
54
  @io.puts "{ rank=same; node#{print_hash beta.partner.object_id} node#{print_hash beta.object_id} }"
58
55
  end
59
- if beta.respond_to? :alpha and opts[:alpha] != false
56
+ if beta.respond_to?(:alpha) && opts[:alpha] != false
60
57
  alpha = beta.alpha
61
- if alpha
62
- @io.puts "node#{print_hash alpha.object_id} -> node#{print_hash beta.object_id};"
63
- end
58
+ @io.puts "node#{print_hash alpha.object_id} -> node#{print_hash beta.object_id};" if alpha
64
59
  end
65
60
  beta.children.each do |child|
66
61
  @io.puts "node#{print_hash beta.object_id} -> node#{print_hash child.object_id};"
67
62
  dump_beta child, opts
68
63
  end
69
64
  end
70
-
71
65
  end
72
-
73
66
  end
@@ -1,12 +1,10 @@
1
1
  module Wongi::Engine
2
2
  module NetworkParts
3
-
4
3
  module Collectable
5
-
6
- def collectors name = nil
7
- @collectors ||= { }
4
+ def collectors(name = nil)
5
+ @collectors ||= {}
8
6
  if name
9
- @collectors[name] ||= [ ]
7
+ @collectors[name] ||= []
10
8
  else
11
9
  @collectors
12
10
  end
@@ -16,27 +14,25 @@ module Wongi::Engine
16
14
  collectors :error
17
15
  end
18
16
 
19
- def add_collector collector, name
20
- collectors( name ) << collector
17
+ def add_collector(collector, name)
18
+ collectors(name) << collector
21
19
  end
22
20
 
23
21
  def add_error_collector
24
22
  add_collector collector, :error
25
23
  end
26
24
 
27
- def collection name
28
- collectors( name ).map( &:default_collect ).flatten.uniq
25
+ def collection(name)
26
+ collectors(name).map(&:default_collect).flatten.uniq
29
27
  end
30
28
 
31
29
  def errors
32
- error_collectors.map( &:errors ).flatten
30
+ error_collectors.map(&:errors).flatten
33
31
  end
34
32
 
35
- def collected_tokens name
36
- collectors( name ).map { |collector| collector.production.tokens }.flatten
33
+ def collected_tokens(name)
34
+ collectors(name).map { |collector| collector.production.tokens }.flatten
37
35
  end
38
-
39
36
  end
40
-
41
37
  end
42
38
  end
@@ -1,25 +1,21 @@
1
1
  module Wongi::Engine
2
-
3
2
  module NetworkParts
4
-
5
3
  module Debug
6
-
7
4
  def full_wme_dump
8
5
  @timeline.each_with_index do |slice, index|
9
- puts "time #{ index - @timeline.length }"
10
- slice.each do |key, alpha|
11
- puts "\t#{alpha.template} -> [#{alpha.wmes.map(&:to_s).join ", "}]"
6
+ puts "time #{index - @timeline.length}"
7
+ slice.each do |_key, alpha|
8
+ puts "\t#{alpha.template} -> [#{alpha.wmes.map(&:to_s).join ', '}]"
12
9
  end
13
10
  puts ""
14
11
  end
15
12
  puts "time 0"
16
- alpha_hash.each do |key, alpha|
17
- puts "\t#{alpha.template} -> [#{alpha.wmes.map(&:to_s).join ", "}]"
13
+ alpha_hash.each do |_key, alpha|
14
+ puts "\t#{alpha.template} -> [#{alpha.wmes.map(&:to_s).join ', '}]"
18
15
  end
19
16
  end
20
17
 
21
- def full_dump io = $stdout
22
-
18
+ def full_dump(io = $stdout)
23
19
  alpha_hash.each_value do |alpha|
24
20
  io.puts "ALPHA #{alpha.template}"
25
21
  alpha.wmes.each do |wme|
@@ -27,12 +23,11 @@ module Wongi::Engine
27
23
  end
28
24
  end
29
25
  dump_beta beta_top, io
30
-
31
26
  end
32
27
 
33
28
  private
34
29
 
35
- def token_lineage token
30
+ def token_lineage(token)
36
31
  result = []
37
32
  while token.parent
38
33
  result << token.parent
@@ -41,14 +36,14 @@ module Wongi::Engine
41
36
  result
42
37
  end
43
38
 
44
- def dump_wme wme, io
39
+ def dump_wme(wme, io)
45
40
  io.puts "\tWME: #{wme.object_id} #{wme}"
46
41
  wme.tokens.each { |token| io.puts "\t\tTOKEN #{token.object_id}" }
47
42
  io.puts "\tGENERATING:" unless wme.generating_tokens.empty?
48
43
  wme.generating_tokens.each { |token| io.puts "\t\tTOKEN #{token.object_id}" }
49
44
  end
50
45
 
51
- def dump_beta beta, io
46
+ def dump_beta(beta, io)
52
47
  case beta
53
48
  when BetaMemory
54
49
  dump_beta_memory beta, io
@@ -58,28 +53,25 @@ module Wongi::Engine
58
53
  io.puts "BETA #{beta.object_id} #{beta.class} : TODO"
59
54
 
60
55
  end
61
- io.puts "\tCHILDREN: #{beta.children.map(&:object_id).join ", "}"
56
+ io.puts "\tCHILDREN: #{beta.children.map(&:object_id).join ', '}"
62
57
  beta.children.each { |child| dump_beta child, io } unless beta.children.empty?
63
58
  end
64
59
 
65
- def dump_beta_memory beta, io
60
+ def dump_beta_memory(beta, io)
66
61
  io.puts "BETA MEMORY #{beta.object_id}"
67
62
  beta.tokens.each { |token|
68
- io.puts "\tTOKEN #{token.object_id} [#{token_lineage(token).map(&:object_id).map(&:to_s).join(" - ")}]"
69
- token.wmes.each { |wme| io.puts "\t\tWME " + wme.object_id.to_s }
63
+ io.puts "\tTOKEN #{token.object_id} [#{token_lineage(token).map(&:object_id).map(&:to_s).join(' - ')}]"
64
+ token.wmes.each { |wme| io.puts "\t\tWME #{wme.object_id}" }
70
65
  }
71
66
  end
72
67
 
73
- def dump_ncc beta, io
68
+ def dump_ncc(beta, io)
74
69
  io.puts "NCC #{beta.object_id}"
75
70
  beta.tokens.each { |token|
76
- io.puts "\tTOKEN #{token.object_id} [#{token_lineage(token).map(&:object_id).map(&:to_s).join(" - ")}]"
77
- token.wmes.each { |wme| io.puts "\t\tWME " + wme.object_id.to_s }
71
+ io.puts "\tTOKEN #{token.object_id} [#{token_lineage(token).map(&:object_id).map(&:to_s).join(' - ')}]"
72
+ token.wmes.each { |wme| io.puts "\t\tWME #{wme.object_id}" }
78
73
  }
79
74
  end
80
-
81
75
  end
82
-
83
76
  end
84
-
85
77
  end