ruleby 0.9.b4 → 0.9.b7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitignore +5 -0
  2. data/GPL.txt +341 -0
  3. data/LICENSE.txt +52 -0
  4. data/README.markdown +22 -0
  5. data/benchmarks/basic_rules.rb +61 -0
  6. data/benchmarks/joined_rules.rb +66 -0
  7. data/benchmarks/miss_manners/data.rb +146 -0
  8. data/benchmarks/miss_manners/miss_manners.rb +33 -0
  9. data/benchmarks/miss_manners/model.rb +193 -0
  10. data/benchmarks/miss_manners/rules.rb +105 -0
  11. data/benchmarks/model.rb +36 -0
  12. data/examples/diagnosis.rb +129 -0
  13. data/examples/fibonacci_example1.rb +44 -0
  14. data/examples/fibonacci_example2.rb +40 -0
  15. data/examples/fibonacci_example3.rb +78 -0
  16. data/examples/fibonacci_rulebook.rb +84 -0
  17. data/examples/hello.rb +45 -0
  18. data/examples/ticket.rb +113 -0
  19. data/examples/wordgame.rb +107 -0
  20. data/lib/core/engine.rb +26 -24
  21. data/lib/core/nodes.rb +77 -35
  22. data/lib/ruleby.rb +0 -37
  23. data/ruleby.gemspec +17 -0
  24. data/spec/and_or_spec.rb +252 -0
  25. data/spec/coercion_spec.rb +5 -0
  26. data/spec/collect_spec.rb +1021 -0
  27. data/spec/errors_spec.rb +148 -0
  28. data/spec/ferrari_spec.rb +39 -0
  29. data/spec/function_spec.rb +199 -0
  30. data/spec/hello_spec.rb +34 -0
  31. data/spec/node_sharing_spec.rb +53 -0
  32. data/spec/property_spec.rb +69 -0
  33. data/spec/spec.opts +4 -0
  34. data/spec/spec_helper.rb +9 -0
  35. data/tasks/documentation.rake +32 -0
  36. data/tasks/rspec.rake +21 -0
  37. data/tasks/test.rake +9 -0
  38. data/tests/assert_facts.rb +130 -0
  39. data/tests/common.rb +29 -0
  40. data/tests/duck_type.rb +79 -0
  41. data/tests/gets.rb +48 -0
  42. data/tests/join_nodes.rb +63 -0
  43. data/tests/nil.rb +72 -0
  44. data/tests/not_patterns.rb +91 -0
  45. data/tests/or_patterns.rb +154 -0
  46. data/tests/regex.rb +47 -0
  47. data/tests/self_reference.rb +54 -0
  48. metadata +81 -49
