ruleby 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/benchmarks/basic_rules.rb +66 -0
- data/benchmarks/joined_rules.rb +73 -0
- data/benchmarks/miss_manners/data.rb +11 -0
- data/benchmarks/miss_manners/miss_manners.rb +11 -1
- data/benchmarks/miss_manners/model.rb +11 -0
- data/benchmarks/miss_manners/rules.rb +49 -110
- data/benchmarks/model.rb +36 -0
- data/examples/example_diagnosis.rb +35 -73
- data/examples/example_hello.rb +20 -22
- data/examples/example_politician.rb +22 -11
- data/examples/example_ticket.rb +40 -85
- data/examples/fibonacci_example1.rb +13 -2
- data/examples/fibonacci_example2.rb +11 -0
- data/examples/fibonacci_rulebook.rb +58 -111
- data/examples/test_self_reference.rb +51 -9
- data/lib/core/atoms.rb +53 -116
- data/lib/core/engine.rb +96 -96
- data/lib/core/nodes.rb +330 -298
- data/lib/core/patterns.rb +36 -39
- data/lib/core/utils.rb +141 -3
- data/lib/dsl/ferrari.rb +263 -0
- data/lib/dsl/letigre.rb +212 -0
- data/lib/dsl/steel.rb +313 -0
- data/lib/rulebook.rb +82 -265
- data/lib/ruleby.rb +13 -0
- metadata +21 -19
- data/benchmarks/50_joined_rules.rb +0 -78
- data/benchmarks/50_rules.rb +0 -57
- data/benchmarks/5_joined_rules.rb +0 -78
- data/benchmarks/5_rules.rb +0 -57
@@ -0,0 +1,66 @@
|
|
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
|
+
require 'model'
|
15
|
+
|
16
|
+
include Ruleby
|
17
|
+
|
18
|
+
class TestRulebook < Rulebook
|
19
|
+
def rules(n)
|
20
|
+
(0..n).each do |index|
|
21
|
+
rule "Rule-#{index}".to_sym do |r|
|
22
|
+
r.when do |has|
|
23
|
+
has.a Account
|
24
|
+
has.a.status = 'standard'
|
25
|
+
has.a.title = 'mr'
|
26
|
+
has.a.account_id = "acc#{index}"
|
27
|
+
end
|
28
|
+
|
29
|
+
r.then do |e,vars|
|
30
|
+
# puts "rule #{index} fired"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def run_benchmark(rules, facts)
|
38
|
+
puts "running benchmark for: #{rules} rules and #{facts} facts"
|
39
|
+
|
40
|
+
t1 = Time.new
|
41
|
+
engine :engine do |e|
|
42
|
+
TestRulebook.new(e).rules(rules)
|
43
|
+
|
44
|
+
t2 = Time.new
|
45
|
+
diff = t2.to_f - t1.to_f
|
46
|
+
puts 'time to create rule set: ' + diff.to_s
|
47
|
+
for k in (0..facts)
|
48
|
+
e.assert Account.new('standard', 'mr', ('acc'+k.to_s))
|
49
|
+
end
|
50
|
+
|
51
|
+
t3 = Time.new
|
52
|
+
diff = t3.to_f - t2.to_f
|
53
|
+
puts 'time to assert facts: ' + diff.to_s
|
54
|
+
e.match
|
55
|
+
|
56
|
+
t4 = Time.new
|
57
|
+
diff = t4.to_f - t3.to_f
|
58
|
+
puts 'time to run agenda: ' + diff.to_s
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
run_benchmark(5, 500)
|
63
|
+
puts '-------'
|
64
|
+
run_benchmark(50, 500)
|
65
|
+
puts '-------'
|
66
|
+
run_benchmark(500, 500)
|
@@ -0,0 +1,73 @@
|
|
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
|
+
require 'model'
|
15
|
+
|
16
|
+
include Ruleby
|
17
|
+
|
18
|
+
class TestRulebook < Rulebook
|
19
|
+
def rules(n)
|
20
|
+
(0..n).each do |index|
|
21
|
+
rule "Rule-#{index}".to_sym do |r|
|
22
|
+
r.when do |has|
|
23
|
+
has.a Account
|
24
|
+
has.a.status = 'standard'
|
25
|
+
has.a.account_id :id
|
26
|
+
|
27
|
+
has.addr Address
|
28
|
+
has.addr.addr_id = :id, :%
|
29
|
+
has.addr.city = 'Foobar'
|
30
|
+
has.addr.state = 'FB'
|
31
|
+
has.addr.zip = '12345'
|
32
|
+
end
|
33
|
+
|
34
|
+
r.then do |e,vars|
|
35
|
+
# puts "rule #{index} fired"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_benchmark(rules,facts)
|
43
|
+
puts "running benchmark for: #{rules} rules and #{facts} facts"
|
44
|
+
|
45
|
+
t1 = Time.new
|
46
|
+
engine :engine do |e|
|
47
|
+
TestRulebook.new(e).rules(rules)
|
48
|
+
|
49
|
+
t2 = Time.new
|
50
|
+
diff = t2.to_f - t1.to_f
|
51
|
+
puts 'time to create rule set: ' + diff.to_s
|
52
|
+
|
53
|
+
|
54
|
+
for k in (0..facts)
|
55
|
+
e.assert Account.new('standard', nil, "acc#{k}")
|
56
|
+
e.assert Address.new("acc#{k}",'Foobar', 'FB', '12345')
|
57
|
+
end
|
58
|
+
|
59
|
+
t3 = Time.new
|
60
|
+
diff = t3.to_f - t2.to_f
|
61
|
+
puts 'time to assert facts: ' + diff.to_s
|
62
|
+
|
63
|
+
e.match
|
64
|
+
|
65
|
+
t4 = Time.new
|
66
|
+
diff = t4.to_f - t3.to_f
|
67
|
+
puts 'time to run agenda: ' + diff.to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
run_benchmark(5, 50)
|
72
|
+
puts '-------'
|
73
|
+
run_benchmark(50, 50)
|
@@ -1,3 +1,14 @@
|
|
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
|
+
|
1
12
|
module MissManners
|
2
13
|
class MannersData
|
3
14
|
def initialize
|
@@ -1,6 +1,16 @@
|
|
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
|
+
|
1
12
|
$LOAD_PATH << File.join(File.dirname(__FILE__), '../../lib/')
|
2
13
|
require 'ruleby'
|
3
|
-
require 'rulebook'
|
4
14
|
require 'model'
|
5
15
|
require 'data'
|
6
16
|
require 'rules'
|
@@ -1,3 +1,14 @@
|
|
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
|
+
|
1
12
|
module MissManners
|
2
13
|
|
3
14
|
class Chosen
|
@@ -1,163 +1,102 @@
|
|
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
|
+
|
1
12
|
require 'model'
|
2
13
|
|
3
14
|
module MissManners
|
4
15
|
|
5
|
-
class MannersRulebook < Rulebook
|
16
|
+
class MannersRulebook < Ruleby::Rulebook
|
6
17
|
def rules
|
7
|
-
rule
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
r.then = action do |e,vars|
|
15
|
-
guestName = vars[:guest].name
|
16
|
-
|
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
|
17
23
|
seating = Seating.new(vars[:count].value,1,true,1,guestName,1,guestName)
|
18
|
-
e.assert seating
|
19
|
-
|
24
|
+
e.assert seating
|
20
25
|
path = Path.new(vars[:count].value, 1, guestName)
|
21
26
|
e.assert path
|
22
|
-
|
23
27
|
e.retract vars[:count]
|
24
28
|
vars[:count].value = vars[:count].value + 1
|
25
29
|
e.assert vars[:count]
|
26
|
-
|
27
30
|
puts "assign first seat : #{seating.to_s} : #{path.to_s}"
|
28
|
-
|
29
31
|
vars[:context].state = Context::ASSIGN_SEATS
|
30
32
|
e.modify vars[:context]
|
31
|
-
end
|
32
33
|
end
|
33
34
|
|
34
|
-
rule
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
has.g(Guest).&.name(:name).&.sex(:rightGuestSex).&.hobby(:rightGuestHobby)
|
44
|
-
has.g.name = :seatingRightGuestName, :%
|
45
|
-
|
46
|
-
has.lg(Guest).&.name(:leftGuestName).&.sex:sex
|
47
|
-
has.lg.hobby(:hobby).&.hobby = :rightGuestHobby, :%
|
48
|
-
has.lg.sex :rightGuestSex do |s,rgs| s != rgs end
|
49
|
-
|
50
|
-
has.not.path(Path).&.id = :seatingId, :%
|
51
|
-
has.path.guestName = :leftGuestName, :%
|
52
|
-
|
53
|
-
has.not.chosen Chosen
|
54
|
-
has.chosen.id = :seatingId, :%
|
55
|
-
has.chosen.guestName = :leftGuestName, :%
|
56
|
-
has.chosen.hobby = :leftGuestHobby, :%
|
57
|
-
end
|
58
|
-
|
59
|
-
r.then = action do |e,vars|
|
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|
|
60
43
|
rightSeat = vars[:seatingRightSeat]
|
61
44
|
seatId = vars[:seatingId]
|
62
|
-
countValue = vars[:count].value
|
63
|
-
|
45
|
+
countValue = vars[:count].value
|
64
46
|
seating = Seating.new(countValue,seatId,false,rightSeat,vars[:seatingRightGuestName],rightSeat+1,vars[:leftGuestName])
|
65
47
|
path = Path.new(countValue,rightSeat+1,vars[:leftGuestName])
|
66
|
-
chosen = Chosen.new(seatId, vars[:leftGuestName], vars[:rightGuestHobby] )
|
67
|
-
|
48
|
+
chosen = Chosen.new(seatId, vars[:leftGuestName], vars[:rightGuestHobby] )
|
68
49
|
puts "find seating : #{seating} : #{path} : #{chosen}"
|
69
|
-
|
70
50
|
e.assert seating
|
71
51
|
e.assert path
|
72
52
|
e.assert chosen
|
73
|
-
|
74
53
|
vars[:count].value = countValue + 1
|
75
54
|
e.modify vars[:count]
|
76
|
-
|
77
55
|
vars[:context].state = Context::MAKE_PATH
|
78
56
|
e.modify vars[:context]
|
79
|
-
end
|
80
|
-
|
81
57
|
end
|
82
58
|
|
83
|
-
rule
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
has.seating.path(:p).&.path = false
|
89
|
-
|
90
|
-
has.path(Path).&.guestName(:pathGuestName).&.seat(:pathSeat)
|
91
|
-
has.path.id = :seatingPid, :%
|
92
|
-
|
93
|
-
has.not.path2 Path
|
94
|
-
has.path2.id = :seatingId, :%
|
95
|
-
has.path2.guestName = :pathGuestName, :%
|
96
|
-
end
|
97
|
-
|
98
|
-
r.then = action do |e,vars|
|
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|
|
99
64
|
path = Path.new(vars[:seatingId],vars[:pathSeat],vars[:pathGuestName])
|
100
65
|
e.assert path
|
101
66
|
puts "make Path : #{path}"
|
102
|
-
end
|
103
67
|
end
|
104
68
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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|
|
112
76
|
vars[:seating].path = true
|
113
|
-
e.modify vars[:seating]
|
114
|
-
|
77
|
+
e.modify vars[:seating]
|
115
78
|
vars[:context].state = Context::CHECK_DONE
|
116
79
|
e.modify vars[:context]
|
117
80
|
puts "path Done : #{vars[:seating]}"
|
118
|
-
end
|
119
|
-
|
120
|
-
# HACK We had to add this because Ruleby's conflict resolution strategy
|
121
|
-
# is not robust enough. If it worked correctly, this priority would not
|
122
|
-
# be nessecary because the 'make path' activations would have more
|
123
|
-
# recent facts supporting it.
|
124
|
-
r.priority = -5
|
125
81
|
end
|
126
82
|
|
127
|
-
rule
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
has.seating(Seating).&.rightSeat = :lastSeat, :%
|
132
|
-
end
|
133
|
-
|
134
|
-
r.then = action do |e,vars|
|
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|
|
135
87
|
vars[:context].state = Context::PRINT_RESULTS
|
136
88
|
e.modify vars[:context]
|
137
|
-
end
|
138
89
|
end
|
139
90
|
|
140
|
-
rule
|
141
|
-
|
142
|
-
has.context Context
|
143
|
-
has.context.state = Context::CHECK_DONE
|
144
|
-
end
|
145
|
-
r.then = action do |e,vars|
|
91
|
+
rule :continue, {:priority => -5},
|
92
|
+
[Context,:context,m.state == Context::CHECK_DONE] do |e,vars|
|
146
93
|
vars[:context].state = Context::ASSIGN_SEATS
|
147
94
|
e.modify vars[:context]
|
148
|
-
end
|
149
|
-
r.priority = -5
|
150
95
|
end
|
151
96
|
|
152
|
-
rule
|
153
|
-
|
154
|
-
has.c Context
|
155
|
-
has.c.state = Context::PRINT_RESULTS
|
156
|
-
end
|
157
|
-
|
158
|
-
r.then = action do |e,vars|
|
97
|
+
rule :allDone,
|
98
|
+
[Context,:context,m.state == Context::PRINT_RESULTS] do |e,vars|
|
159
99
|
puts 'All done'
|
160
|
-
end
|
161
100
|
end
|
162
101
|
end
|
163
102
|
end
|
data/benchmarks/model.rb
ADDED
@@ -0,0 +1,36 @@
|
|
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,6 +1,16 @@
|
|
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
|
+
|
1
12
|
$LOAD_PATH << File.join(File.dirname(__FILE__), '../lib/')
|
2
13
|
require 'ruleby'
|
3
|
-
require 'rulebook'
|
4
14
|
|
5
15
|
class Patient
|
6
16
|
def initialize(name,fever,spots,rash,sore_throat,innoculated)
|
@@ -37,104 +47,56 @@ class Treatment
|
|
37
47
|
attr:treatment,true
|
38
48
|
end
|
39
49
|
|
40
|
-
class DiagnosisRulebook < Rulebook
|
50
|
+
class DiagnosisRulebook < Ruleby::Rulebook
|
41
51
|
def rules
|
42
|
-
rule
|
43
|
-
|
44
|
-
|
45
|
-
exists.p.fever=:high
|
46
|
-
exists.p.spots=true
|
47
|
-
exists.p.innoculated=true
|
48
|
-
end
|
49
|
-
r.then = action do |e,vars|
|
50
|
-
name = vars[:n]
|
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]
|
51
55
|
e.assert Diagnosis.new(name, :measles)
|
52
|
-
puts "Measles diagnosed for #{name}"
|
53
|
-
end
|
54
|
-
r.priority = 100
|
56
|
+
puts "Measles diagnosed for #{name}"
|
55
57
|
end
|
56
58
|
|
57
|
-
rule
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
exists.p.spots=true
|
62
|
-
|
63
|
-
exists.not.d Diagnosis
|
64
|
-
exists.d.name = :n, :%
|
65
|
-
exists.d.diagnosis = :measles
|
66
|
-
end
|
67
|
-
r.then = action do |e,vars|
|
68
|
-
name = vars[:n]
|
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]
|
69
63
|
e.assert Diagnosis.new(name, :allergy)
|
70
64
|
puts "Allergy diagnosed for #{name} from spots and lack of measles"
|
71
|
-
end
|
72
65
|
end
|
73
66
|
|
74
|
-
rule
|
75
|
-
|
76
|
-
|
77
|
-
exists.p.name :n2
|
78
|
-
exists.p.rash = true
|
79
|
-
end
|
80
|
-
r.then = action do |e,vars|
|
81
|
-
name = vars[:n2]
|
67
|
+
rule :Allergy2,
|
68
|
+
[Patient,:p, {m.name=>:n}, m.rash==true] do |e,v|
|
69
|
+
name = v[:n]
|
82
70
|
e.assert Diagnosis.new(name, :allergy)
|
83
71
|
puts "Allergy diagnosed from rash for #{name}"
|
84
|
-
end
|
85
72
|
end
|
86
73
|
|
87
|
-
rule
|
88
|
-
|
89
|
-
|
90
|
-
exists.p.name :n3
|
91
|
-
exists.p.sore_throat=true
|
92
|
-
exists.p.fever do |f| f == :mild || f == :high end
|
93
|
-
end
|
94
|
-
r.then = action do |e,vars|
|
95
|
-
name = vars[:n3]
|
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]
|
96
77
|
e.assert Diagnosis.new(name, :flu)
|
97
78
|
puts "Flu diagnosed for #{name}"
|
98
|
-
end
|
99
79
|
end
|
100
80
|
|
101
|
-
rule
|
102
|
-
|
103
|
-
|
104
|
-
exists.d.name :n4
|
105
|
-
exists.d.diagnosis = :measles
|
106
|
-
end
|
107
|
-
r.then = action do |e,vars|
|
108
|
-
name = vars[:n4]
|
81
|
+
rule :Penicillin,
|
82
|
+
[Diagnosis, :d, {m.name => :n}, m.diagnosis==:measles] do |e,v|
|
83
|
+
name = v[:n]
|
109
84
|
e.assert Treatment.new(name, :penicillin)
|
110
85
|
puts "Penicillin prescribed for #{name}"
|
111
|
-
end
|
112
86
|
end
|
113
87
|
|
114
|
-
rule
|
115
|
-
|
116
|
-
|
117
|
-
exists.d.name :n5
|
118
|
-
exists.d.diagnosis = :allergy
|
119
|
-
end
|
120
|
-
r.then = action do |e,vars|
|
121
|
-
name = vars[:n5]
|
88
|
+
rule :Allergy_pills,
|
89
|
+
[Diagnosis, :d, {m.name => :n}, m.diagnosis==:allergy] do |e,v|
|
90
|
+
name = v[:n]
|
122
91
|
e.assert Treatment.new(name, :allergy_shot)
|
123
92
|
puts "Allergy shot prescribed for #{name}"
|
124
|
-
end
|
125
93
|
end
|
126
94
|
|
127
|
-
rule
|
128
|
-
|
129
|
-
|
130
|
-
exists.d.name :n6
|
131
|
-
exists.d.diagnosis = :flu
|
132
|
-
end
|
133
|
-
r.then = action do |e,vars|
|
134
|
-
name = vars[:n6]
|
95
|
+
rule :Bed_rest,
|
96
|
+
[Diagnosis, :d, {m.name => :n}, m.diagnosis==:flu] do |e,v|
|
97
|
+
name = v[:n]
|
135
98
|
e.assert Treatment.new(name, :bed_rest)
|
136
99
|
puts "Bed rest prescribed for #{name}"
|
137
|
-
end
|
138
100
|
end
|
139
101
|
end
|
140
102
|
end
|