I'm currently reading Raymond Smullyan's To Mock A Mockingbird, a book recommended by my thesis supervisor/NLP teacher. Anyway, in chapter 5, Smullyan discussed some knight-and-knave puzzles, which reminds me of the good old Discrete Math days. Here it is:

In the Island of Knights and Knaves, every inhabitant is either a knight or a knave. Knights make only true statements and knaves only false ones.

  1. Is it possible for any inhabitant of this island to claim that he is a knave?
  2. Is it possible for an inhabitant of the island to claim that he and his brother are both knaves?
  3. Suppose an inhabitant A says about himself and his brother B: "At least one of us is a knave." What type is A and what type is B?
  4. Suppose A instead says: "Exactly one of us is a knave." What can be deduced about A and what can be deduced about B?
  5. Suppose A instead says: "My brother and I are the same type; we are either both knights or both knaves." What could then be deduced about A and B?

Prolog solution

It's been a while since I last code in Prolog, but here's a quick-and-dirty solution that I came up with:

 truth(not(X),true) :- truth(X,false).  
 truth(and(X,Y),true) :- truth(X,true), truth(Y,true).  
 truth(or(X,Y),true) :- truth(X,true) ; truth(Y,true).  
 truth(imp(X,Y),true) :- truth(X,false) ; truth(Y,true).  
 truth(exor(X,Y),true) :- (truth(X,true),truth(Y,false)) ; (truth(X,false),truth(Y,true)).  
 truth(biimp(X,Y),true) :- truth(exor(X,Y),false).  
   
 truth(not(X),false) :- truth(X,true).  
 truth(and(X,Y),false) :- truth(X,false) ; truth(Y,false).  
 truth(or(X,Y),false) :- truth(X,false) , truth(Y,false).  
 truth(imp(X,Y),false) :- truth(X,true) , truth(Y,false).  
 truth(exor(X,Y),false) :- (truth(X,true),truth(Y,true)) ; (truth(X,false),truth(Y,false)).  
 truth(biimp(X,Y),false) :- truth(exor(X,Y),true).  
   
 truth(is_a(knight,knight),true).  
 truth(is_a(knave,knave),true).  
 truth(is_a(knight,knave),false).  
 truth(is_a(knave,knight),false).  
   
 truth(say(knight,Statement),true) :- truth(Statement,true).  
 truth(say(knave,Statement),true) :- truth(Statement,false).  
 truth(say(knight,Statement),false) :- truth(Statement,false).  
 truth(say(knave,Statement),false) :- truth(Statement,true).  

Answer 1: no
 ?- truth(say(A,is_a(knave,A)),TruthValue).  
 A = knight,  
 TruthValue = false ;  
 A = knave,  
 TruthValue = false ;  
If A is a knight, he wouldn't lie by saying he is a knave; if A is a knave, he wouldn't admit that he is.

Answer 2: yes
 ?- truth(say(A,and(is_a(knave,A),is_a(knave,B))),true).  
 A = knave,  
 B = knight .  

Answer 3: A is a knight and B is a knave
 ?- truth(say(A,or(is_a(knave,A),is_a(knave,B))),true).  
 A = knight,  
 B = knave .  

Answer 4: B is a knave, A cannot be determined.
 ?- truth(say(A,exor(is_a(knave,A),is_a(knave,B))),true).  
 A = knight,  
 B = knave ;  
 A = B, B = knave ;  

Answer 5: B is a knight, A cannot be determined.
 ?- truth(say(A,biimp(is_a(knave,A),is_a(knave,B))),true).  
 A = B, B = knight ;  
 A = knave,  
 B = knight ;  


The Search for Arthur York
Inspector Craig: What do you know about Arthur York?
Defendant: Arthur York once claimed that I was a knave.
Inspector Craig: Are you by any chance Arthur York?
Defendant: Yes.
Is the defendant Arthur York?

Let's assume that the defendant is Arthur York, that is truth(say(Defendant,is_a(Defendant,Arthur_York)),true).

 ?- truth(say(Defendant,is_a(Defendant,Arthur_York)),true), truth(say(Defendant,say(Arthur_York,is_a(knave,Defendant))),Truth).  
 Defendant = Arthur_York, Arthur_York = knight,  
 Truth = false ;  
   
 Defendant = knave,  
 Arthur_York = knight,  
 Truth = false ;  

Under this assumption, evaluation of the first claim leads to contradiction. Thus the defendant cannot be Arthur York.