@@ -0,0 +1,72 @@
1
+ # This file is part of the Ruleby project (http://ruleby.org)
2
+ #
3
+ # This application is free software; you can redistribute it and/or
4
+ # modify it under the terms of the Ruby license defined in the
5
+ # LICENSE.txt file.
6
+ #
7
+ # Copyright (c) 2010 Joe Kutner and Matt Smith. All rights reserved.
8
+ #
9
+ # * Authors: Joe Kutner, Matt Smith
10
+ #
11
+
12
+ require 'test/unit'
13
+ require 'ruleby'
14
+
15
+ include Ruleby
16
+
17
+ module Nil
18
+
19
+ class Number
20
+ def initialize(value)
21
+ @value = value
22
+ end
23
+ attr:value, true
24
+ end
25
+
26
+ class NilRulebook < Rulebook
27
+ def rules
28
+ rule [Number, :m, m.value == 42], [Context, :c] do |v|
29
+ v[:c].inc :rule1
30
+ end
31
+
32
+ rule [Number, :m, m.value < 42], [Context, :c] do |v|
33
+ v[:c].inc :rule2
34
+ end
35
+
36
+ rule [Number, :m, m.value > 42], [Context, :c] do |v|
37
+ v[:c].inc :rule3
38
+ end
39
+
40
+ rule [Number, :m, m.value <= 42], [Context, :c] do |v|
41
+ v[:c].inc :rule4
42
+ end
43
+
44
+ rule [Number, :m, m.value >= 42], [Context, :c] do |v|
45
+ v[:c].inc :rule5
46
+ end
47
+ end
48
+ end
49
+
50
+ class Test < Test::Unit::TestCase
51
+
52
+ def test_0
53
+
54
+ engine :engine do |e|
55
+ NilRulebook.new(e).rules
56
+
57
+ ctx = Context.new
58
+ e.assert ctx
59
+ e.assert Number.new(43)
60
+ e.assert Number.new(42)
61
+ e.assert Number.new(41)
62
+ e.match
63
+
64
+ assert_equal 1, ctx.get(:rule1)
65
+ assert_equal 1, ctx.get(:rule3)
66
+ assert_equal 1, ctx.get(:rule2)
67
+ assert_equal 2, ctx.get(:rule4)
68
+ assert_equal 2, ctx.get(:rule5)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,91 @@
1
+ # This file is part of the Ruleby project (http://ruleby.org)
2
+ #
3
+ # This application is free software; you can redistribute it and/or
4
+ # modify it under the terms of the Ruby license defined in the
5
+ # LICENSE.txt file.
6
+ #
7
+ # Copyright (c) 2008 Joe Kutner and Matt Smith. All rights reserved.
8
+ #
9
+ # * Authors: Joe Kutner
10
+ #
11
+
12
+ require 'test/unit'
13
+
14
+ require 'ruleby'
15
+
16
+ include Ruleby
17
+
18
+ module NotPatterns
19
+
20
+ class A
21
+ attr :name, true
22
+ end
23
+
24
+ class B
25
+ attr :name, true
26
+ end
27
+
28
+ class C
29
+ attr :name, true
30
+ end
31
+
32
+ class NotPatternsRulebook < Rulebook
33
+ def rules
34
+ rule [:not, A], [Context, :c] do |v|
35
+ v[:c].inc :rule1
36
+ end
37
+
38
+ rule [Context, :c], [:not, A, m.name == :X] do |v|
39
+ v[:c].inc :rule2
40
+ end
41
+
42
+ rule [:not, A, m.name == :Y], [Context, :c] do |v|
43
+ v[:c].inc :rule3
44
+ end
45
+
46
+ rule [A, {m.name => :x}],
47
+ [:not, B, m.name == b(:x)],
48
+ [Context, :c] do |v|
49
+ v[:c].inc :rule4
50
+ end
51
+
52
+ rule [A, :a, {m.name => :x}],
53
+ [:not, C, :c, m.name == b(:x)],
54
+ [Context, :c] do |v|
55
+ v[:c].inc :rule5
56
+ end
57
+
58
+ rule [:not, Message], [Context, :c] do |v|
59
+ v[:c].inc :rule6
60
+ end
61
+ end
62
+ end
63
+
64
+ class Test < Test::Unit::TestCase
65
+ def test_0
66
+ engine :engine do |e|
67
+ NotPatternsRulebook.new(e).rules
68
+ ctx = Context.new
69
+ e.assert ctx
70
+
71
+ a = A.new
72
+ a.name = :X
73
+ e.assert a
74
+ b = B.new
75
+ b.name = :Y
76
+ e.assert b
77
+ c = C.new
78
+ c.name = :X
79
+ e.assert c
80
+
81
+ e.match
82
+ assert_equal 0, ctx.get(:rule1)
83
+ assert_equal 1, ctx.get(:rule3)
84
+ assert_equal 0, ctx.get(:rule2)
85
+ assert_equal 1, ctx.get(:rule4)
86
+ assert_equal 0, ctx.get(:rule5)
87
+ assert_equal 1, ctx.get(:rule6)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,154 @@
1
+ # This file is part of the Ruleby project (http://ruleby.org)
2
+ #
3
+ # This application is free software; you can redistribute it and/or
4
+ # modify it under the terms of the Ruby license defined in the
5
+ # LICENSE.txt file.
6
+ #
7
+ # Copyright (c) 2009 Joe Kutner and Matt Smith. All rights reserved.
8
+ #
9
+ # * Authors: Joe Kutner
10
+ #
11
+
12
+ require 'test/unit'
13
+
14
+ require 'ruleby'
15
+
16
+ include Ruleby
17
+
18
+ module OrPatterns
19
+
20
+ class OrPatternsRulebook < Rulebook
21
+ def rules
22
+ rule OR([Message, m.message == :FIRST], [Message, m.message == :SECOND]), [Context, :c] do |v|
23
+ v[:c].inc :rule1
24
+ end
25
+
26
+ rule OR([Message, m.message == :FIRST], [Message, m.message == :FOOBAR]), [Context, :c] do |v|
27
+ v[:c].inc :rule2
28
+ end
29
+
30
+ rule OR([Message, m.message == :FIRST], [Message, m.message == :FIRST]), [Context, :c] do |v|
31
+ v[:c].inc :rule3
32
+ end
33
+
34
+ rule OR([Message, m.message == :FOO], [Message, m.message == :BAR]), [Context, :c] do |v|
35
+ # this is not expected to pass
36
+ v[:c].inc :rule4
37
+ end
38
+
39
+ rule OR([Message, m.message == :FOOBAR], [Message, m.message == :SECOND]), [Context, :c] do |v|
40
+ v[:c].inc :rule5
41
+ end
42
+
43
+ rule AND([Message, m.message == :FIRST], [Message, m.message == :SECOND]), [Context, :c] do |v|
44
+ # no reason for this to work - its verbose, just checking.
45
+ v[:c].inc :rule6
46
+ end
47
+
48
+ rule AND([Message, m.message == :FOOBAR], [Message, m.message == :SECOND]), [Context, :c] do |v|
49
+ # no reason for this to work - its verbose, just checking.
50
+ v[:c].inc :rule7
51
+ end
52
+
53
+ rule OR(AND([Message, m.message == :FIRST], [Message, m.message == :SECOND])), [Context, :c] do |v|
54
+ v[:c].inc :rule8
55
+ end
56
+
57
+ rule OR([Message, m.message == :FIRST]), [Context, :c] do |v|
58
+ v[:c].inc :rule9
59
+ end
60
+
61
+ rule OR(AND([Message, m.message == :FIRST], [Message, m.message == :SECOND]), [Message, m.message == :FOOBAR]), [Context, :c] do |v|
62
+ v[:c].inc :rule10
63
+ end
64
+
65
+ rule AND([Message, m.message == :FIRST], [Context, :c]) do |v|
66
+ # no reason for this to work - its verbose. But it does work, so just checking.
67
+ v[:c].inc :rule11
68
+ end
69
+
70
+ rule AND([Message, m.message == :FOOBAR], [Context, :c]) do |v|
71
+ # no reason for this to work - its verbose. But it does work, so just checking.
72
+ v[:c].inc :rule12
73
+ end
74
+
75
+ rule OR([Message, :f, m.message == :FOOBAR], [Message, :g, m.message == :SECOND]), [Context, :c] do |v|
76
+ if v[:f]
77
+ # :f should be null
78
+ v[:c].inc :rule13a
79
+ end
80
+
81
+
82
+ if v[:g]
83
+ # :g should never be null
84
+ v[:c].inc :rule13b
85
+ end
86
+ end
87
+
88
+ rule OR([Message, :f, m.message == :FIRST], [Message, :s, m.message == :SECOND]), [Context, :c] do |v|
89
+ if v[:f]
90
+ v[:c].inc :rule14a
91
+ end
92
+
93
+ if v[:s]
94
+ v[:c].inc :rule14b
95
+ end
96
+ end
97
+
98
+ rule OR(AND([Message, m.message == :FIRST], [Message, m.message == :SECOND]), [Message, m.message == :FOOBAR], [Message, m.message == :THIRD]), [Context, :c] do |v|
99
+ v[:c].inc :rule16
100
+ end
101
+
102
+ rule OR(AND(OR([Message, m.message == :FIRST], [Message, m.message == :SECOND]), [Message, m.message == :THIRD])), [Context, :c] do |v|
103
+ v[:c].inc :rule17
104
+ end
105
+
106
+ rule OR(AND(OR(OR([Message, m.message == :FIRST])))), [Context, :c] do |v|
107
+ v[:c].inc :rule18
108
+ end
109
+
110
+ rule OR(AND(OR(OR([Message, m.message == :FOOBAR])))), [Context, :c] do |v|
111
+ v[:c].inc :rule19
112
+ end
113
+
114
+ rule OR([Message, m.message == :FIRST], [Message, m.message == :SECOND], [Message, m.message == :THIRD]), [Context, :c] do |v|
115
+ v[:c].inc :rule20
116
+ end
117
+ end
118
+ end
119
+
120
+ class Test < Test::Unit::TestCase
121
+ def test_0
122
+ engine :engine do |e|
123
+ OrPatternsRulebook.new(e).rules
124
+ ctx = Context.new
125
+ e.assert ctx
126
+ e.assert Message.new(:FIRST, :FIRST)
127
+ e.assert Message.new(:FIRST, :SECOND)
128
+ e.assert Message.new(:FIRST, :THIRD)
129
+ e.match
130
+ assert_equal 3, ctx.get(:rule20)
131
+ assert_equal 0, ctx.get(:rule19)
132
+ assert_equal 1, ctx.get(:rule18)
133
+ assert_equal 2, ctx.get(:rule17)
134
+ assert_equal 2, ctx.get(:rule16)
135
+ assert_equal 1, ctx.get(:rule14b)
136
+ assert_equal 1, ctx.get(:rule14a)
137
+ assert_equal 1, ctx.get(:rule13b)
138
+ assert_equal 0, ctx.get(:rule13a)
139
+ assert_equal 0, ctx.get(:rule12)
140
+ assert_equal 1, ctx.get(:rule11)
141
+ assert_equal 1, ctx.get(:rule10)
142
+ assert_equal 1, ctx.get(:rule9)
143
+ assert_equal 1, ctx.get(:rule8)
144
+ assert_equal 0, ctx.get(:rule7)
145
+ assert_equal 1, ctx.get(:rule6)
146
+ assert_equal 1, ctx.get(:rule5)
147
+ assert_equal 0, ctx.get(:rule4)
148
+ assert_equal 2, ctx.get(:rule3)
149
+ assert_equal 1, ctx.get(:rule2)
150
+ assert_equal 2, ctx.get(:rule1)
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,47 @@
1
+ # This file is part of the Ruleby project (http://ruleby.org)
2
+ #
3
+ # This application is free software; you can redistribute it and/or
4
+ # modify it under the terms of the Ruby license defined in the
5
+ # LICENSE.txt file.
6
+ #
7
+ # Copyright (c) 2007 Joe Kutner and Matt Smith. All rights reserved.
8
+ #
9
+ # * Authors: Joe Kutner, Matt Smith
10
+ #
11
+
12
+ require 'test/unit'
13
+ require 'ruleby'
14
+
15
+ include Ruleby
16
+
17
+ MY_RE = /slot_(\d+)/
18
+
19
+ module RE
20
+
21
+ class RERulebook < Rulebook
22
+ def rules
23
+
24
+ rule [Message, :m, m.message =~ MY_RE], [Context, :c] do |v|
25
+ v[:c].inc :my_re
26
+ end
27
+
28
+ end
29
+ end
30
+
31
+ class Test < Test::Unit::TestCase
32
+
33
+ def test_0
34
+ ctx = Context.new
35
+
36
+ engine :engine do |e|
37
+ RERulebook.new(e).rules
38
+ e.assert ctx
39
+ e.assert Message.new(:HELLO, 'slot_1')
40
+ e.assert Message.new(:HELLO, 'slot_x')
41
+ e.match
42
+ end
43
+
44
+ assert_equal 1, ctx.get(:my_re)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ # This file is part of the Ruleby project (http://ruleby.org)
2
+ #
3
+ # This application is free software; you can redistribute it and/or
4
+ # modify it under the terms of the Ruby license defined in the
5
+ # LICENSE.txt file.
6
+ #
7
+ # Copyright (c) 2008 Joe Kutner and Matt Smith. All rights reserved.
8
+ #
9
+ # * Authors: Joe Kutner, Matt Smith, John Mettraux
10
+ #
11
+
12
+ require 'test/unit'
13
+
14
+ require 'ruleby'
15
+
16
+ include Ruleby
17
+
18
+ module SelfReference
19
+
20
+ class SelfRefRulebook < Rulebook
21
+ def rules
22
+ rule [Message, :m, {m.message => :x}, m.status == b(:x)],
23
+ [Context, :c] do |v|
24
+ v[:c].inc :rule2
25
+ end
26
+
27
+ # This is effectively the same as the rule above
28
+ rule [Message, :m, m.status == m.message],
29
+ [Context, :c] do |v|
30
+ v[:c].inc :rule3
31
+ end
32
+
33
+ end
34
+ end
35
+
36
+
37
+ class Test < Test::Unit::TestCase
38
+
39
+ def test_0
40
+
41
+ engine :engine do |e|
42
+ SelfRefRulebook.new(e).rules
43
+ ctx = Context.new
44
+ e.assert ctx
45
+ e.assert Message.new(:HELLO, :HELLO)
46
+ e.assert Message.new(:HELLO, :GOODBYE)
47
+ e.match
48
+
49
+ assert_equal 1, ctx.get(:rule2)
50
+ assert_equal 1, ctx.get(:rule3)
51
+ end
52
+ end
53
+ end
54
+ end
metadata CHANGED
@@ -1,71 +1,103 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruleby
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.b7
4
5
  prerelease: 4
