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,69 @@
1
+ require 'spec_helper'
2
+
3
+ class PropFact
4
+ attr :value, true
5
+ def initialize(v=nil); @value = v; end
6
+ end
7
+
8
+ class PropCtx
9
+
10
+ end
11
+
12
+
13
+ include Ruleby
14
+
15
+ class PropRulebook < Rulebook
16
+ def gt_rules
17
+ rule [PropFact, :p, m.value > 0] do
18
+ assert Success.new
19
+ end
20
+ end
21
+
22
+ def lte_rules
23
+ rule [PropFact, :p, m.value > 42], [PropCtx, :pc] do
24
+ # do nothing, just being here helps reproduce a bug
25
+ end
26
+ rule [PropFact, :p, m.value <= 42], [PropCtx, :pc] do
27
+ assert Success.new
28
+ end
29
+ end
30
+ end
31
+
32
+ describe Ruleby::Core::Engine do
33
+ describe "property gt_rules" do
34
+ subject do
35
+ engine :engine do |e|
36
+ PropRulebook.new(e).gt_rules
37
+ end
38
+ end
39
+
40
+ before do
41
+ subject.assert PropFact.new(1)
42
+ subject.match
43
+ end
44
+
45
+ it "should have matched" do
46
+ subject.errors.should == []
47
+ subject.retrieve(Success).size.should == 1
48
+ end
49
+ end
50
+ describe "property lte_rules" do
51
+ subject do
52
+ engine :engine do |e|
53
+ PropRulebook.new(e).lte_rules
54
+ end
55
+ end
56
+
57
+ before do
58
+ subject.assert PropCtx.new
59
+ subject.assert PropFact.new(42)
60
+ subject.assert PropFact.new(41)
61
+ subject.match
62
+ end
63
+
64
+ it "should have matched" do
65
+ subject.errors.should == []
66
+ subject.retrieve(Success).size.should == 2
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format profile
4
+ --backtrace
@@ -0,0 +1,9 @@
1
+ require 'ruleby'
2
+ #require 'rspec'
3
+
4
+ class Success
5
+ attr :status, true
6
+ def initialize(status=nil)
7
+ @status = status
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ #
2
+ # DOCUMENTATION
3
+
4
+ #ALLISON=`allison --path`
5
+ #ALLISON="/Library/Ruby/Gems/1.8/gems/allison-2.0.3/lib/allison.rb"
6
+
7
+ Rake::RDocTask.new do |rd|
8
+
9
+ #rd.main = "README.txt"
10
+ #rd.rdoc_dir = "html/rufus-verbs"
11
+
12
+ rd.rdoc_files.include(
13
+ "LICENSE.txt",
14
+ "lib/**/*.rb")
15
+
16
+ rd.title = "ruleby rdoc"
17
+
18
+ rd.options << '-N' # line numbers
19
+ rd.options << '-S' # inline source
20
+
21
+ #rd.template = ALLISON if File.exist?(ALLISON)
22
+ end
23
+
24
+
25
+ #
26
+ # WEBSITE
27
+
28
+ #task :upload_website => [ :clean, :rdoc ] do
29
+ # account = "whoever@rubyforge.org"
30
+ # webdir = "/var/www/gforge-projects/ruleby"
31
+ # sh "rsync -azv -e ssh html/source #{account}:#{webdir}/"
32
+ #end
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
@@ -0,0 +1,9 @@
1
+
2
+ #
3
+ # TESTING
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << "tests"
7
+ t.test_files = FileList['tests/test.rb']
8
+ t.verbose = true
9
+ end
@@ -0,0 +1,130 @@
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 AssertFacts
19
+
20
+ class Fibonacci
21
+ def initialize(sequence,value=-1)
22
+ @sequence = sequence
23
+ @value = value
24
+ end
25
+
26
+ attr_reader :sequence
27
+ attr :value, true
28
+
29
+ def to_s
30
+ return super + "::sequence=" + @sequence.to_s + ",value=" + @value.to_s
31
+ end
32
+ end
33
+
34
+ class SimpleRulebook < Rulebook
35
+ def rules
36
+ rule [Message, :m, {m.message => :x}, m.status == b(:x)],
37
+ [Context, :c] do |v|
38
+ v[:c].inc :rule1
39
+ end
40
+ end
41
+ end
42
+
43
+ class FibonacciRulebook < Rulebook
44
+ def rules
45
+ # Bootstrap1
46
+ rule :Bootstrap1, {:priority => 4},
47
+ [Fibonacci, :f, m.value == -1, m.sequence == 1 ] do |vars|
48
+ vars[:f].value = 1
49
+ modify vars[:f]
50
+ end
51
+
52
+ # Recurse
53
+ rule :Recurse, {:priority => 3},
54
+ [Fibonacci, :f, m.value == -1] do |vars|
55
+ f2 = Fibonacci.new(vars[:f].sequence - 1)
56
+ assert f2
57
+ end
58
+
59
+ # Bootstrap2
60
+ rule :Bootstrap2,
61
+ [Fibonacci, :f, m.value == -1 , m.sequence == 2] do |vars|
62
+ vars[:f].value = 1
63
+ modify vars[:f]
64
+ end
65
+
66
+ # Calculate
67
+ rule :Calculate,
68
+ [Context, :c],
69
+ [Fibonacci,:f1, m.value.not== -1, {m.sequence => :s1}],
70
+ [Fibonacci,:f2, m.value.not== -1, {m.sequence( :s1, &c{ |s2,s1| s2 == s1 + 1 } ) => :s2}],
71
+ [Fibonacci,:f3, m.value == -1, m.sequence(:s2, &c{ |s3,s2| s3 == s2 + 1 }) ] do |vars|
72
+ vars[:f3].value = vars[:f1].value + vars[:f2].value
73
+ modify vars[:f3]
74
+ retract vars[:f1]
75
+ vars[:c].set vars[:f3].sequence, vars[:f3].value
76
+ end
77
+ end
78
+ end
79
+
80
+ class Test < Test::Unit::TestCase
81
+
82
+ def test_0
83
+ engine :engine do |e|
84
+ ctx = Context.new
85
+ e.assert ctx
86
+ e.assert Message.new(:HELLO, :HELLO)
87
+ SimpleRulebook.new(e).rules
88
+ e.assert Message.new(:HELLO, :GOODBYE)
89
+ e.match
90
+ assert_equal 1, ctx.get(:rule1)
91
+ end
92
+ end
93
+
94
+ def test_1
95
+ engine :engine do |e|
96
+ ctx = Context.new
97
+ e.assert ctx
98
+ e.assert Message.new(:HELLO, :HELLO)
99
+ e.assert Message.new(:HELLO, :GOODBYE)
100
+ SimpleRulebook.new(e).rules
101
+ e.match
102
+ assert_equal 1, ctx.get(:rule1)
103
+ end
104
+ end
105
+
106
+ def test_2
107
+ fib1 = Fibonacci.new(150)
108
+ engine :engine do |e|
109
+ FibonacciRulebook.new(e).rules
110
+ ctx = Context.new
111
+ e.assert ctx
112
+ e.assert fib1
113
+ e.match
114
+ assert_equal 9969216677189303386214405760200, ctx.get(150)
115
+ end
116
+ end
117
+
118
+ def test_3
119
+ fib1 = Fibonacci.new(150)
120
+ engine :engine do |e|
121
+ ctx = Context.new
122
+ e.assert ctx
123
+ e.assert fib1
124
+ FibonacciRulebook.new(e).rules
125
+ e.match
126
+ assert_equal 9969216677189303386214405760200, ctx.get(150)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,29 @@
1
+
2
+ class Context
3
+
4
+ def initialize
5
+ @counts = {}
6
+ @counts.default = 0
7
+ end
8
+
9
+ def inc(key)
10
+ @counts[key] += 1
11
+ end
12
+
13
+ def set(key,value)
14
+ @counts[key] = value
15
+ end
16
+
17
+ def get(key)
18
+ @counts[key]
19
+ end
20
+ end
21
+
22
+ class Message
23
+ def initialize(status,message)
24
+ @status = status
25
+ @message = message
26
+ end
27
+ attr :status, true
28
+ attr :message, true
29
+ end
@@ -0,0 +1,79 @@
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
+ require 'test/unit'
12
+ require 'ruleby'
13
+
14
+ include Ruleby
15
+
16
+ module Duck
17
+ class Foobar
18
+ end
19
+
20
+ class Email < Message
21
+ end
22
+
23
+ class Loan
24
+ def initialize(name,age)
25
+ @name = name
26
+ @age = age
27
+ @status = :HELLO
28
+ end
29
+ attr :name, true
30
+ attr :age, true
31
+ attr :status, true
32
+ end
33
+
34
+
35
+ class DuckRulebook < Rulebook
36
+
37
+ def rules
38
+
39
+ rule [m.status == :HELLO], [Context, :c] do |v|
40
+ v[:c].inc :rule1
41
+ end
42
+
43
+ rule [:is_a?, Message, m.status == :HELLO], [Context, :c] do |v|
44
+ v[:c].inc :rule2
45
+ end
46
+
47
+ rule [Message, m.status == :HELLO], [Context, :c] do |v|
48
+ v[:c].inc :rule3
49
+ end
50
+ end
51
+ end
52
+
53
+ class DuckTypeTest < Test::Unit::TestCase
54
+
55
+ def test_0
56
+
57
+ engine :engine do |e|
58
+ DuckRulebook.new(e).rules
59
+ ctx = Context.new
60
+ a = Loan.new('A','B')
61
+ b = Message.new(:HELLO, 'test')
62
+ c = Email.new(:HELLO, 'test')
63
+ d = Message.new(:FOOBAR, 'foobar')
64
+ f = Foobar.new
65
+
66
+ e.assert ctx
67
+ e.assert a; e.match; e.retract a
68
+ e.assert b; e.match; e.retract b
69
+ e.assert c; e.match; e.retract c
70
+ e.assert d; e.match; e.retract d
71
+ e.assert f; e.match; e.retract f
72
+
73
+ assert_equal 3, ctx.get(:rule1)
74
+ assert_equal 2, ctx.get(:rule2)
75
+ assert_equal 1, ctx.get(:rule3)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,48 @@
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
+ TEST_STR = String.new("it worked")
18
+
19
+ module Get
20
+
21
+ class GetRulebook < Rulebook
22
+ def rules
23
+
24
+ rule [Message, :m, m.status == :HELLO] do |v|
25
+ @engine.assert TEST_STR
26
+ end
27
+
28
+ end
29
+ end
30
+
31
+ class Test < Test::Unit::TestCase
32
+
33
+ def test_0
34
+
35
+ engine :engine do |e|
36
+ GetRulebook.new(e).rules
37
+ e.assert Message.new(:HELLO, 'test')
38
+ e.match
39
+
40
+ strs = e.retrieve(String)
41
+
42
+ assert_equal 1, strs.size
43
+
44
+ assert_equal TEST_STR, strs[0]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,63 @@
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 JoinNodes
19
+
20
+ class A
21
+
22
+ end
23
+
24
+ class B
25
+
26
+ end
27
+
28
+ class JoinNodesRulebook < Rulebook
29
+ def rules
30
+ rule [A], [B], [Context, :c] do |v|
31
+ v[:c].inc :rule1
32
+ end
33
+ end
34
+ end
35
+
36
+ class Test < Test::Unit::TestCase
37
+ def test_0
38
+ engine :engine do |e|
39
+ JoinNodesRulebook.new(e).rules
40
+ ctx = Context.new
41
+ a = A.new
42
+ b = B.new
43
+ e.assert ctx
44
+ e.assert a
45
+ e.assert b
46
+ e.match
47
+ assert_equal 1, ctx.get(:rule1)
48
+ e.retract a
49
+ e.match
50
+ assert_equal 1, ctx.get(:rule1)
51
+ e.assert B.new
52
+ e.match
53
+ assert_equal 1, ctx.get(:rule1)
54
+ e.assert A.new
55
+ e.match
56
+ assert_equal 3, ctx.get(:rule1)
57
+ e.retract b
58
+ e.match
59
+ assert_equal 4, ctx.get(:rule1)
60
+ end
61
+ end
62
+ end
63
+ end