/* A Family of Truths and Lies in Picat. From Avinash Kumar Singh, Ph.D.: "A Family of Truths and Lies — Can You Crack This Logic Puzzle?" https://medium.com/puzzle-sphere/a-family-of-truths-and-lies-can-you-crack-this-logic-puzzle-8c2b98e4f828 """ Imagine a strange village with two kinds of families. Family X — they always tell the truth. Family Y — they always lie. You meet three people: A, B, and C. Each of them belongs to either Family X or Family Y. A tells you: "Either I or B belongs to a different family from the other two." Now here’s the twist: You, the clever one, are sure about the family of one of the three — either A, B, or C. Can you figure out which one? And how? """ Here are the four possible outcomes (from go/0): [0,0,0] [0,0,1] [1,0,0] [1,0,1] This shows that we know that B must be of family Y, i.e. always lies. Using logic programming (go2/0), we get the same solution, i.e. that B is of family Y: XYX XYY YYX YYY 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 ?=> L = [A,B,C], L :: 0..1, % 0: Always lies (Y family), 1: Always tells the truth (X family) % A tells you % "Either I or B belongs to a different family from the other two." A #<=> ( ( A #!= B #/\ A #!= C) #\/ ( B #!= A #/\ B #!= C) ), solve(L), println(L), fail, nl. go => true. % Logic programming go2 ?=> L = [A,B,C], F = "XY", % Families are x (always tells the truth or y (always lies) member(A,F), member(B,F), member(C,F), % A tells you % "Either I or B belongs to a different family from the other two." ( A == 'X' -> (( A != B, A != C) ;( B != A, B != C) ) ; not (( A != B, A != C) ; ( B != A, B != C) ) ), println(L), fail, nl. go2 => true.