/* Knight, Knaves and Spies in Picat. From https://github.com/the-faisalahmed/Optimization/blob/main/logic%20puzzles/Knights%2C_Knaves_and_Spies.ipynb """ An island has three kinds of inhabitants: knights, who always tell the truth, knaves, who always lie, and spies, who can either tell the truth or lie. You encounter three people: A, B, and C, and you know for sure that one is a knight, one is a knave, and one is a spy. Each of the three knows the type of the other two. A says, “I am a spy”. B says, “I am a spy”. C says, “B is a spy”. What are the types of A, B, and C? """ A: Knave B: Spy C: Knight Cf https://en.wikibooks.org/wiki/Puzzles/Logic_puzzles/Knights,_Knaves_%26_Spies This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> Knave = 0, Knight = 1, Spy = 2, Type = [A,B,C], Type :: [Knave,Knight,Spy], % Speak truth Ts = [AT,BT,CT], % Truth Ts :: 0..1, % You know that one is a knight, one is a knave, and one is a spy. all_different(Type), % A says, “I am a spy”. AT #<=> A #= Spy, % B says, “I am a spy”. BT #<=> B #= Spy, % C says, “B is a spy”. CT #<=> B #= Spy, % Who is the knight, who is the knave, and who is the spy? foreach(I in 1..3) Ts[I] #= 1 #=> Type[I] :: [Knight,Spy], Ts[I] #= 0 #=> Type[I] :: [Knave,Spy] end, Vars = Ts ++ Type, solve(Vars), println(ts=Ts), println(type=Type), Map = new_map([0="Knave",1="Knight",2="Spy"]), printf("A: %w B: %w C: %w\n",Map.get(A), Map.get(B),Map.get(C)), fail, nl. go => true.