```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/.

```