Amb In Ruby

RubyLanguage has CallWithCurrentContinuation just like SchemeLanguage, but it misses macros so you have to use a standard class:

 class Amb
   def initialize
     @paths = []
   end

def choose *choices choices.each do |choice| callcc do |cc| @paths << cc return choice end end fail end

def fail @paths.pop.call rescue abort "Choice tree exhausted." end end

amb =Amb.new foo=amb.choose a,b,c.. amb.fail if..

...

I hacked on what you had above and came up with this. It memoizes and checks for nils.

 def choices(choicelist)
  @@cont ||= []
  choicelist.each { |choice|
   callcc { |cc|
    @@cont << cc
    @@conditionCount = 0
    return choice
   }
  }
  nil
 end

def condition(dependsOn) @@memo ||= {} @@conditionCount ||= 0 @@conditionCount += 1 @@memo[@@conditionCount] ||= {} return if @@memo[@@conditionCount][dependsOn] == true if dependsOn.include? nil or @@memo[@@conditionCount][dependsOn] == false or !(@@memo[@@conditionCount][dependsOn] = yield) @@cont.pop.call if @@cont.last end end

def again @@counter ||= 0 @@agains ||= 0 @@agains += 1 return if @@counter >= @@agains @@counter += 1 @@agains = 0 @@cont.last.call end

foo = choices(1..1000) bar = choices(1..1000)

condition([bar]) { bar > 10 } condition([bar]) { (bar % 2) == 0 } condition([foo]) { foo > 30 } condition([foo, bar]) { bar == (foo * 2) }

again again again

puts foo puts bar

-- spooq


Also see AmbSpecialForm, AmbInPython
CategoryRuby

EditText of this page (last edited May 21, 2008) or FindPage with title or text search