PZ08B - Logic programming and Prolog
Programming Language Design and Implementation (4th Edition)
by T. Pratt and M. Zelkowitz
Prentice Hall, 2001
Section 8.4
Appendix A.12
PZ08B
Programming Language design
Logic Programming
So far programming has been algorithmic.
Procedural: statements (C, C++, FORTRAN, Pascal)
Functional: expressions (Postscript, ML, LISP)
Now we will look at declarative languages - They state
what the solution should look like; not how to compute
such a solution.
You are already an expert in some of these languages!
Example, BNF. Give a description of all even length
palindromes over 0 and 1:
Can list them: 00, 11, 0000, 0110, 1001, 1111, ...
Can give a specification rule: S 0S0 | 1S1 | 00 | 11
The BNF rule does not say how to generate such strings or
how to recognize a given string, only a description of
what all such strings look like.
There is some other process that would build the parse
tree for any given string.
PZ08B
Programming Language design
Basic for Prolog
We can specify either all the strings that obey the
relationship we want, or we can specify a pattern (the
context free production in this case) that is matched
with the input string.
This model occurs frequently in database applications.
Consider a relation X:
X(a,b) is a fact that states that a and b have relation X.
Such relations and facts are the basis for Prolog
execution.
PZ08B
Programming Language design
Prolog overview
Development by Alain Coulmerauer and Philippe Roussel,
who were interested in developing a language for
making deductions from text
Developed in Marseilles, France, in 1972
Based on the the principle of resolution by Kowalski
from the University of Edinburgh
Although there is no standard for Prolog, the version
developed at the University of Edinburgh has become a
widely used variant
A Prolog program consists of a series of facts (concrete
relationships) among data objects and a set of rules.
A process of unification on Horn clauses - as we shall
soon see - is the basis for Prolog execution
PZ08B
Programming Language design
Sample Prolog program
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Figure A.16 in text
%editor [Link]
/* Read in data as a Prolog Relation */
datavals(4,[1,2,3,4]).
%editor [Link]
go :- reconsult('[Link]'),
datavals(A,B),
Relation go starts execution
INSUM is 0,
for(A,B,INSUM,OUTSUM),nl,
write('SUM ='),write(OUTSUM),nl.
/* for loop executes 'I' times */
for(I,B,INSUM,OUTSUM) :- not(I=0),
B=[HEAD|TAIL],
write(HEAD),
NEWVAL is INSUM+HEAD,
for(I-1,TAIL,NEWVAL,OUTSUM).
/* If I is 0, return INSUM computed value */
for(_,_,INSUM,OUTSUM) :- OUTSUM = INSUM.
not(X) :- X, !, fail.
not(_).
PZ08B
Programming Language design
Simple Prolog facts
A database of facts:
inclass(john, cmsc330).
inclass(mary, cmsc330).
inclass(george, cmsc330).
inclass(jennifer, cmsc330).
inclass(john, cmsc311).
inclass(george, cmsc420).
inclass(susan, cmsc420).[.5ex]
Queries: Prolog can confirm these facts:
inclass(john, cmsc330). Prolog responds yes
inclass(susan, cmsc420). Prolog responds yes
inclass(susan, cmsc330). Prolog responds no
Prolog will search database; but these are not very
interesting.
PZ08B
Programming Language design
Example of unification
Can use a form of substitution called unification to
derive other relationships. (Will discuss unification more
formally later.)
inclass(susan, X). Prolog searches database and
responds X=cmsc420.
Hitting Enter key, Prolog says No since no other fact.
inclass(john, Y). Prolog has following responses:
Y=cmsc330.
Y=cmsc311.
no.
Can define more complex queries:
takingboth(X):-inclass(X, cmsc330),inclass(X, cmsc311).
takingboth(john)
yes
PZ08B
takingboth(Y)
Y=john.
no
Programming Language design
Prolog execution
So Prolog is:
1. A database of facts.
2. A database of queries.
3. A sequential execution model: Search facts in
order looking for matches. If failure, back up to
last match and try next entry in database.
Because of this last item, Prolog is not truly
declarative. It does have an algorithmic execution
model buried in structure of database.
Also, unlike previous languages studied, Prolog is not
complete. Not every program function can be
specified as a Prolog program.
PZ08B
Programming Language design
Simple queries
Other Examples. Multiple definitions:
registered(X) :- takingboth(X).
registered(X) :- inclass(X, cmsc330).
registered(X) :- inclass(X, cmsc311).
registered(X) :- inclass(X, cmsc420).
printclass(X) :- registered(X), write(X),
write(' is registered.'), nl.
printclass(X) :- write(X),
write(' is not registered.'),nl.
printclass(susan) prints 'susan is registered'
printclass(harold) prints 'harold is not registered'
Adding to database:
consult(user) or consult('filename') adds to data base
reconsult(user) modifies database
control-D (D) returns to query mode.
PZ08B
Programming Language design
Prolog Data
Data:
Integers: 1, 2, 3, 4
Reals: 1.2, 3.4, 6.7
Strings: 'abc', '123'
Facts: lower case names
Variables: Upper case names
Lists: [a, b, c, d]
Like ML: [ head | tail ]
PZ08B
Programming Language design
10
Append function
APPEND function: append([a,b,c], [d,e], X)
X = [a,b,c,d,e]
Definition:
append([ ], X, X).
append( [ H | T], Y, [ H | Z]) :- append(T, Y, Z).
(function design similar to applicative languages like
ML.)
PZ08B
Programming Language design
11
Clauses
REVERSE:
reverse([ ],[ ]).
reverse( [H | T ], L) :- reverse(T,Z), append(Z, [H], L).
Prolog execution is via clauses: a,b,c,d.
If any clause fails, backup and try alternative for that
clause.
Cuts(!). Always fail on backup. Forces sequential
execution. Programs with many cuts are really an
imperative program.
PZ08B
Programming Language design
12
Cuts
Logical predicates:
P :- a, b.
P :- c,d.
P is true if a and b are true or if c and d are
true, or (a b) (c d)
(This is where the term logic programming comes from.)
But:
P :- a, !, b.
P :- c,d.
P is true if (a and b) are true or if (a is false and
(c and d are true))
(a b) (not(a) c d) ( See difference?)
Cuts can be used for sequential execution:
P :- a, !, b, !, c, !, d.
PZ08B
Programming Language design
13
Not and Assignment
Not definition:
not(X) :- X, !, fail.
not(_).
If X succeeds, then fail (! prevents backtracking), and
if X fails then the second definition always
succeeds.
Assignment:
X is 3+1
X = 3+1
X=3+1, X=4
X is 3+1, X=4
PZ08B
means arithmetic value
means same expression
fails (X unifies to expression 3+1.
The expression 3+1 is not 4.)
succeeds (X unifies to 4.)
Programming Language design
14
Underlying theory of Prolog - briefly
Any logical predicate can be written in disjunctive
normal form (DNF): As a series of or'ed terms:
A (B C) = (A B) (A C)
Consider any such predicate in DNF: A B C D E
Group negated and non-negated terms together:
(A C D) (B E)
Write as: A, C, D :- B, E.
But: (A C D) (B E)
(A C D) (B E) by de Morgan's laws
(B E) implies (A C D).
So if (B E) is true, then (A C D) is true.
PZ08B
Programming Language design
15
Horn clauses
What if we only have one non-negated term? A :- B, E.
We call such expressions Horn clauses.
A:- B, E. means (B E) A
So if we show that B and E are true, then we have shown
that A must be true.
We call A :- B, E. a query.
Note: If we write a fact A., then we are simply saying
that we have the Horn clause:
true A.
PZ08B
Programming Language design
16
Unification
Prolog unification is an extension to variable
substitution.
Macros are an example of substitution:
Generate quadratic formula: a x2 + b x + c = 0
root(A, B, C) = -B + sqrt(B*B-4*A*C)/(2*A)
If A=1, B=2, C=3+4, substitution gives us:
root(1, 2, 3+4) = -(2) + sqrt((2)*(2)-4*(1)*(3+4))/
(2*(1))
Consider following 2 sets of rules:
P(x,y) = x * y
Q(z) = z2
PZ08B
Programming Language design
17
Unification - 2
Now consider:
P(c+d, Q(e+f)) = (c+d)*Q(e+f) = (c+d) * (e+f)2
P(c+d, Q(e+f)) = P(c+d, (e+f)2) = (c+d) * (e+f)2
Same result achieved two ways, substitute into P first or
into Q.
(c+d) * (e+f)2 represents both a substitution into P and
a substitution into Q.
The P substitution is c+d for x, Q(e+f) for y.
The Q substitution is e+f for z.
So we say c+d for x and Q(e+f) for y and e+f for z
unifies P and Q.
Example:
append([2,3],[4,5],L) L=[2,3,4,5] unifies clause.
append([1,2],L,M), reverse(M,[3,2,1])
L=[3], M=[1,2,3] unify these clauses.
Note in this last case, M came from reverse, L came from
append. Substitution works both ways and .
PZ08B
Programming Language design
18