mort666-wongi-engine 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.hgignore +6 -0
  4. data/.hgtags +13 -0
  5. data/.ruby-gemset +1 -0
  6. data/.travis.yml +19 -0
  7. data/CHANGELOG.md +106 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE +22 -0
  10. data/README.md +27 -0
  11. data/Rakefile +9 -0
  12. data/examples/ex01.rb +23 -0
  13. data/examples/ex02.rb +37 -0
  14. data/examples/graphviz.rb +16 -0
  15. data/examples/rdf.n3 +6 -0
  16. data/examples/rdf.rb +14 -0
  17. data/examples/timeline.rb +48 -0
  18. data/lib/wongi-engine.rb +36 -0
  19. data/lib/wongi-engine/alpha_memory.rb +60 -0
  20. data/lib/wongi-engine/beta.rb +11 -0
  21. data/lib/wongi-engine/beta/assignment_node.rb +40 -0
  22. data/lib/wongi-engine/beta/beta_memory.rb +49 -0
  23. data/lib/wongi-engine/beta/beta_node.rb +94 -0
  24. data/lib/wongi-engine/beta/filter_node.rb +48 -0
  25. data/lib/wongi-engine/beta/join_node.rb +140 -0
  26. data/lib/wongi-engine/beta/ncc_node.rb +67 -0
  27. data/lib/wongi-engine/beta/ncc_partner.rb +40 -0
  28. data/lib/wongi-engine/beta/neg_node.rb +115 -0
  29. data/lib/wongi-engine/beta/optional_node.rb +142 -0
  30. data/lib/wongi-engine/beta/or_node.rb +37 -0
  31. data/lib/wongi-engine/beta/production_node.rb +31 -0
  32. data/lib/wongi-engine/compiler.rb +115 -0
  33. data/lib/wongi-engine/core_ext.rb +63 -0
  34. data/lib/wongi-engine/data_overlay.rb +144 -0
  35. data/lib/wongi-engine/dsl.rb +132 -0
  36. data/lib/wongi-engine/dsl/action/base.rb +11 -0
  37. data/lib/wongi-engine/dsl/action/error_generator.rb +31 -0
  38. data/lib/wongi-engine/dsl/action/simple_action.rb +60 -0
  39. data/lib/wongi-engine/dsl/action/simple_collector.rb +52 -0
  40. data/lib/wongi-engine/dsl/action/statement_generator.rb +46 -0
  41. data/lib/wongi-engine/dsl/action/trace_action.rb +49 -0
  42. data/lib/wongi-engine/dsl/any_rule.rb +33 -0
  43. data/lib/wongi-engine/dsl/assuming.rb +31 -0
  44. data/lib/wongi-engine/dsl/builder.rb +44 -0
  45. data/lib/wongi-engine/dsl/clause/assign.rb +15 -0
  46. data/lib/wongi-engine/dsl/clause/fact.rb +71 -0
  47. data/lib/wongi-engine/dsl/clause/gen.rb +17 -0
  48. data/lib/wongi-engine/dsl/clause/generic.rb +38 -0
  49. data/lib/wongi-engine/dsl/generated.rb +43 -0
  50. data/lib/wongi-engine/dsl/ncc_subrule.rb +17 -0
  51. data/lib/wongi-engine/dsl/query.rb +24 -0
  52. data/lib/wongi-engine/dsl/rule.rb +84 -0
  53. data/lib/wongi-engine/enumerators.rb +21 -0
  54. data/lib/wongi-engine/error.rb +22 -0
  55. data/lib/wongi-engine/filter.rb +6 -0
  56. data/lib/wongi-engine/filter/asserting_test.rb +20 -0
  57. data/lib/wongi-engine/filter/equality_test.rb +36 -0
  58. data/lib/wongi-engine/filter/filter_test.rb +18 -0
  59. data/lib/wongi-engine/filter/greater_than_test.rb +36 -0
  60. data/lib/wongi-engine/filter/inequality_test.rb +36 -0
  61. data/lib/wongi-engine/filter/less_than_test.rb +36 -0
  62. data/lib/wongi-engine/graph.rb +73 -0
  63. data/lib/wongi-engine/network.rb +416 -0
  64. data/lib/wongi-engine/network/collectable.rb +42 -0
  65. data/lib/wongi-engine/network/debug.rb +85 -0
  66. data/lib/wongi-engine/ruleset.rb +74 -0
  67. data/lib/wongi-engine/template.rb +78 -0
  68. data/lib/wongi-engine/token.rb +114 -0
  69. data/lib/wongi-engine/version.rb +5 -0
  70. data/lib/wongi-engine/wme.rb +89 -0
  71. data/lib/wongi-engine/wme_match_data.rb +34 -0
  72. data/spec/beta_node_spec.rb +29 -0
  73. data/spec/bug_specs/issue_4_spec.rb +141 -0
  74. data/spec/dataset_spec.rb +27 -0
  75. data/spec/dsl_spec.rb +9 -0
  76. data/spec/filter_specs/assert_test_spec.rb +102 -0
  77. data/spec/filter_specs/less_test_spec.rb +41 -0
  78. data/spec/generation_spec.rb +116 -0
  79. data/spec/high_level_spec.rb +378 -0
  80. data/spec/network_spec.rb +182 -0
  81. data/spec/overlay_spec.rb +61 -0
  82. data/spec/rule_specs/any_rule_spec.rb +75 -0
  83. data/spec/rule_specs/assign_spec.rb +88 -0
  84. data/spec/rule_specs/assuming_spec.rb +66 -0
  85. data/spec/rule_specs/maybe_rule_spec.rb +101 -0
  86. data/spec/rule_specs/ncc_spec.rb +258 -0
  87. data/spec/rule_specs/negative_rule_spec.rb +105 -0
  88. data/spec/ruleset_spec.rb +54 -0
  89. data/spec/simple_action_spec.rb +40 -0
  90. data/spec/spec_helper.rb +3 -0
  91. data/spec/wme_spec.rb +83 -0
  92. data/wongi-engine.gemspec +40 -0
  93. metadata +212 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 12af94d3d41d654a50765629e1e9d5e00ac16191
