Here's some more puzzle solutions using Amb. This one is the one
described in the "Learn Scheme in Fixnum days" online book (where I
found the original Amb implementation). (see
http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_chap_14)
However, this is not an exact transcription of the book's logic, I was
able to simplify a number of the assertions.
Enjoy!
-- Jim Weirich
# The Kalotans are a tribe with a peculiar quirk. Their males always
# tell the truth. Their females never make two consecutive true
# statements, or two consecutive untrue statements.
#
# An anthropologist (let's call him Worf) has begun to study
# them. Worf does not yet know the Kalotan language. One day, he meets
# a Kalotan (heterosexual) couple and their child Kibi. Worf asks
# Kibi: ``Are you a boy?'' Kibi answers in Kalotan, which of course
# Worf doesn't understand.
#
# Worf turns to the parents (who know English) for explanation. One of
# them says: ``Kibi said: `I am a boy.' '' The other adds: ``Kibi is a
# girl. Kibi lied.''
#
# Solve for the sex of the parents and Kibi.
require 'amb'
# Some helper methods for logic
class Object
def implies(bool)
self ? bool : true
end
def xor(bool)
self ? !bool : bool
end
end
count = 0
A = Amb.new
# Begin the solution
begin
# Kibi's parents are either male or female, but must be distinct.
parent1 = A.choose(:male, :female)
parent2 = A.choose(:male, :female)
A.assert parent1 != parent2
# Kibi sex, and Kibi's self description are separate facts
kibi = A.choose(:male, :female)
kibi_said = A.choose(:male, :female)
# We will capture whether kibi lied in a local variable. This will
# make some later logic conditions a bit easier. (Note: the Scheme
# implementation sets the kibi_lied variable to a choice of true or
# false and then uses assertions to make all three variables
# consistent. This way however, is just so much easier.)
kibi_lied = kibi != kibi_said
# Now we look at what the parents said. If the first parent was
# male, then kibi must have described itself as male.
A.assert(
(parent1==:male).implies( (kibi_said == :male ) )
)
# If the first parent is female, then there are no futher deductions
# to make. Their statement could either be true or false.
# If the second parent is male, then both its statements must be
# true.
A.assert( (parent2 == :male).implies( kibi==:female ))
A.assert( (parent2 == :male).implies( kibi_lied ))
# If the second parent is female, then the condition is more
# complex. In this case, one or the other of the parent 2's
# statements are false, but not both are false. Let's introduce
# some variables for statements 1 and 2 just to make this a bit
# clearer.
s1 = kibi_lied
s2 = (kibi == :female)
A.assert(
(parent2 == :female).implies( (s1 && !s2).xor(!s1 && s2) )
)
# Now just print out the solution.
count += 1
puts "Solution #{count}"
puts "The first parent is #{parent1}."
puts "The second parent is #{parent2}."
puts "Kibi is #{kibi}."
puts "Kibi said #{kibi_said} and #{kibi_lied ? 'lied' : 'told the
truth'}."
puts
A.failure # Force a search for another solution.
rescue Amb::ExhaustedError
puts "No More Solutions"
end
--
Posted via http://www.ruby-forum.com/.