This page generated at Mon May 18 19:43:10 PDT 1998.
From the Book
Read section 2.13 before you start this laboratory... Now download
and save the following file as ASCII text:
[ pg84.plg ]
Start Prolog like this
Q pg84.plgand the code will be compiled ready for you to input the two queries (at the "?-" prompt) that are in Sebesta on page 84. You can list the program with the query "listing.". Don't forget the periods! Use CTRL/D to terminate the Prolog run.
Hints.
Study these hints... especially if unexpected things happen...
End of line does not count.
X is a variable - with an unknown (as yet?) value.
x is the atom x
help(word).
apropos('string').
pl
consult('name_of_file').
The Game is afoot!
This is simple demonstration of the power of Logic Programming.
Don't get bogged down in how, just download and run
the program.
Sherlock Holmes is using a computer("The Engine") to investigate the murder at the Metropolitan Club. Read the handout first....
Find and download(Save as text) a copy of
http://www/cs320/prolog/metro1.plg[ metro1.plg ] You can run Prolog with UNIX command
plTell the interpreter to compile the facts of the case into database.
consult('metro1').
^Don't forget the punctuation.You can now investigate the murder.
What happens when you input these lines?
listing(murderer).
listing(room).
listing(attire).
listing(hair).Don't forget the periods, and the case of everything is lower case.
Then try inputting this query:
murderer(X).Don't forget the periods, and the case of X.
Was that neat? We will now ask Prolog to show us, step by step how it solved the crime:
trace, murderer(X).Keep tapping return as each step is taken.
Help
Start up Prolog and try the following queries out...
Don't forget the '.' at the end of each query.
help.
help(1-1).
help(2-1).
help(=).
help(is).
apropos(list).
apropos(help).
Variables and Constants
Prolog comes programmed with some very simple facts that
make X=Y precisely when they are identical expressions/structures.
Start up Prolog and the input the following (after the ?- prompt!)
X = 1.
^ do NOT forget the dot!
X = 2.
x = 1.
X = x.Question: Is Prolog case sensitive in a funny way? How?
print(X).Fact: If a variable is not defined then it is bound to a special unknown and unique variable Gnnn for some number nnn.
Next we state that X is identical to 1 and then ask Prolog to print out the value of X.
X = 1, print(X).A comma in Prolog means And then.
X = 1, print(X).
print(X).Question: What is the life time of the variable X above?
X = 1, X=1, print(X).
X = 1, print(X), X = 2, print(X).Question: Inside a sequence, can a variable be changed, once it is defined?
Unification
Prolog has something a lot more powerful than simple assignments.
If you give it an equation:
X=Y.It tries to find values that make X and Y the same.
Try the following queries out... one at a time and think about what happens.
Don't forget the '.' at the end of each query.
X=x.
X=1*3.
X= a*b^2+b*x+c.
X*Y=1*3.
X*Y=1+3.
X+Y=1+3.
R=x*cos(theta)+r*sin(theta).
X+Y=x*cos(theta)+r*sin(theta).
A*B+C=x*cos(theta)+r*sin(theta).
X*5=1*Y.
X=1+2*3.
X+(Y*Z)=1+2*3.Think a little about the results. How does '=' in Prolog differ from '=' in say C++?
Structures
Structures in Prolog can be written like this
name(field, field, field, ....)so they look just like procedure or function calls. In Prolog data and program are similar!
Try these, one at a time, thinking the meanwhile:
print( date(12,01,1945) ).
date(13,01,1945)=date(12,01,1945).
date(12,01,1945)=date(12,01,1945).
dare(12,01,1945)=date(12,01,1945).
date(01,12,1945)=date(12,01,1945).
date(Day,Month,Year)=date(12,01,1945).
date(D,_,_)=date(12,01,1945).
date(_,Month,_)=date(12,01,1945).
date(_,_,Year)=date(12,01,1945).
date(_,jan,_)=date(12,01,1945).Note: _ is a kind of wild card variable. Each occurrence of '_' can have a different value.
Here are some more complex structures:
mother(rhea, X)=mother(Y, jupiter).
father(saturn, X)=father(Y,Y).
son(jupiter,saturn)=son(Y,Y).
p(X,Y)=p(Z,Z), X=alpha.
Lists in Prolog
Prolog came after LISP - indeed the early versions were programmed
in LISP and/or borrowed the syntax of LISP as well. However the notation
is different:
Advice... don't try to input a list as a command.
Here are some examples of lists:
X=[1, 2, 3, 4, 6, 7], Y=X.
[X | Y] = [1, 2, 3, 4, 6, 7].
[X, Y, Z] = [1, 2, 3].
[X, Y, Z] = [1, 2, 3, 4].
[First | Rest] =[1, 2, 3, 4, 6, 7].
[Fudge | Chocolate] =[1, 2, 3, 4, 6, 7].
[First, Second | Rest]=[1, 2, 3, 4, 6, 7].
[First, Second, Third]=[Second, Third, First], First=1.
[ sin(X), cos(Y) ] = [ 0, 1].
[ sin(X), cos(Y) ] = [ sin(a), 1].
[ sin(X), cos(Y) ] = [ sin(a), cos(b)].
A predicate
The predicate 'member' is defined in prolog. member(X,Y) is true
if Prolog can find a match between X and the elements of Y.
Here is the official documentation:
help(member).Note. Sorry about the jargon.... ignore it for now! How about looking at the source code:
listing(member).Question. Is that a neat definition or what! Do you want to see if works?
member( 1, [ 1,2,3,4,5]).
member( 0, [ 1,2,3,4,5]).It can be used to generate a whole series of items from the list:
(Hit ";" after each X=.... is output).
member( X, [1,2,3,4,5,6]).The values generated by member can be used in the next term in the query:
member(X, [1,2,3]), Y=a(X,X).Several such can be done in one query:
member(X, [1,2,3]), member(Y,[1,2,3]), XY=[X,Y].
member(X, [1,2,3]), member(Y,[1,2,3]), X<Y, XY=[X,Y].
Firstly you can use is as a condition or test:
1 is 1+2*3.
7 is 1+2*3.Second you can use it to bind a value to a variable like Answer or 'X'.
Answer is 1+2*3.
X is 1*2+3.But the next one fails:
answer is 1+2*3.
(whY!)One of the following is OK and one is a "No.", which:
x is 1*2*3*4*5.
X is 1*2*3*4*5.
Don't forget that variables are unbound after the statement has been interpreted:
X is 1*2*3*4*5.
Y is X.
But you can do a series of calculations using the comma:
X is 3*3, Y is 4*4, Z is 5*5, W is X+Y, W=Z.
These rules take a little time to master. Can you predict the outcomes of the following:
X = 17+3.
x is 17+3.
x = 17+3.
X is 17+3.
How about the following:
X is 17 + x.
X = 17 + x.
Arithmetic Operators:
Our Prolog has the following arithmetic operators
+ - * / mod ^Try them out.
Try out the following queries:
X=1+2, Answer = X.
X=1+2, Answer is X.
X=Y+Z, Z=1, Y=3, ANSWER is X.
X=Y+Z, Z=1, Y=3, A = X.
X=Y+Z, Z=1, Y=3, A is X.
7 is 1+2*3.
1+2*3 is 7.
7 = 1+2*3.
1+2*3 = 7.
X=1+2*3.
X is 1+2*3.
1+2*3 = X.
1+2*3 is X.
X=1, Y=2, Z=3, W=X+Y*Z.
X=1, Y=2, Z=3, W is X+Y*Z.
X=1, Y=2, Z=3, X+Y*Z=W.
X=1, Y=2, Z=3, X+Y*Z is W.
X+alpha=beta+Y.Also test things like the following.... watch out there is one operator below that is NOT a prolog relation!
1+2+3<2*3.
1+2+3>2*3.
1+2+3<=2*3.
1+2+3=<2*3.
1+2+3=>2*3.
1+2+3=:=2*3.
1+2+3=\=2*3.
1+2+3=2*3.
1996 mod 4=:=0.
Boolean operators and conditions
The semicolon in Prolog is unique. It means 'or'.
Prolog
, and
; orThe following demonstrate the Booleans: true and fail.
true.
fail.
true; fail.
fail;fail.
true;true.
fail;true.
1996 mod 4 =:= 0.
1997 mod 4 =:= 0.
1998 mod 4 =:= 0.
1996 mod 4 =\= 0.
1996 mod 100 =:= 0.
1900 mod 100 =:= 0.Julis Caesar's calendar used this Law:
1996 mod 4 =:=0, 1996 mod 100=\=0.We now use the Gregorian formular:
(1996 mod 4 =:=0, 1996 mod 100=\=0; 1996 mod 400 =:=0).
(1997 mod 4 =:=0, 1997 mod 100=\=0; 1997 mod 400 =:=0).
(1998 mod 4 =:=0, 1998 mod 100=\=0; 1998 mod 400 =:=0).
(1900 mod 4 =:=0, 1900 mod 100=\=0; 1900 mod 400 =:=0).
(1600 mod 4 =:=0, 1600 mod 100=\=0; 1600 mod 400 =:=0).
or-else
To be precise comma and semicolon are not just shortcircuited boolean
operators like in C. They are also used to make programs. A comma
means "and_then", and a semicolon makes an "or_else".
Here is quey that is very like an earlier one... but there is a semicolon in it. Semicolons separate Alterntatives.
X = 1, print(X); X = 2, print(X).When the first X is printed, input a semicolon to find the next one, like this:
3 ?- X = 1, print(X); X = 2, print(X).
1
X = 1 ;
The semicolon in Prolog separates alternate solutions to a problem. Prolog tries out each in turn, and if one does not work it tries the next. Prolog will supply several answers to a problem - just input ';' (or-else!) after the first solution is printed. Example:
X=a; X=b; X=c.Produces
X = aand the Prolog waits for
;and so on
X = b ;
X = c ;
No(meaning there are No more). Try the above.
The semicolon has lower priority than a comma(and-then) (like in English). Try the following:
X=1,Y=2; Y=1,X=2; X=a,Y=b.
Notice that the bindings are undone at the end of each alternative.
X=1,Y=2,SUM is X+Y; X=3,Y=4, SUM is X+Y.
We can also use parentheses '()' in Prolog statements:
(X=1;X=2;X=3),(Y=1;Y=2;Y=3), SUM is X+Y.(9 answers....)
Finally, Prolog will not produce output if a condition is false:
(X=1;X=2;X=3),(Y=1;Y=2;Y=3), 4 is X+Y.(only 3 answers).
Prolog loops!
Using the 'member' predicate we can abbreviate
X=1,X=2,X=3....and so we can solve simple word problems by writing searches: What digit has a square of 9?
member(X,[1,2,3,4,5,6,7,8,9,0]), X*X =:= 9.
What digit has a square of 3?
member(X,[1,2,3,4,5,6,7,8,9,0]), X^2 =:= 3.
How about looking for a solution of an equation:
member(X,[1,2,3,4,5,6,7,8,9,0]), X^2-11*X+28=:=0.
But the following fails.... why?
member(X,[1,2,3,4,5,6,7,8,9,0]), X^2-11*X+28=0.
Storing facts for the future.
You noticed that variables have a very short life time: One statement
at most:
X=1.
X=Z.We can store a set of alternative values in the Prolog data base by 'asserting' that a 'predicate' is true:
assert(a(1)).
assert(a(2)).
assert(a(3)).The three statements above will place three "simple facts" in the data base:
listing(a).We can ask prolog about these stored facts, for example "is a(1) true":
a(1).or "is a(4) true":
a(4).or
a(x).
But we can ALSO retrieve the all the values by using a variable instead of a constant and tapping ";" each time, like this:
a(X).
Given a value of X that fits a(X), and another value in Y use them in a test and so generate a series of solutions to an equation:
a(X),a(Y), X+Y =:= 4.
Example of defining a set
Here I define what a vowel is:
assert(vowel(a)).
assert(vowel(e)).
assert(vowel(i)).
assert(vowel(o)).
assert(vowel(u)).And then you can run this:
vowel(V), write(b),write(V),write(g),nl.Hint: help(nl). etc
It's a pocket database
The following defines the set of nonzero digits, even if it takes too
much typing...:
assert(d(1)). assert(d(2)). assert(d(3)).
assert(d(4)). assert(d(5)). assert(d(6)).
assert(d(7)). assert(d(8)). assert(d(9)).You can now find out if there is a 2 digit number that is equal to the sum of the squares of its digits:
d(D1), d(D2), N is 10*D1+D2, N =:= D1^2+D2^2.
How might you find a 3 digit number that is equal to the sum of the cubes of its digits?
Using 'assert' all the time is a pain!
The good news is, that the Prolog compiler reads in and compiles a file of statements by asserting them... but this is enough, for one lab(:-).