Hi All
How to execute the following program?
% Mr S and Mr P problem
%
% There are two numbers M and N such that 1<M & N<100.
% Mr S is told their sum S and Mr P is told their product P. The
% following dialogue takes place:
%
% Statement-1:
% Mr P: I don't know the nmbers.
% (There are several sum values S that are compatibile with
% the product value P).
statement1(P) :- several(S, compatible(S,P)).
% Statement-2:
% Mr S: I knew you didn't know them.
% I don't know them either.
% (For every product value P that is compatible with the
% sum value S, statement-1 is true of P; and
% there are several products values P that are compatible
% with the sum value S).
statement2(S) :- every(P, compatible(S,P), statement1(P)),
several(P, compatible(S,P)).
% Statement-3:
% Mr P: Now I know the numbers!
% (There is just one sum value S compatible with the product
% value P for which statement-2 is true of S, and that value
% is S1).
statement3(P,S1) :- one(S,
(sumvalue(S), statement2(S), compatible(S,P)),
S1).
% Statement-4:
% Mr s: Now I know them too!
% (There is just one product value P compatible with the
% sum value S for which statement-3 is true of P and S,
% and that value is P1).
statement4(S,P1) :- one(P, (statement3(P,S), compatible(S,P)), P1).
% Question: What are the numbers?
% (For which sum value S and product value P is statemen-4
% true?)
answer(S,P) :- statement4(S,P).
% [The single solution S=17, P=52 is produced inabout 9 seconds].
% Definitions of the quantifiers 'one', 'several' and 'every'.
one(X,P,X1) :- setof(X,P,[X1]).
several(X,P) :- setof(X,P,Xs), length(Xs,N), N>1.
every(X,P,Q) :- \+ (P,\+Q).
% The remaining definitions are compiled:
%:-compile(sandp1).
%--------------------------------------------------------------------
% Supporting definitions for the Mr S and Mr P Problem.
% Sum values range from 4 to 198.
sumvalue(S) :- range(S,4,198).
% The next two clauses are logicaly equivalent to the third clause,
% but are more efficient in the cases that S or P are aready known.
compatible(S,P) :- nonvar(S), !, integer(S),
Mmax is S/2, S99 is S-99, max(2,S99,Mmin),
range(M,Mmin,Mmax),
P is M*(S-M).
compatible(S,P) :- nonvar(P), !, integer(P),
sqroot(P,Mmax), P99 is P/99, max(2,P99,Mmin),
range(M,Mmin,Mmax),
N is P/M, integer(N), P is M*N,
S is M+N.
% Sum value S is compatible with product value P if there are
% numbrs M and N in the range 2 to 99 such that S is the sum
% of M and N, and P is the product of M and N. (See above.)
compatible(S,P) :-
range(M,2,99),
range(N,2,99),
S is M+N,
P is M*N.
% Finally, definitions of the predicates 'range', 'max' and 'sqroot'.
range(I,L,M) :- nonvar(I), !, L=<I, I=<M.
range(I,L,_).
range(I,L,M) :- L<M, L1 is L+1, range(I,L1,M).
max(X,Y,X) :- X>=Y, !.
max(X,Y,Y) :- X<Y, !.
sqroot(N,RN) :- N<181, !, N1 is N*4, N2 is N*2,
sqroot(N1,RN1,0,N2), RN is RN1/2.
sqroot(N,RN) :- N<32768, !, N1 is N*4,
sqroot(N1,RN1,0,363), RN is RN1/2.
sqroot(N,RN) :- sqroot(N,RN,0,363).
% 'sqroot' expanded to include upper and lower limits
sqroot(N,RN,RN,_) :- N=:=RN*RN, !.
sqroot(N,RN,RN,RN1) :- RN1-RN<2, !.
sqroot(N,RN,LL,UL) :- ML is (LL+UL+1)/2, M is ML*ML,
sqrootn(N,RN,LL,UL,ML,M).
% 'sqrootn' sets up for next inocation of sqroot
sqrootn(N,RN,LL,UL,ML,M) :- M>N, !, sqroot(N,RN,LL,ML).
sqrootn(N,RN,LL,UL,ML,M) :- M=<N, sqroot(N,RN,ML,UL).
thanks
from Peter (
cmk...@hotmail.com)