Re: How to solve the following ``Liars'' puzzle in prolog?



Hi,

jakob wrote:


all(_, []).
all(Pred, [X|Xs]) :-
P =.. [Pred, X],
call(P),
all(Pred, Xs).

Consider using maplist/2, or flip arguments to allow for first-argument indexing.


distinct([]).
distinct([X|Xs]) :- not(member(X, Xs)), distinct(Xs).

Better use (standard) \+/1 instead of not/1.


Here is a version based on constraints and meta-interpretation:


:- use_module(library(bounds)).

:- op(710, xfy, xor).
:- op(720, xfy, and).

true(A is A).
true(A and B) :-
true(A),
true(B).
true(A xor B) :-
true(A),
false(B).
true(A xor B) :-
false(A),
true(B).

false(A is B) :-
A #\= B.


solution(Sol) :-
Girls = [Betty,Ethel,Joan,Kitty,Mary],
Girls in 1..5,
all_different(Girls),
true(Kitty is 2 xor Betty is 3 and
Ethel is 1 xor Joan is 2 and
Joan is 3 xor Ethel is 5 and
Kitty is 2 xor Mary is 4 and
Mary is 4 xor Betty is 1),
keysort([Betty-betty,Mary-mary,Joan-joan,
Kitty-kitty,Ethel-ethel], Sol).


?- solution(Ss).

Ss = [1-kitty, 2-joan, 3-betty, 4-mary, 5-ethel]


All the best,
Markus.
.