After a bit of thought I realize this problem was a poster child
application for languages like Prolog or Mercury.
But I know I'm not going to have to time to learn them.
But ruby is pretty flexible...
Anybody have any Prolog alike goal finding / backtracking type ruby
module available? (Couldn't spot any on RAA or rubyforge.)
John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john....@tait.co.nz
New Zealand
A Million Monkeys can inflict worse things than just Shakespeare on
your system.
I'm interessted in a framework for backtracking in ruby, too.
I think, using the Regexp Class an their methods will help, solving this
problem in a general way.
Fred from Wuppertal, Germany
> Anybody have any Prolog alike goal finding / backtracking type ruby
> module available? (Couldn't spot any on RAA or rubyforge.)
This isn't really prolog alike, but it's a nice simple backtracking
facility. To test it, try this:
amb = Amb.new
x = amb.one_of(1..10)
y = amb.one_of(1..10)
amb.assert(x + y == 7)
amb.assert(x - y == 1)
puts [x,y] #=> 4, 3
Or, say, this:
if amb.maybe
x = 1
y = 3
else
x = 7
y = 10
end
amb.assert(x > 1)
puts y #=> 10
amb.assert(y < 10) #=> error
To read more about it, search for "john mccarthy's amb" or see
http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-15.html
Cheers,
Avi
-----------------
#amb.rb
#Avi Bryant, Nov. 2003
class Amb
def initialize
@failureContinuation = proc{raise "Amb goal tree exhausted"}
end
def fail
@failureContinuation.call(nil)
end
def assert(bool)
fail unless bool
end
def choose(procArray)
kPrev = @failureContinuation
callcc do |kEntry|
procArray.each do |p|
callcc do |kNext|
@failureContinuation = proc do |v|
@failureContinuation = kPrev
kNext.call(v)
end
kEntry.call(p.call)
end
end
kPrev.call(nil)
end
end
def one_of(enumerable)
choose(enumerable.collect{|ea| proc{ea}})
end
def maybe
one_of([true, false])
end
end