% -*- Mode: Prolog -*- % Someone has stolen the jam! The March Hare said he didn't do it % (naturally!) The Mad Hatter proclaimed one of them (the Hare, the % Hatter or the Dormouse) stole the jam, but of course it wasn't the % Hatter himself. When asked whether the Mad Hatter and March Hare % spoke the truth, the Dormouse said that one of the three (including % herself) must have stolen the jam. % By employing the very expensive servieces of Dr. Himmelheber, the % famous psychiatrist, we eventually learned that not both the Dormous % and the March Hare spoke the truth. % % Assuming, as we do, that fairy-tale characters either always lie or % always tell the truth, it remains to discover who really stole the % jam. :- op(1100, xfy, or). :- op(1000, xfy, and). :- op(900, xfx, is_one_of). :- op(700, xfx, is_not). % Some convenince declarations X or Y :- X ; Y. X and Y :- X, Y. truth(X,truth(X)) :- X. lie(X,lie(X)) :- \+ X. X is_one_of L :- member(X,L). X is_not Y :- X \= Y. % Some nice formatting for the answers. portray(reason([Claim])) :- format("- The claim ~p.~n", [Claim]), !. %Red cut portray(reason([Claim|Rest])) :- format("- The claim ~p.~n~p", [Claim, reason(Rest)]). portray(truth(X)) :- format("'~p' is true", [X]). portray(lie(X)) :- format("'~p' is false", [X]). portray(X and Y) :- format("~p and ~p", [X,Y]). portray(X or Y) :- format("~p or ~p", [X,Y]). portray(X is_not Y) :- format("~p is not ~p", [X,Y]). portray(X is_one_of List) :- format("~p is either ~p", [X, '$PL'(List)]). portray('$PL'([X])) :- format("or ~p", [X]), !. %Red cut portray('$PL'([H|T])) :- format("~p, ~p", [H,'$PL'(T)]). % The actual code to solve the logic puzzle. % 'Thief' is the thief for the 'Reason'. find_the(Thief,Reason) :- HareClaim = (Thief is_not hare), HatterClaim = (Thief is_one_of [hatter,hare,dormouse] and Thief is_not hatter), DormouseClaim = (Thief is_one_of [hatter,hare,dormouse]), % Either claim can be the truth or a lie (truth(HareClaim,Why1) or lie(HareClaim,Why1)), (truth(HatterClaim,Why2) or lie(HatterClaim,Why2)), (truth(DormouseClaim,Why3) or lie(DormouseClaim,Why3)), % Dr. Himmelheber's observation (lie(HareClaim,_) or lie(DormouseClaim,_)), Reason = reason([Why1, Why2, Why3]). find_the_thief :- find_the(Thief,Reason), format("The thief is the ~p.~nProof:~n~p", [Thief,Reason]).