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