University of Toronto
Department of Computer Science

CSC324 - Principles of Programming Languages

Spring 1998
John Mylopoulos


Programming in Prolog: Tutorial Notes 4

Prepared by Thodoros Topaloglou


1. How to use Prolog.
---------------------

% cprolog
C-prolog version ..             { invokes Prolog }
| ?-                            { Prolog runs in query mode }
| ?- halt.                      { exit Prolog }
%

% prolog myfile                  { invokes Prolog and loads myfile }

% more /local/doc/Cprolog1.4/Cprolog1.4.doc	  { User's Guide }

2. Reading-in files 
-------------------

% prolog
| ?- [myfile].			{ consults file }
| ?- ['tmp/one'].               { consults file one from dir tmp }
| ?- [one, two].                { consults files one, two }
| ?- [three, -one].             { consults three and reconsults one }
| ?- [user].			{ enter clauses from terminal }
|				  { this is the new prompt }
| a(0).
| 			{ to return at query mode }
| ?- a(X).			{ posing query }
X = 0
Yes				{ Prolog's answer }
|?- halt.                       { exit }
%

3. Write a simple program
-------------------------

	/option 1/				/option 2/

%prolog						%vi myfile
|?- [user].					
| a(1).						%prolog myfile
| a(2).
    .
| a(3).						     .
| Ctrl-D
| ?-a(1).		{ does a(1) hold? }
Yes
| ?-a(0).               
No
| ?-a(X)		{ return those X's for which a(X) is true }
X = 1;			  { more answers }
X = 2;
X = 3;
No			{ no more answers }
| ?-

4. Utilities.
------------

| ?- listing.		/* produces a listing of the current content of
a(1).			/* Prolog's workspace
a(2).
a(3).
Yes
| ?-halt.

%prolog file2		/* restore file2
| ?-consult(f).		/* same as ?-[f].
| ?-reconsult(f).       /* same as ?-[-f].

more file handling

see(F)          file F becomes the current input stream
seeing(F)       succeeds if F is the current input stream
seen            current input is closed

tell(F), telling(F), told       for output stream

?-tell(F), listing, told.       save prolog's workspace into file F
?-tell(F), listing(a), told.    save a listing of all "a" defns into file F


5. Simple Examples
------------------

Prolog's Syntax (incomplete.. see notes for complete syntax):

clause ::= fact | rule
rule ::= head :- body
body ::= literal {, literals}
literal ::= functor [ arg-list ] | ..
arg-list ::= ( arg {, agr} )
arg ::= var | string | number | literal
...

<1>
| ?- [user].
mother(a,e).                                 / FACTS /		.
father(a,b).                                    .		.
father(b,c).                                    .			. 
father(d,b).                                    .			.
parent(X,Y) :- mother(X,Y).                  / RULES /			.
parent(X,Y) :- father(X,Y).			     .
.
grandfather(X,Y) :- parent(Z,Y), father(X,Z).   .	/ PROLOG DB /
Ctrl-D
| ?- father(a,b).			     / QUERIES /
Yes
| ?- father(X,b).
a;
d;
Yes

<2>
islist([]).
islist([Head|Tail]) :- islist(Tail).			/ AXIOMS /

[a, b, c]                                               / LISTS /
.(a.(b.(c.nil)))
nil
[]

?- islist([1,a,2]).
Yes

?-islist(tom).
No

<3>
is_list_of_integers([]).
is_list_of_integers([Head|Tail]) :-
				 integer(Head),			/* checks is
				 Head is instantiated to 
				 is_list_of_integers(Tail).	/* an integer

other useful built-in predicates for testing/type_checking

var(X)		      checks if X is currently instantiated to a variable
atom(X)			     checks if X is .. non-var term of arity 0 other
than a number		     
atomic(X)		     checks if X is an atom or a number
number(X)		     ...

<4>

member(X, [X|_]).
member(X, [Y|R]):- member(X,R).

?-member(1,[2,1,3]).
yes

6. Good documentation
---------------------

a. islist/1
	arg1: has to be instatiated
   succeeds if arg1 is a list

b. is_list_of_integers/1 self-documented

use descriptive names for predicates and variables 

in-line comments

	% this is one line comment

	/* this is
	   multiple lines comment	*/

7. Prolog's many faces! (3)
------------------------------- 

declarative  (as above)
procedural   (see below)
database     (the family example)

A :- B,C.
?-A.            call A          /PROCEDURAL/
                >>>> call B
                >>>> call C
                end

8. Prolog's execution 
---------------------

?- A.    
   is A true? OR can you prove A (according to what is defined in)

focuses on WHAT, rather than HOW!

Prolog's inference engine performs linear input resolution (it is essentially
a combination of depth first search and unification)

p(X) :- q(X), r(X).
q(1).
q(2).
r(3).

?- p(X). /* query: is there an obj. X that satisfies properties q and r.*/
No

Why?		     p(X)
                   _______|________
		             |      and       |
                q(X)              r(X)
           _____|___             |
          |      or       |             |
         q(1)           q(2)      r(3)

OR

proc p(X)
     : call q(X)
     : call r(X)
end p

call p(X)

9. Debugging facilities
------------------------

| ?- trace.		{ switches tracing mode ON }
yes

| ?- .
.... trace output ..

| ?- notrace.		{ switches tracing OFF}
yes 

|?- debug.		{ switches debugging ON}
|?- nodebug.		  { switches debugging OFF}

Tracing/debugging is based on the BOX model:

		            +--------------+
         Call --->|              |---> Exit
                  |  procedure   | 
         Fail <---|              |<--- Back-to
                  +--------------+


/*
 * 10. List Processing
 * ------------------							     
 */

flatten( [Head | Tail], Flat) :-
        flatten( Head, FH),
        flatten( Tail, FT),
        append( FH, FT, Flat).
flatten( X, [X]) :-
         X \== [] .
flatten([], []).


/*	    ?-flatten([1,[2,3],2,[[3,4]]],X).				*/
/*	      X = [1,2,3,2,3,4]
*/
/*	Yes								*/
/*	?- flatten([2,[3,[4]],1], X).
*/
/*	  X = [2,3,4,1]							*/
/*	  Yes
*/
/*	?- flatten([[2],[3]],X).					*/
/*	  X = [2,3]
*/
/*	yes								*/



append([],L,L).
append([A|L1],L2,[A|L3]):-
        append(L1,L2,L3).


/*
 *
 * 11. Recursion and Iteration
 * --------------------------
 */

/* Four implementations of factorial */

factorial1(0,s(0)).
factorial1(s(N),F) :- 
		   factorial1(N,F1), 
		   times(s(N),F1,F).

times(0,X,0).
times(s(X),Y,Z) :- 
		times(X,Y,W), 
		plus(W,Y,Z).

plus(0,X,X) :- natural_number(X).
plus(s(X),Y,s(Z)) :- plus(X,Y,Z).

natural_number(0).
natural_number(s(X)) :- natural_number(X).

/*
 * Another recursive definition. 
 */

factorial2(0,1).

factorial2(N,F) :-
        N > 0, 
	N1 is N - 1, 
	factorial2(N1,F1), 
	F is N * F1.

/*
 * This is an iterative definition.
 */

factorial3(N,F) :- factorial3(0,N,1,F).

factorial3(N,N,F,F).
factorial3(I,N,T,F) :-
        I < N, 
	I1 is I + 1, 
	T1 is T * I1, 
	factorial3(I1,N,T1,F).

/*
 * A second example of an iterative factorial.
 */

factorial4(N,F) :- factorial4(N,1,F).

factorial4(0,F,F).

factorial4(N,T,F) :-
        N > 0, 
	T1 is T * N,	
	N1 is N - 1, 
	factorial4(N1,T1,F).







.