Hardly efficient (in fact I haven't yet run it through to completion),
but since we were recently talking about amb:
---
$colors = ["red", "white", "yellow", "blue", "green"]
$nationalities = ["Brit", "Swede", "Dane", "Norwegian", "German"]
$beverages = ["tea", "coffee", "milk", "beer", "water"]
$cigars = ["Pall Mall", "Blends", "Dunhill", "Prince", "Bluemasters"]
$pets = ["dogs", "birds", "cats", "horse", "fish"]

class House
  attr_reader :color, :nationality, :beverage, :cigar, :pet

  def initialize
    @color = $amb.one_of($colors)
    @nationality = $amb.one_of($nationalities)
    @beverage = $amb.one_of($beverages)
    @cigar = $amb.one_of($cigars)
    @pet = $amb.one_of($pets)
  end
end

def find(property, value)
  $houses.detect{|h| h.send(property) == value} || $amb.fail
end

def color(s) find(:color, s) end
def nationality(s) find(:nationality, s) end
def beverage(s) find(:beverage, s) end
def cigar(s) find(:cigar, s) end
def pet(s) find(:pet, s) end

def next_door(h1, h2)
  ($houses.index(h1) - $houses.index(h2)).abs == 1
end

$amb = Amb.new
$houses = (1..5).collect{House.new}

#fact 1
$amb.assert(nationality("Brit").color == "red")
#fact 2
$amb.assert(nationality("Swede").pet == "dogs")
#fact 3
$amb.assert(nationality("Dane").beverage == "tea")
#fact 4
$amb.assert(houses.index(color("white")) -
houses.index(color("green")) == 1)
#fact 5
$amb.assert(color("green").beverage == "coffee")
#fact 6
$amb.assert(cigar("Pall Mall").pet == "birds")
#fact 7
$amb.assert(color("yellow").cigar == "Dunhill")
#fact 8
$amb.assert(houses[2].beverage == "milk")
#fact 9
$amb.assert(houses[0].nationality == "Norwegian")
#fact 10
$amb.assert(next_door(cigar("Blends"), pet("cats")))
#fact 11
$amb.assert(next_door(cigar("Dunhill"), pet("horse")))
#fact 12
$amb.assert(cigar("Bluemasters").beverage == "beer")
#fact 13
$amb.assert(nationality("German").cigar == "Prince")
#fact 14
$amb.assert(next_door(nationality("Norwegian"), color("blue")))
#fact 15
$amb.assert(next_door(cigar("Blends"), beverage("water")))

#No owners have the same pet, smoke the same brand of cigar
#or drink the same beverage.
$amb.assert(houses.collect{|h| h.color}.uniq.size == 5)
$amb.assert(houses.collect{|h| h.nationality}.uniq.size == 5)
$amb.assert(houses.collect{|h| h.beverage}.uniq.size == 5)
$amb.assert(houses.collect{|h| h.cigar}.uniq.size == 5)
$amb.assert(houses.collect{|h| h.pet}.uniq.size == 5)

puts "The " + pet("fish").nationality + " owns the fish"