ruleby 0.3 → 0.4

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.
@@ -1,193 +0,0 @@
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
- module MissManners
13
-
14
- class Chosen
15
- def initialize(id,guestName,hobby)
16
- @id = id
17
- @guestName = guestName
18
- @hobby = hobby
19
- end
20
- attr_reader :id, :guestName, :hobby
21
- def to_s
22
- "{Chosen id=#{@id}, name=#{@guestName}, hobbies=#{@hobby}}"
23
- end
24
- end
25
-
26
- class Context
27
- START_UP = 0
28
- ASSIGN_SEATS = 1
29
- MAKE_PATH = 2
30
- CHECK_DONE = 3
31
- PRINT_RESULTS = 4
32
- STATE_STRINGS = ["START_UP","ASSIGN_SEATS","MAKE_PATH","CHECK_DONE","PRINT_RESULTS"]
33
- def initialize(state)
34
- if state == :start
35
- @state = START_UP
36
- else
37
- raise "Context #{state.to_s} does not exist for Context Enum"
38
- end
39
- end
40
- attr :state, true
41
- def string_value
42
- return STATE_STRINGS[@state]
43
- end
44
- def is_state(state)
45
- return @state == state
46
- end
47
- def to_s
48
- return "[Context state=" + string_value.to_s + "]";
49
- end
50
- end
51
-
52
- class Count
53
- def initialize(value)
54
- @value = value
55
- end
56
- attr :value, true
57
- def ==(object)
58
- if object.object_id == self.object_id
59
- return true
60
- elsif object == nil || !(object.kind_of?(Count))
61
- return false
62
- end
63
- return @value == object.value;
64
- end
65
- def to_s
66
- return "[Count value=#{@value.to_s}]"
67
- end
68
- def to_hash
69
- return value.to_hash
70
- end
71
- end
72
-
73
- class Guest
74
- def initialize(name,sex,hobby)
75
- @name = name
76
- @sex = sex
77
- @hobby = hobby
78
- end
79
- attr_reader :name,:sex,:hobby
80
- def to_s
81
- return "[Guest name=" + @name.to_s + ", sex=" + @sex.to_s + ", hobbies=" + @hobby.to_s + "]";
82
- end
83
- end
84
-
85
- class Hobby
86
- @stringH1 = "h1"
87
- @stringH2 = "h2"
88
- @stringH3 = "h3"
89
- @stringH4 = "h4"
90
- @stringH5 = "h5"
91
- HOBBY_STRINGS = [@stringH1,@stringH2,@stringH3,@stringH4,@stringH5]
92
- def initialize(hobby)
93
- @hobbyIndex = hobby-1
94
- @hobby = HOBBY_STRINGS[@hobbyIndex]
95
- end
96
- H1 = Hobby.new(1)
97
- H2 = Hobby.new(2)
98
- H3 = Hobby.new(3)
99
- H4 = Hobby.new(4)
100
- H5 = Hobby.new(5)
101
- attr_reader :hobby
102
- def resolve(hobby)
103
- if @stringH1 == hobby
104
- return H1
105
- elsif @stringH2 == hobby
106
- return H2
107
- elsif @stringH3 == hobby
108
- return H3
109
- elsif @stringH4 == hobby
110
- return H4
111
- elsif @stringH5 == hobby
112
- return H5
113
- else
114
- raise "Hobby '" + @hobby.to_s + "' does not exist for Hobby Enum"
115
- end
116
- end
117
- def to_hash
118
- return @hobbyIndex.to_hash
119
- end
120
- def to_s
121
- return @hobby
122
- end
123
- end
124
-
125
- class LastSeat
126
- def initialize(seat)
127
- @seat = seat
128
- end
129
- attr_reader :seat
130
- def to_s
131
- return "[LastSeat seat=#{@seat.to_s}]"
132
- end
133
- end
134
-
135
- class Path
136
- def initialize(id,seat,guestName)
137
- @id = id
138
- @guestName = guestName
139
- @seat = seat
140
- end
141
- attr_reader :id, :guestName, :seat
142
- def to_s
143
- "[Path id=#{@id.to_s}, name=#{@guestName.to_s}, seat=#{@seat.to_s}]"
144
- end
145
- end
146
-
147
- class Seating
148
- def initialize(id,pid,path,leftSeat,leftGuestName,rightSeat,rightGuestName)
149
- @id = id
150
- @pid = pid
151
- @path = path
152
- @leftSeat = leftSeat
153
- @leftGuestName = leftGuestName
154
- @rightSeat = rightSeat
155
- @rightGuestName = rightGuestName
156
- end
157
- attr :path, true
158
- attr_reader :id,:pid,:leftSeat,:leftGuestName,:rightSeat,:rightGuestName
159
- def to_s
160
- return "[Seating id=#{@id.to_s} , pid=#{pid.to_s} , pathDone=#{@path.to_s} , leftSeat=#{@leftSeat.to_s}, leftGuestName=#{@leftGuestName.to_s}, rightSeat=#{@rightSeat.to_s}, rightGuestName=#{@rightGuestName.to_s}]";
161
- end
162
- end
163
-
164
- class Sex
165
- STRING_M = 'm'
166
- STRING_F = 'f'
167
- SEX_LIST = [ STRING_M, STRING_F ]
168
- def initialize(sex)
169
- @sex = sex
170
- end
171
- M = Sex.new( 0 )
172
- F = Sex.new( 1 )
173
- def sex
174
- return SEX_LIST[sex]
175
- end
176
- def resolve(sex)
177
- if STRING_M == sex
178
- return M
179
- elsif STRING_F == sex
180
- return F
181
- else
182
- raise "Sex '#{@sex.to_s}' does not exist for Sex Enum"
183
- end
184
- end
185
- def to_s
186
- return @sex.to_s
187
- end
188
- def to_hash
189
- return @sex.to_hash
190
- end
191
- end
192
-
193
- end
@@ -1,104 +0,0 @@
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 'model'
13
-
14
- module MissManners
15
-
16
- class MannersRulebook < Ruleby::Rulebook
17
- def rules
18
- rule :assignFirstSeat,
19
- [Context,:context, m.state == Context::START_UP],
20
- [Guest,:guest],
21
- [Count,:count] do |e,vars|
22
- guestName = vars[:guest].name
23
- seating = Seating.new(vars[:count].value,1,true,1,guestName,1,guestName)
24
- e.assert seating
25
- path = Path.new(vars[:count].value, 1, guestName)
26
- e.assert path
27
- e.retract vars[:count]
28
- vars[:count].value = vars[:count].value + 1
29
- e.assert vars[:count]
30
- puts "assign first seat : #{seating.to_s} : #{path.to_s}"
31
- vars[:context].state = Context::ASSIGN_SEATS
32
- e.modify vars[:context]
33
- end
34
-
35
- rule :findSeating,
36
- [Context,:context, {m.state == Context::ASSIGN_SEATS => :state}],
37
- [Count,:count, {m.value => :countValue}],
38
- [Seating,:seating, {m.path == true =>:p, m.id=>:seatingId, m.pid=>:seatingPid, m.rightSeat=>:seatingRightSeat, m.rightGuestName=>:seatingRightGuestName}],
39
- [Guest,:g, {m.name=>:name, m.sex=>:rightGuestSex, m.hobby=>:rightGuestHobby}, m.name == b(:seatingRightGuestName)],
40
- [Guest,:lg, {m.name=>:leftGuestName, m.sex=>:sex, m.hobby == b(:rightGuestHobby) => :hobby}, m.sex(:rightGuestSex, &c{|s,rgs| s != rgs} )],
41
- [:~,Path, m.id == b(:seatingId), m.guestName == b(:leftGuestName)],
42
- [:~,Chosen, m.id == b(:seatingId), m.guestName == b(:leftGuestName), m.hobby == b(:leftGuestHobby)] do |e,vars|
43
- rightSeat = vars[:seatingRightSeat]
44
- seatId = vars[:seatingId]
45
- countValue = vars[:count].value
46
- seating = Seating.new(countValue,seatId,false,rightSeat,vars[:seatingRightGuestName],rightSeat+1,vars[:leftGuestName])
47
- path = Path.new(countValue,rightSeat+1,vars[:leftGuestName])
48
- chosen = Chosen.new(seatId, vars[:leftGuestName], vars[:rightGuestHobby] )
49
- puts "find seating : #{seating} : #{path} : #{chosen}"
50
- e.assert seating
51
- e.assert path
52
- e.assert chosen
53
- vars[:count].value = countValue + 1
54
- e.modify vars[:count]
55
- vars[:context].state = Context::MAKE_PATH
56
- e.modify vars[:context]
57
- end
58
-
59
- rule :makePath,
60
- [Context,:context, {m.state == Context::MAKE_PATH => :s}],
61
- [Seating,:seating, {m.id=>:seatingId, m.pid=>:seatingPid, m.path == false =>:p}],
62
- [Path,:path, {m.guestName=>:pathGuestName, m.seat=>:pathSeat}, m.id == b(:seatingPid)],
63
- [:~,Path,m.id == b(:seatingId), m.guestName == b(:pathGuestName)] do |e,vars|
64
- path = Path.new(vars[:seatingId],vars[:pathSeat],vars[:pathGuestName])
65
- e.assert path
66
- puts "make Path : #{path}"
67
- end
68
-
69
- # NOTE We had to add this because Ruleby's conflict resolution strategy
70
- # is not robust enough. If it worked correctly, this priority would not
71
- # be nessecary because the 'make path' activations would have more
72
- # recent facts supporting it.
73
- rule :pathDone, {:priority => -5},
74
- [Context,:context, m.state == Context::MAKE_PATH],
75
- [Seating,:seating, m.path == false] do |e,vars|
76
- vars[:seating].path = true
77
- e.modify vars[:seating]
78
- vars[:context].state = Context::CHECK_DONE
79
- e.modify vars[:context]
80
- puts "path Done : #{vars[:seating]}"
81
- end
82
-
83
- rule :areWeDone,
84
- [Context,:context, m.state == Context::CHECK_DONE],
85
- [LastSeat,:ls, {m.seat => :lastSeat}],
86
- [Seating,:seating, m.rightSeat == b(:lastSeat)] do |e,vars|
87
- vars[:context].state = Context::PRINT_RESULTS
88
- e.modify vars[:context]
89
- end
90
-
91
- rule :continue, {:priority => -5},
92
- [Context,:context,m.state == Context::CHECK_DONE] do |e,vars|
93
- vars[:context].state = Context::ASSIGN_SEATS
94
- e.modify vars[:context]
95
- end
96
-
97
- rule :allDone,
98
- [Context,:context,m.state == Context::PRINT_RESULTS] do |e,vars|
99
- puts 'All done'
100
- end
101
- end
102
- end
103
-
104
- end
@@ -1,36 +0,0 @@
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
- class Account
13
- def initialize(status, title, account_id)
14
- @status = status
15
- @title = title
16
- @account_id = account_id
17
- end
18
-
19
- attr :status, true
20
- attr :title, true
21
- attr :account_id, true
22
- end
23
-
24
- class Address
25
- def initialize(addr_id, city, state, zip)
26
- @addr_id = addr_id
27
- @city = city
28
- @state = state
29
- @zip = zip
30
- end
31
-
32
- attr :addr_id, true
33
- attr :city, true
34
- attr :state, true
35
- attr :zip, true
36
- end
@@ -1,117 +0,0 @@
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
- $LOAD_PATH << File.join(File.dirname(__FILE__), '../lib/')
13
- require 'ruleby'
14
-
15
- class Patient
16
- def initialize(name,fever,spots,rash,sore_throat,innoculated)
17
- @name = name
18
- @fever = fever
19
- @spots= spots
20
- @rash = rash
21
- @sore_throat = sore_throat
22
- @innoculated = innoculated
23
- end
24
- attr:name, true
25
- attr:fever, true
26
- attr:spots, true
27
- attr:rash, true
28
- attr:sore_throat, true
29
- attr:innoculated, true
30
- end
31
-
32
- class Diagnosis
33
- def initialize(name,diagnosis)
34
- @name=name
35
- @diagnosis=diagnosis
36
- end
37
- attr:name,true
38
- attr:diagnosis,true
39
- end
40
-
41
- class Treatment
42
- def initialize(name,treatment)
43
- @name=name
44
- @treatment=treatment
45
- end
46
- attr:name,true
47
- attr:treatment,true
48
- end
49
-
50
- class DiagnosisRulebook < Ruleby::Rulebook
51
- def rules
52
- rule :Measles, {:priority => 100},
53
- [Patient,:p,{m.name=>:n},m.fever==:high,m.spots==true,m.innoculated==true] do |e,v|
54
- name = v[:n]
55
- e.assert Diagnosis.new(name, :measles)
56
- puts "Measles diagnosed for #{name}"
57
- end
58
-
59
- rule :Allergy1,
60
- [Patient,:p, {m.name=>:n}, m.spots==true],
61
- [:not, Diagnosis, m.name==b(:n), m.diagnosis==:measles] do |e,v|
62
- name = v[:n]
63
- e.assert Diagnosis.new(name, :allergy)
64
- puts "Allergy diagnosed for #{name} from spots and lack of measles"
65
- end
66
-
67
- rule :Allergy2,
68
- [Patient,:p, {m.name=>:n}, m.rash==true] do |e,v|
69
- name = v[:n]
70
- e.assert Diagnosis.new(name, :allergy)
71
- puts "Allergy diagnosed from rash for #{name}"
72
- end
73
-
74
- rule :Flu,
75
- [Patient,:p, {m.name=>:n}, m.sore_throat==true, m.fever(&c{|f| f==:mild || f==:high})] do |e,v|
76
- name = v[:n]
77
- e.assert Diagnosis.new(name, :flu)
78
- puts "Flu diagnosed for #{name}"
79
- end
80
-
81
- rule :Penicillin,
82
- [Diagnosis, :d, {m.name => :n}, m.diagnosis==:measles] do |e,v|
83
- name = v[:n]
84
- e.assert Treatment.new(name, :penicillin)
85
- puts "Penicillin prescribed for #{name}"
86
- end
87
-
88
- rule :Allergy_pills,
89
- [Diagnosis, :d, {m.name => :n}, m.diagnosis==:allergy] do |e,v|
90
- name = v[:n]
91
- e.assert Treatment.new(name, :allergy_shot)
92
- puts "Allergy shot prescribed for #{name}"
93
- end
94
-
95
- rule :Bed_rest,
96
- [Diagnosis, :d, {m.name => :n}, m.diagnosis==:flu] do |e,v|
97
- name = v[:n]
98
- e.assert Treatment.new(name, :bed_rest)
99
- puts "Bed rest prescribed for #{name}"
100
- end
101
- end
102
- end
103
-
104
- include Ruleby
105
-
106
- engine :engine do |e|
107
-
108
- DiagnosisRulebook.new(e).rules
109
-
110
- e.assert Patient.new('Fred',:none,true,false,false,false)
111
- e.assert Patient.new('Joe',:high,false,false,true,false)
112
- e.assert Patient.new('Bob',:high,true,false,false,true)
113
- e.assert Patient.new('Tom',:none,false,true,false,false)
114
-
115
- e.match
116
-
117
- end