4
+ data.tar.gz: cba9301423232c6e383123dedd2a13df65d72217
5
+ SHA512:
6
+ metadata.gz: e08fdafc7be2abd537ac06953594ec8880a4e1be39a95c87678897ee44e5229ea9f9de7e706b1acaeb85494faec9f4c46624659702a83dccdc45b442f1ca5928
7
+ data.tar.gz: c2844b38099dec1ac0f3654e5d8ecc7103237a59a2b4cd8a6d786194747de0446cc92f3187c449858b85acffc30d44bd61155fb14224ae927ed71f05780da526
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rspec
7
+ .rvmrc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
20
+ .ruby-version
@@ -0,0 +1,6 @@
1
+ syntax: glob
2
+ *.DS_Store
3
+ Gemfile.lock
4
+ .rspec
5
+ .ruby-version
6
+
data/.hgtags ADDED
@@ -0,0 +1,13 @@
1
+ b1dfd471a2a9e4a57f0e4932ac184faa5d6fa5b5 v0.1.0.alpha1
2
+ cf7d0e690fb65541b19074e132813c79a36d12c5 v0.1.0
3
+ accab6252d5746dafe847935ad55f8500594d0cc v0.1.1
4
+ 0000000000000000000000000000000000000000 v0.1.1
5
+ 80964eb067a8445980b27e871731ff1274bd7be2 v0.2.1
6
+ 808537c4e3a2defd382fd8f0a662f8850c70aa1f v0.2.2
7
+ b8b5d5ac7b39ce11d9bb86e61fcb04b227aca02d v0.2.7
8
+ 2b0925ffd7d5c9acc48ffd873abff9a3b6ed66c3 v0.2.8
9
+ 2b0925ffd7d5c9acc48ffd873abff9a3b6ed66c3 v0.2.8
10
+ 5692396d6db5ab9a9b1d26a0f41686124f87de62 v0.2.8
11
+ a2f9d52603db027baced51f673daf46b8fe8745a v0.2.9
12
+ a2f9d52603db027baced51f673daf46b8fe8745a v0.2.9
13
+ da4529420721bdd153839261e624b3738e7355e9 v0.2.9
@@ -0,0 +1 @@
1
+ wongi-engine
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.10
4
+ - 2.2.6
5
+ - 2.3.3
6
+ - 2.4.0
7
+ - jruby-9.0
8
+ sudo: false
9
+ notifications:
10
+ hipchat:
11
+ rooms:
12
+ secure: OwpsmGlIxlSbLUWVZZI+xBErDkFc5XO2vmjs+ddQkNiL1E9N5SG35x75113S6EZ3qhqeNMPFBfZYDqem6jkhNOWsmH3EIH+QT1lWxnosrr0LgyJpvFosvjQaryvqJHVhT5tdBqzaWEYB6ObRLOUt7A5YrbtWHyTScB6ThpXCiR4=
13
+ webhooks:
14
+ urls:
15
+ - secure: Xm+R/3O6iG2sDbfrR8D5Y9AYJkB7DDjLBcKZEn+xaTVjuX/XFLF7p+v9n9v7Qs/v0VtU75pVX4Z++OmNJZJzJKB3Owgb4c1rMOGmctza2JPL+1yovmhpG0/S0hjMkO5g4CsAKKcQoaDXNrubUVHpEchLPP/aCx7/F4twCan9bfc=
16
+ on_success: always
17
+ on_failure: always
18
+ on_start: false
19
+
@@ -0,0 +1,106 @@
1
+ # Changelog
2
+
3
+ ## 0.2.9
4
+
5
+ * fixed a bug preventing variables being bound to `false` and `nil`
6
+
7
+ ## 0.2.8
8
+
9
+ * fixed a namespacing bug affecting code not including the DSL module
10
+
11
+ ## 0.2.7
12
+
13
+ * fixed an NCC deactivation bug
14
+
15
+ ## 0.2.6
16
+
17
+ * fixed `Network#each`
18
+
19
+ ## 0.2.5
20
+
21
+ * fixed some overlay-related memory leaks
22
+
23
+ ## 0.2.3
24
+
25
+ * fixed the error collector
26
+
27
+ ## 0.2.2
28
+
29
+ * fixed retention of WMEs added to an overlay
30
+
31
+ ## 0.2.1
32
+
33
+ * data overlay fixes
34
+
35
+ ## 0.2.0
36
+
37
+ * refactored compilation code
38
+ * [data overlays](https://github.com/ulfurinn/wongi-engine/issues/45)
39
+ * DSL methods are removed from `Object` and are available by including `Wongi::Engine::DSL` instead
40
+
41
+ ## 0.1.4
42
+
43
+ * fixed a bug in evaluation of `assign` nodes
44
+
45
+ ## 0.1.0
46
+
47
+ * massively rewritten rule activation; this simplifies development and debugging and opens the road for useful features such as fully reversible custom actions
48
+ * **treat this as a major upgrade and test thoroughly**
49
+
50
+ ## 0.0.17
51
+
52
+ * introduced the `assuming` matcher
53
+
54
+ ## 0.0.13
55
+
56
+ * fixed a bug with recursive generations of multiple facts
57
+
58
+ ## 0.0.12
59
+
60
+ * fixed another NCC bug
61
+
62
+ ## 0.0.11
63
+
64
+ * fixed cleanup of invalidated NCC branches
65
+
66
+ ## 0.0.10
67
+
68
+ * fixed interaction of filters and optional nodes
69
+
70
+ ## 0.0.9
71
+
72
+ * fixed the definition of `asserted` (#16)
73
+
74
+ ## 0.0.8
75
+
76
+ * preventing the feedback loop introduced in 0.0.7; experimental
77
+
78
+ ## 0.0.7
79
+
80
+ * added a guard against introducing variables in neg clauses
81
+ * fixed execution context of simple action block (#7)
82
+ * fixed #4 once more, better
83
+ * fixed a bug with OptionalNode (#12)
84
+ * fixed behaviour of neg nodes; this will cause feedback loops when a gen action creates a fact that invalidates the action's condition
85
+
86
+ ## 0.0.6
87
+
88
+ * fixed a bug caused by retracting facts from within a rule action (#4)
89
+
90
+ ## 0.0.5
91
+
92
+ * fixed a bug with multiple `assert` tests following the same node (#2)
93
+
94
+ ## 0.0.4
95
+
96
+ * reintegrated RDF support
97
+ * collapsible filter matchers
98
+
99
+ ## 0.0.3
100
+
101
+ * bug fixes
102
+ * `assert`, `assign`
103
+
104
+ ## 0.0.1
105
+
106
+ * initial repackaged release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wongi-engine.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012-2015 Valeri Sokolov <ulfurinn@ulfurinn.net>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,27 @@
1
+ # Wongi::Engine
2
+
3
+ [![Join the chat at https://gitter.im/ulfurinn/wongi-engine](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ulfurinn/wongi-engine?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+
5
+ [![Build Status](https://travis-ci.org/ulfurinn/wongi-engine.svg?branch=master)](https://travis-ci.org/ulfurinn/wongi-engine) (MRI 1.9.3 to 2.3, Rubinius, JRuby)
6
+
7
+ [Feature annoucements](https://github.com/ulfurinn/wongi-engine/issues?q=is%3Aopen+is%3Aissue+label%3Aannoucement)
8
+
9
+ [Open discussions](https://github.com/ulfurinn/wongi-engine/issues?q=is%3Aopen+is%3Aissue+label%3Adiscussion)
10
+
11
+ [Tutorial](http://ulfurinn.github.io/wongi-engine/)
12
+
13
+ This library contains a rule engine written in Ruby. It's based on the [Rete algorithm](http://en.wikipedia.org/wiki/Rete_algorithm) and uses a DSL to express rules in a readable way.
14
+
15
+ **Word of caution**: this is complex and fragile machinery, and there may be subtle bugs that are only revealed with nontrivial usage. Be conservative with upgrades, test your rules extensively, and please report any behaviour that is not consistent with your expectations.
16
+
17
+ ## Acknowledgements
18
+
19
+ The Rete implementation in this library largely follows the outline presented in [\[Doorenbos, 1995\]](http://reports-archive.adm.cs.cmu.edu/anon/1995/CMU-CS-95-113.pdf).
20
+
21
+ ## Contributing
22
+
23
+ 1. Fork it
24
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
25
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
26
+ 4. Push to the branch (`git push origin my-new-feature`)
27
+ 5. Create new Pull Request
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new('spec')
7
+
8
+ # If you want to make this the default task
9
+ task :default => :spec
@@ -0,0 +1,23 @@
1
+ include Wongi::Engine
2
+
3
+ ds = Network.new
4
+
5
+ ds << WME.new( "Alice", "friend", "Bob" )
6
+
7
+ puts "Enumerate all:"
8
+
9
+ ds.each do |wme|
10
+ puts wme
11
+ end
12
+
13
+ puts "Enumerate by pattern:"
14
+
15
+ ds.each :_, "friend", :_ do |wme|
16
+ puts wme
17
+ end
18
+
19
+ puts "Mismatching pattern:"
20
+
21
+ ds.each :_, "foe", :_ do |wme|
22
+ puts wme
23
+ end
@@ -0,0 +1,37 @@
1
+ include Wongi::Engine
2
+ include Wongi::Engine::DSL
3
+
4
+ ds = Network.new
5
+
6
+ ds << ruleset {
7
+
8
+ name "Example"
9
+
10
+ rule "symmetric" do
11
+ forall {
12
+ has :P, "symmetric", true
13
+ has :A, :P, :B
14
+ }
15
+ make {
16
+ gen :B, :P, :A
17
+ }
18
+ end
19
+
20
+ }
21
+
22
+ puts "Installed ruleset"
23
+
24
+ ds << WME.new( "friend", "symmetric", true )
25
+ ds << WME.new( "Alice", "friend", "Bob" )
26
+
27
+ puts "Asserted facts:"
28
+
29
+ puts "Should print 3 facts:"
30
+ puts ds.wmes.to_a
31
+
32
+
33
+ ds.retract WME.new( "Alice", "friend", "Bob" )
34
+
35
+ puts "Should print 1 fact:"
36
+ puts ds.wmes.to_a
37
+
@@ -0,0 +1,16 @@
1
+ require 'wongi-engine'
2
+
3
+ include Wongi::Engine
4
+ include Wongi::Engine::DSL
5
+
6
+ ds = Network.new
7
+ ds << rule('demo') {
8
+ forall {
9
+ has 1, 2, 3
10
+ maybe 4, 5, 6
11
+ }
12
+ }
13
+
14
+ File.open "rete.dot", "w" do |io|
15
+ Graph.new( ds ).dot( io )
16
+ end
@@ -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
+ ] .
@@ -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
@@ -0,0 +1,48 @@
1
+ require 'wongi-engine'
2
+
3
+ def sep
4
+ puts "---------------------------"
5
+ end
6
+
7
+ engine = Wongi::Engine.create
8
+
9
+ engine.debug!
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 )
17
+
18
+ engine.full_wme_dump
19
+
20
+ sep
21
+
22
+ engine << [1, 1, 1]
23
+ engine.full_wme_dump
24
+ engine.snapshot!
25
+
26
+ sep
27
+
28
+ engine << [2, 2, 2]
29
+ engine.full_wme_dump
30
+ engine.snapshot!
31
+
32
+ sep
33
+
34
+ engine << [3, 3, 3]
35
+ engine.full_wme_dump
36
+ engine.snapshot!
37
+
38
+ sep
39
+
40
+ engine << [4, 4, 4]
41
+ engine.full_wme_dump
42
+ engine.snapshot!
43
+
44
+ sep
45
+
46
+ engine << [5, 5, 5]
47
+ engine.full_wme_dump
48
+ engine.snapshot!
@@ -0,0 +1,36 @@
1
+ module Wongi
2
+ module Engine
3
+
4
+ def self.create
5
+ Network.new
6
+ end
7
+
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
18
+ end
19
+
20
+ require 'wongi-engine/version'
21
+ require 'wongi-engine/core_ext'
22
+ require 'wongi-engine/error'
23
+ require 'wongi-engine/template'
24
+ require 'wongi-engine/wme'
25
+ require 'wongi-engine/wme_match_data'
26
+ require 'wongi-engine/token'
27
+ require 'wongi-engine/filter'
28
+ require 'wongi-engine/alpha_memory'
29
+ require 'wongi-engine/beta'
30
+ require 'wongi-engine/dsl'
31
+ require 'wongi-engine/ruleset'
32
+ require 'wongi-engine/compiler'
33
+ require 'wongi-engine/data_overlay'
34
+ require 'wongi-engine/enumerators'
35
+ require 'wongi-engine/network'
36
+ require 'wongi-engine/graph'
@@ -0,0 +1,60 @@
1
+ module Wongi::Engine
2
+
3
+ class AlphaMemory
4
+
5
+ attr_reader :betas, :template, :rete
6
+
7
+ def initialize template, rete = nil
8
+ @template = template
9
+ @rete = rete
10
+ @betas = []
11
+ @wmes = []
12
+ @frozen = false
13
+ end
14
+
15
+ def activate wme
16
+ wme.overlay.add_wme(wme, self)
17
+ # 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
+ betas.each do |beta|
19
+ beta.alpha_activate wme
20
+ end
21
+ end
22
+
23
+ def deactivate wme
24
+ wme.overlay.remove_wme(wme, self)
25
+ betas.each do |beta|
26
+ beta.alpha_deactivate wme
27
+ end
28
+ end
29
+
30
+ def snapshot! alpha
31
+ alpha.wmes.map( &:dup ).each do |wme|
32
+ activate wme
33
+ end
34
+ end
35
+
36
+ def inspect
37
+ "<Alpha #{__id__} template=#{template}>"
38
+ end
39
+
40
+ def to_s
41
+ inspect
42
+ end
43
+
44
+ def size
45
+ wmes.count
46
+ end
47
+
48
+ def wmes
49
+ Enumerator.new do |y|
50
+ rete.overlays.each do |overlay|
51
+ overlay.raw_wmes(self).dup.each do |wme|
52
+ y << wme
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end