[net.lang.prolog] Liars & Truthtellers

Foonberg@AEROSPACE@sri-unix.UUCP (07/28/83)

From:  Foonberg at AEROSPACE (Alan Foonberg)

/*  Here is my solution.  I do not claim, by any means, that it is correct,
complete, or logically accurate.  But, it does produce the correct results,
using what was given.

-- Alan.

*/


says(b, says(a, l(a))). 	% The Given:  b says "a said that a is a
says(c, l(b)).			% liar," and c says "b is a liar."

notfalse(X) :-			% Something cannot be shown to be false if
	p(X);			% either it can be proven true or it was
	not(clause(p(X)),true),	% not explicitly given.
	!.

p(X) :-				% Something is obviously true if it was
	clause(X, true),	% explicitly given.
	!.

p(says(X,Y)) :-			% Something (Y) can be said by someone (X)
	(notfalse(t(X)),	% if the thing is true and the person is a
	 notfalse(Y));		% truthteller or if the thing is false and
	(notfalse(l(X)),	% the person is a liar.
	 notfalse(not(Y))),
	!.

p(X) :-				% In case of nested p's, and to divert p(t(X))
	X,			% and p(l(X))) to the clauses below.
	!.

t(X) :-				% Someone is a truthteller if he explicitly
	clause(says(X,Y),true), % says something which can be shown to be
	p(Y),			% true.
	!.

l(X) :-			
	clause(says(X,Y),true),	% Someone is a liar if he explicitly says
	not(p(Y)),		% something which cannot be shown to be
	!.			% true. (Not exactly correct, I know!)