5
- version: 0.9.b4
6
6
  platform: ruby
7
- authors:
8
- - Joe Kutner
9
- - Matt Smith
7
+ authors:
8
+ - Joe Kutner
9
+ - Matt Smith
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
-
14
- date: 2011-06-27 00:00:00 -05:00
15
- default_executable:
13
+ date: 2011-11-16 00:00:00.000000000Z
16
14
  dependencies: []
17
-
18
- description: |
19
- Ruleby is a rule engine written in the Ruby language. It is a system for executing a set
20
- of IF-THEN statements known as production rules. These rules are matched to objects using
21
- the forward chaining Rete algorithm. Ruleby provides an internal Domain Specific Language
22
- (DSL) for building the productions that make up a Ruleby program.
23
-
15
+ description: ! "Ruleby is a rule engine written in the Ruby language. It is a system
16
+ for executing a set \nof IF-THEN statements known as production rules. These rules
17
+ are matched to objects using \nthe forward chaining Rete algorithm. Ruleby provides
18
+ an internal Domain Specific Language \n(DSL) for building the productions that make
19
+ up a Ruleby program.\n"
24
20
  email: jpkutner@gmail.com
25
21
  executables: []
26
-
27
22
  extensions: []
28
-
29
23
  extra_rdoc_files: []
