These minimal notes on Prolog show only some of its flavor.
Here are facts
plays(ann,fido). friend(john,sam).where ann, fido, john, and sam are individuals, and plays and friend are functors. And here is a rule
likes(X,Y) :- plays(X,Y),friend(X,Y).It says that if X plays with Y and X is a friend of Y then X likes Y. Variables start with capital letters (If we are not interested in the value of a variable, we can just use _ (underscore)).
On yoda, you call prolog as /usr/local/prolog/bin/prolog. The prompt in prolog is
| ?-You exit prolog with the statement
halt.You can add rules and facts to the current session in a number of ways:
| ?- consult(user). | like(b,a). | like(d,c). ^Dwhich adds the two clauses to the working space.
| ?- consult('filename').which is added at the end of the working space.
| ?- assert(< clause >).
variable arithmetic predicate relation substitution computation ----------------------------------------------------------- == identical no no = unifiable yes no =:= same value no yes is is the yes yes value ofand some examples of their use:
?- X == Y. no ?- X + 1 == 2 + Y. no ?- X + 1 = 2 + Y. X = 2 Y = 1 ?- X + 1 = 1 + 2. no
factorial(0,1). factorial(N,F) :- N>0, N1 is N-1, factorial(N1,F1),F is N*F1. then ?- factorial(5,F). F = 120 ?- factorial(X,120). instantiation error
factorial(0,1). factorial(N,F) :- N1 is N-1, factorial(N1,F1),F is N*F1. then ?- factorial(5,F). F = 120; Here ";" asks for next value of F keeps on going until stack overflow
(1) factorial(0,1). (2) factorial(N,F) :- factorial(N1,F1), N is N1+1, F is N*F1. then ?- factorial(5,F). F = 120 ?- factorial(X,120). X = 5; integer overflow Here is why factorial(X,120) returns 5. For brevity, instead of "factorial" we will write "f". f(X,120) / | / | [0/N5,1/F5,1/N4,1/F4,2/N3,2/F3,3/N2,6/F2,4/N1,24/F1,5/N1] / +-----------------------+ / | | | f(0,1) f(N1,F1) X is N1+1 6 is X*F1 / | / | [0/N5,1/F5,1/N4,1/F4,2/N3,2/F3,3/N2,6/F2,4/N1,24/F1] / +-----------------------+ / | | | f(0,1) f(N2,F2) N1 is N2+1 F1 is N1*F2 / | / | [0/N5,1/F5,1/N4,1/F4,2/N3,2/F3,3/N2,6/F2] / +-----------------------+ / | | | f(0,1) f(N3,F3) N2 is N3+1 F2 is N2*F3 / | / | [0/N5,1/F5,1/N4,1/F4,2/N3,2/F3] / +-----------------------+ / | | | f(0,1) f(N4,F4) N3 is N4+1 F3 is N3*F4 / | / | [0/N5,1/F5,1/N4,1/F4] / +-----------------------+ / | | | f(0,1) f(N5,F5) N4 is N5+1 F4 is N4*F5 | | | [0/N5,1/F5] | f(0,1)In this diagram we see the substitutions computed. Much is not said in the diagram, for example why we abandon the unifications with the various f(0,1)s. [Let's say it for the second f(0,1) from the top: because it forces the substitution [0/N1,1/F1,1/X] and this cause 6 is X*F1 to fail.]
Dot Notation List Notation Lisp Notation ----------------------------------------------------- .(X,Y) [X | Y] (X . Y) .(X, .(Y,Z)) [X,Y|Z] (X (Y . Z)) .(X, .(Y, .(Z, []))) [X,Y,Z] (X Y Z)
len([],0). len([_|T], N) :- len(T,M), N is M+1. ?- len([a,b,c],X). X = 3 ?- len([a,b,c], 3). yes ?- len([a,b,c], 5). no
member(X,[X|_]). member(X,[_|T]) :- member(X,T). ?- member(X, [1,2,3,4,5]). X=1; X=2; X=3; X=4; X=5; no
select(H,[H|T],T). select(X,[H|T],[H|T1]) :- select(X,T,T1). ?- select(X,[a,b,c],R). X=a R=[b,c]; X=b R=[a,c]; X=c R=[a,b]; no
S E N D + M O R E --------- M O N E Yto be solved by mapping the letters into distinct digits and then doing regular arithmetic. We add variables to represent the various carries:
C3 C2 C1 S E N D + M O R E ------------ M O N E YWe observe that carries can only be 0 or 1 and thus that M has to be 1. Then here is a solution:
solve([S,E,N,D], [M,O,R,E], [M,O,N,E,Y]) :- M=1, L=[2,3,4,5,6,7,8,9], select(S,L,L1), S>0, (C3=0; C3=1), ";" means OR O is S+M+C3-10*M, select(O, L1, L2), select(E,L2,L3), (C2=0;C2=1), N is E+O+C2-10*C3, select(N,L3,L4), (C1=0;C1=1), R is E+10*C2-(N+C1), select(R,L4,L5), select(D,L5,L6), Y is D+E-10*C1, select(Y,L6,_). ?- solve([S,E,N,D], [M,O,R,E], [M,O,N,E,Y]). S=9 E=5 N=6 D=7 M=1 O=0 R=8 Y=2; no
ingargiola@cis.temple.edu