Warren@SRI-AI@sri-unix.UUCP (07/28/83)
From: David Warren <Warren@SRI-AI> Here's a solution to the puzzle Russ Abbott posed. % Liars and Non-Liars Puzzle % On a certain island the inhabitants are partitioned into those who % always tell the truth and those who always lie. I landed on the % island and met three inhabitants A, B, and C. I asked A, "Are you a % truth-teller or a liar?" He mumbled something which I couldn't make % out. I asked B what A had said. B replied, "A said he was a liar." % C then volunteered, "Don't believe B, he's lying." What can you tell % about A, B, and C? :-op(900,xfx,if). :-op(800,xfy,and). :-op(700,xfx,[is_in,isnt_in]). :-op(100,fy,not). says(a,mumble). says(b,says(a,liar(a))). says(c,liar(b)). liar(X) if says(X,Y) and not Y. not liar(X) if says(X,Y) and Y. not says(X,Y) if not liar(X) and not Y. not says(X,Y) if liar(X) and Y. provable(P and Q,A) :- !, provable(P,A), provable(Q,A). provable(P,_) :- P. provable(P,A) :- P is_in A. provable(P,A) :- P isnt_in A, P if Q, negation(P,P1), provable(Q,[P1|A]). P is_in [P|_]. P is_in [_|A] :- P is_in A. P isnt_in []. P isnt_in [P1|A] :- P \== P1, P isnt_in A. negation(not P,P) :- !. negation(P, not P). :- provable(liar(X),[]), write(X), write(' is a liar.'), nl. :- provable(not liar(X),[]), write(X), write(' is not a liar.'), nl.
Suwa@Sumex-AIM@sri-unix.UUCP (09/19/83)
From: Motoi Suwa <Suwa@Sumex-AIM> Date: 14 Sep. 1983 From: K.Handa ETL Japan Subject: Another Puzzle Solution This is the solution of Alan's puzzle introduced on 24 Aug. ?-go(10). will display the ten disgit number as following: -->6210001000 and ?-go(4). will: -->1210 -->2020 I found following numbers: 6210001000 521001000 42101000 3211000 21200 1210 2020 The Following is the total program ( DEC10 Prolog Ver.3 ) /*** initial assertion ***/ init(D):- ass_xn(D),assert(rest(D)),!. ass_xn(0):- !. ass_xn(D):- D1 is D-1,asserta(x(D1,_)),asserta(n(D1)),ass_xn(D1). /*** main program ***/ go(D):- init(D),guess(D,0). go(_):- abolish(x,2),abolish(n,1),abolish(rest,1). /* guess 'N'th digit */ guess(D,D):- result,!,fail. guess(D,N):- x(N,X),var(X),!,n(Y),N=<Y,N*Y=<D,ass(N,Y),set(D,N,Y), N1 is N+1,guess(D,N1). guess(D,N):- x(N,X),set(D,N,X),N1 is N+1,guess(D,N1). /* let 'N'th digit be 'X' */ ass(N,X):- only(retract(x(N,_))),asserta(x(N,X)),only(update(1)). ass(N,_):- retract(x(N,_)),asserta(x(N,_)),update(-1),!,fail. only(X):- X,!. /* 'X' 'N's appear in the sequence of digit */ set(D,N,X):- count(N,Y),rest(Z),!,Y=<X,X=<Y+Z,X1 is X-Y,set1 (D,N,X1,0). set1(_,N,0,_):- !. set1(D,N,X,P):- n(M),P=<M,x(M,Y),var(Y),M*N=<D,ass(M,N),set(D,M,N), X1 is X-1,P1 is M,set1(D,N,X1,P1). /* 'X' is the number of digits which value is 'N' */ count(N,X):- bagof(M,M^(x(M,Z),nonvar(Z),Z=N),L),length(L,X). count(_,0). /* update the number of digits which value is not yet assigned */ update(Z):- only(retract(rest(X))),Z1 is X-Z,assert(rest(Z1)). update(Z):- retract(rest(X)),Z1 is X+Z,assert(rest(Z1)),!,fail. /* display the result */ result:- print(-->),n(N),x(N,M),print(M),fail. result:- nl.