30
-
31
- files:
32
- - lib/rule_helper.rb
33
- - lib/rulebook.rb
34
- - lib/ruleby.rb
35
- - lib/core/atoms.rb
36
- - lib/core/engine.rb
37
- - lib/core/nodes.rb
38
- - lib/core/patterns.rb
39
- - lib/core/utils.rb
40
- - lib/dsl/ferrari.rb
41
- - tests/test.rb
42
- has_rdoc: true
24
+ files:
25
+ - .gitignore
26
+ - GPL.txt
27
+ - LICENSE.txt
28
+ - README.markdown
29
+ - benchmarks/basic_rules.rb
30
+ - benchmarks/joined_rules.rb
31
+ - benchmarks/miss_manners/data.rb
32
+ - benchmarks/miss_manners/miss_manners.rb
33
+ - benchmarks/miss_manners/model.rb
34
+ - benchmarks/miss_manners/rules.rb
35
+ - benchmarks/model.rb
36
+ - examples/diagnosis.rb
37
+ - examples/fibonacci_example1.rb
38
+ - examples/fibonacci_example2.rb
39
+ - examples/fibonacci_example3.rb
40
+ - examples/fibonacci_rulebook.rb
41
+ - examples/hello.rb
42
+ - examples/ticket.rb
43
+ - examples/wordgame.rb
44
+ - lib/core/atoms.rb
45
+ - lib/core/engine.rb
46
+ - lib/core/nodes.rb
47
+ - lib/core/patterns.rb
48
+ - lib/core/utils.rb
49
+ - lib/dsl/ferrari.rb
50
+ - lib/rule_helper.rb
51
+ - lib/rulebook.rb
52
+ - lib/ruleby.rb
53
+ - ruleby.gemspec
54
+ - spec/and_or_spec.rb
55
+ - spec/coercion_spec.rb
56
+ - spec/collect_spec.rb
57
+ - spec/errors_spec.rb
58
+ - spec/ferrari_spec.rb
59
+ - spec/function_spec.rb
60
+ - spec/hello_spec.rb
61
+ - spec/node_sharing_spec.rb
62
+ - spec/property_spec.rb
63
+ - spec/spec.opts
64
+ - spec/spec_helper.rb
65
+ - tasks/documentation.rake
66
+ - tasks/rspec.rake
67
+ - tasks/test.rake
68
+ - tests/assert_facts.rb
69
+ - tests/common.rb
70
+ - tests/duck_type.rb
71
+ - tests/gets.rb
72
+ - tests/join_nodes.rb
73
+ - tests/nil.rb
74
+ - tests/not_patterns.rb
75
+ - tests/or_patterns.rb
76
+ - tests/regex.rb
77
+ - tests/self_reference.rb
78
+ - tests/test.rb
43
79
  homepage: http://ruleby.org
44
80
  licenses: []
45
-
46
81
  post_install_message:
47
82
  rdoc_options: []
48
-
49
- require_paths:
50
- - lib
51
- required_ruby_version: !ruby/object:Gem::Requirement
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
52
86
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: 1.8.2
57
- required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
92
  none: false
59
- requirements:
60
- - - ">"
61
- - !ruby/object:Gem::Version
62
- version: 1.3.1
93
+ requirements:
94
+ - - ! '>'
95
+ - !ruby/object:Gem::Version
96
+ version: 1.3.1
63
97
  requirements: []
64
-
65
98
  rubyforge_project: ruleby
66
- rubygems_version: 1.5.1
99
+ rubygems_version: 1.8.10
67
100
  signing_key:
68
101
  specification_version: 3
69
102
  summary: Rete based Ruby Rule Engine
70
- test_files:
71
- - tests/test.rb
103
+ test_files: []