Please use the alphabetical Index, Contents List, and your browsers search feature to find what you need.

This page generated at Mon May 18 19:43:10 PDT 1998.

This page is part of the CS320: Programming Languages Course on the Computer Science Department's WWW Server at CalState, San Bernardino, California, USA. It was generated by Doc Dick Botting.


Contents


    CS320 First Prolog Laboratory -- the elements of Prolog

    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.plg
    and 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...

    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
     	pl
    Tell 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:
  1. list::=left_bracket item #(comma item) right_bracket | pair.
  2. item::=any structure, constant, variable, or list.

    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].

    Arithmetic is not logical

    Prolog was not designed to make scientific calculations easy! But Prolog does have something like a FORTRAN/C/C++ assignment: The key symbol is the reserved word is that forces Prolog to calculate the value of the expression on its right. After doing this it tries to unify the left hand side with the result.

    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.

    And Then,

    Prolog uses a comma in lists, arguments, and also to construct a sequence of terms(like a C/C++ semicolon) and a conjunction(and-operator). It is a little like Ada 'and then'.

    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.

    More arithmetic

    As a general rule arithmetic expressions as not evaluated in Prolog. They are parsed and stored as structures. The Unification process does not evaluate them either. The value of an expression is only calculated on the right hand side of 'is' and on both sides of '<', '>', '=<', '>=', '=:='. Prove this to yourself by trying out the following:
     	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
     ;	or
    The following demonstrate the Booleans: true and fail.
     	true.
     	fail.
     	true; fail.
     	fail;fail.
     	true;true.
     	fail;true.

    Conditions related to the Calendar

    Here are some more examples of conditions concerned with testing for a leap year:
     	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 = a
    and 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(:-).

    Next lab

    [ lab2.html ]

Labels and Definitions in Alphabetical Order