/*********************************************************** who_killed_agatha.pi from Constraint Solving and Planning with Picat, Springer by Neng-Fa Zhou, Hakan Kjellerstrand, and Jonathan Fruhman ***********************************************************/ import cp. main => L = find_all(Killer, who_killed_agatha(Killer)), println(killer=L). who_killed_agatha(Killer) => % Agatha, the butler, and Charles live in Dreadsbury Mansion, % and are the only ones to live there. N = 3, Agatha = 1, Butler = 2, Charles = 3, % The killer is one of the three. Killer :: [Agatha,Butler,Charles], % Define the Hates and Richer Boolean matrices Hates = new_array(N,N), Hates :: 0..1, Richer = new_array(N,N), Richer :: 0..1, % A killer always hates, and is no richer than his victim. foreach (I in 1..N) Killer #= I #=> Hates[I, Agatha] #= 1, Killer #= I #=> Richer[I, Agatha] #= 0 end, % Define the concept of "richer": % nobody is richer than him-/herself foreach (I in 1..N) Richer[I,I] #= 0 end, % if I is richer than J, then J is not richer than I foreach (I in 1..N, J in 1..N, I != J) Richer[I,J] #= 1 #<=> Richer[J,I] #= 0 end, % Charles hates nobody that Agatha hates. foreach (I in 1..N) Hates[Agatha, I] #= 1 #=> Hates[Charles, I] #= 0 end, % Agatha hates everybody except the butler. Hates[Agatha, Butler] #= 0, Hates[Agatha, Charles] #= 1, Hates[Agatha, Agatha] #= 1, % The butler hates everyone not richer than Aunt Agatha. foreach (I in 1 ..N) Richer[I, Agatha] #= 0 #=> Hates[Butler, I] #= 1 end, % The butler hates everyone whom Agatha hates. foreach (I in 1..N) Hates[Agatha, I] #= 1 #=> Hates[Butler, I] #= 1 end, % Nobody hates everyone. foreach (I in 1..N) sum([Hates[I,J] : J in 1..N]) #=< 2 end, % Who killed Agatha? Vars = [Killer] ++ Hates ++ Richer, solve(Vars).