[net.lang.prolog] Knights and Knaves

fiore@hope.UUCP (David Fiore) (08/19/86)

This is my first attempt at writting a prolog problem and I have come to 
a point where I don't know why the program doesn't work and I have run out
of ideas on how to make it work. Could anyone out there in netland help me 
out with this?

	   ADVthanksANCE

	   -David Fiore


/* This program is supposed to solve a logic puzzle I read in R.
   Smullyn's book "What Is The Name Of This Book?".  The problem
   is as follows:

           On a certain island in the pacific is an island
      of knights and knaves.  Now knights by nature allways
      tell the truth, as far as they know it, while knaves
      by nature allways tell lies, as far as they know it. 
      A visitor to the Island of Knights and Knaves comes 
      across three inhabitants of the island standing together
      in a garden.  We will call them Larry, Curly, and Moe.
      The stranger says to Larry: "Are you a knight or a 
      knave?".  Larry answers but, rather indistinctly, so the
      stranger could not make out what Larry said.  So the
      stranger says to Curly: "What did Larry say?".  Curly
      says: "Larry said that he was a knave."  At this point,
      the third man Moe says: "Don't believe Curly, he's lying!"
      The question is what are Curly and Moe?

   It is immediately obvious that whatever Curly is, Moe is the 
   opposite.  What is not immediately obvious to everyone is that
   independant of Moe's statement, we can see that Curly is lying
   because it is impossible for any inhabitant to claim to be a
   knave.  We can therefore deduce that Curly is a knave and Moe is
   a knight.

*/
is_knight (X) :-
   is_knave (X),!,false.

is_knight (X) :-                              /* Someone is a knight if he */
   says (X, Y), Y.                            /* says something and that */
                                              /* thing is true. */

is_knave (X) :-
   is_knight (X), !, false.

is_knave (X) :-                               /* Someone is a knave is he */
   says (X, Y), not (Y).                      /* says something and that */
                                              /* thing is not true. */

legal (X, Y) :-
   Y, is_knight (X).
legal (X, Y) :-
   not (Y), is_knave (X).

says (larry, Z):-                              /* We don't know what he said */
   legal (larry, Z).

says (curly, says (larry, is_knave (larry))). /* Says larry claims knavehood */
says (moe, is_knave (curly)).                 /* Says curly is a knave */

-- 
      ||
      ||         David Fiore, University of California at Riverside.
 =============
      ||         Slow mail   :  1326 Wheaton Way
      ||                        Riverside, Ca.  92507
      ||         E-Mail      
      ||            UseNet   : ...!ucdavis!ucrmath!hope!fiore
      ||            BITNET   : consult@ucrvms 
		
		Have another day!

    "...and at warp eight, we're going nowhere mighty fast"