Misbehaving rule
Reported by max | December 23rd, 2008 @ 05:31 AM | in 0.5
I'm playing around with rules which pick the 'biggest' among the instances of a class. Currently I have the following:
require 'rubygems'
require 'ruleby'
include Ruleby
class Sortable
attr_reader :index
@@biggest = nil
def self.Biggest=(sortable)
puts ">> Biggest #{sortable}"
@@biggest = sortable
end
def self.Biggest()
puts ">> Current biggest is #{@@biggest}"
@@biggest
end
def initialize(index)
@index = index
end
def to_s
"Sortable #{index}"
end
end
class SortingRulebook < Rulebook
def rules
rule :SortInit,
[Class, :c, m.name == 'Sortable', m.Biggest(&c{|inst| inst == nil})],
[Sortable, :s] do |vars|
Sortable.Biggest = vars[:s]
puts "Initialize sortable to #{vars[:s]} (#{vars[:c]})"
modify vars[:c]
end
rule :Sort,
[Class, :c, m.name == 'Sortable', m.Biggest(&c{|inst| puts "Check NON-nil"; inst != nil})],
[Sortable, :s, m.index(&c {|index| res = (index > Sortable.Biggest.index); puts "Index #{index}:#{res}"; res })] do |vars|
raise "Why ignore index > Sortable.Biggest.index" if Sortable.Biggest == vars[:s]
Sortable.Biggest = vars[:s]
puts "#{vars[:s]} is bigger (#{vars[:c]})"
modify vars[:c]
end
end
end
i1 = Sortable.new(1)
i2 = Sortable.new(2)
i3 = Sortable.new(3)
i4 = Sortable.new(4)
Sortable.Biggest = i1
engine :engine do |e|
SortingRulebook.new(e).rules
e.assert Sortable
e.assert i4
e.assert i3
e.assert i2
e.assert i1
e.match
end
When I run it, I get:
$ ruby sort_order2.rb
>> Biggest Sortable 1
>> Current biggest is Sortable 1
>> Current biggest is Sortable 1
Check NON-nil
>> Current biggest is Sortable 1
>> Current biggest is Sortable 1
Index 4:true
>> Current biggest is Sortable 1
Index 3:true
>> Current biggest is Sortable 1
Index 2:true
>> Current biggest is Sortable 1
Index 1:false
>> Current biggest is Sortable 1
>> Biggest Sortable 2
Sortable 2 is bigger (Sortable)
>> Current biggest is Sortable 2
>> Current biggest is Sortable 2
Check NON-nil
>> Current biggest is Sortable 2
>> Current biggest is Sortable 2
sort_order2.rb:51:in `rules': Why ignore index > Sortable.Biggest.index (RuntimeError)
from /Library/Ruby/Gems/1.8/gems/ruleby-0.4/lib/core/engine.rb:34:in `call'
from /Library/Ruby/Gems/1.8/gems/ruleby-0.4/lib/core/engine.rb:34:in `fire'
from /Library/Ruby/Gems/1.8/gems/ruleby-0.4/lib/core/engine.rb:60:in `fire'
from /Library/Ruby/Gems/1.8/gems/ruleby-0.4/lib/core/engine.rb:226:in `match'
from sort_order2.rb:77
from /Library/Ruby/Gems/1.8/gems/ruleby-0.4/lib/ruleby.rb:19:in `engine'
from sort_order2.rb:68
Doesn't seem to be right.
Comments and changes to this ticket
-

jpkutner (at gmail) December 28th, 2008 @ 07:46 PM
- Milestone set to 0.5
- State changed from new to open
- Assigned user set to jpkutner (at gmail)
-

jpkutner (at gmail) December 28th, 2008 @ 08:23 PM
- State changed from open to invalid
This is not a bug. The rule is written incorrectly. There are two ways this rule could be written properly.
1)
rule :Sort, [Class, :c, m.name == 'Sortable', m.Biggest(&c{|inst| puts "Check NON-nil"; inst != nil})], [Sortable, :s, m.index(:c, &c {|index, c| res = (index > c.Biggest.index); puts "Index #{index}:#{res}"; res })] do |vars| raise "Why ignore index(#{vars[:s]}) > Sortable.Biggest.index" if Sortable.Biggest == vars[:s] puts "#{vars[:s]} is bigger (#{vars[:c].Biggest})" Sortable.Biggest = vars[:s] modify vars[:c] endIn this case, we create a reference to the Sortable class, because that is the fact that is being modified. The alternative is:
2)
rule :Sort, [Class, :c, m.name == 'Sortable', m.Biggest(&c{|inst| puts "Check NON-nil"; inst != nil})], [Sortable, :s, m.index(&c {|index, c| res = (index > Sortable.Biggest.index); puts "Index #{index}:#{res}"; res })] do |vars| raise "Why ignore index(#{vars[:s]}) > Sortable.Biggest.index" if Sortable.Biggest == vars[:s] puts "#{vars[:s]} is bigger (#{vars[:c].Biggest})" Sortable.Biggest = vars[:s] modify vars[:s] endHere we have changed the modify call in the RHS to modify the Sortable instance rather than the class. This will cause the second pattern to be reevaluated. That was the original problem -- th engine did not recognize that the Sortable instance fact was modified, and never reevaluated any patterns related to it.
Thanks for the submission.
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป
the Rule Engine for Ruby