Prolog Programming
slides written by
Dr W.F. Clocksin
The Plan
An example program Syntax of terms Some simple programs Terms as data structures, unification The Cut Writing real programs
What is Prolog?
Prolog is the most widely used language to have been inspired by logic programming research. Some features: Prolog uses logical variables. These are not the same as variables in other languages. Programmers can use them as holes in data structures that are gradually filled in as computation proceeds.
More
Unification is a built-in termmanipulation method that passes parameters, returns results, selects and constructs data structures. Basic control flow model is backtracking. Program clauses and data have the same form. The relational form of procedures makes it possible to define reversible procedures.
More
Clauses provide a convenient way to express case analysis and nondeterminism. Sometimes it is necessary to use control features that are not part of logic. A Prolog program can also be seen as a relational database containing rules as well as facts.
What a program looks like
/* At the Zoo */ elephant(george). elephant(mary). panda(chi_chi). panda(ming_ming). dangerous(X) :- big_teeth(X). dangerous(X) :- venomous(X). guess(X, tiger) :- stripey(X), big_teeth(X), isaCat(X). guess(X, koala) :- arboreal(X), sleepy(X). guess(X, zebra) :- stripey(X), isaHorse(X).
Prolog is a declarative language
Clauses are statements about what is true about a problem, instead of instructions how to accomplish the solution. The Prolog system uses the clauses to work out how to accomplish the solution by searching through the space of possible solutions. Not all problems have pure declarative specifications. Sometimes extralogical statements are needed.
Example: Concatenate lists a and b
In an imperative language
list procedure cat(list a, list b) { list t = list u = copylist(a); while (t.tail != nil) t = t.tail; t.tail = b; return u; } cat(a,b) if b = nil then a else cons(head(a), cat(tail(a),b)) cat([], Z, Z). cat([H|T], L, [H|Z]) :- cat(T, L, Z).
In a functional language
In a declarative language
Complete Syntax of Terms
Term
Constant
Names an individual
Compound Term
Names an individual that has parts likes(john, mary) book(dickens, Z, cricket) f(x) [1, 3, g(a), 7, 9] -(+(15, 17), t) 15 + 17 - t
Variable
Stands for an individual unable to be named when program is written X Gross_pay Diagnosis _257 _
Atom
alpha17 gross_pay john_smith dyspepsia + =/= 12Q&A
Number
0 1 57 1.618 2.04e-27 -13.6
Compound Terms
The parents of Spot are Fido and Rover.
parents(spot, fido, rover)
Functor (an atom) of arity 3.
components (any terms)
It is possible to depict the term as a tree: parents spot fido rover
Some atoms have built-in operator declarations so they may be written in a syntactically convenient form. The meaning is not affected. This example looks like an arithmetic expression, but might not be. It is just a term. =/=(15+X, (0*a)+(2<<5)) + 15 X 0 * a 2 =/= + << 5
Compound Terms
More about operators
Any atom may be designated an operator. The only purpose is for convenience; the only effect is how the term containing the atom is parsed. Operators are syntactic sugar. We wont be designating operators in this course, but it is as well to understand them, because a number of atoms have built-in designations as operators. Operators have three properties: position, precedence and associativity. more
Examples of operator properties
Position Prefix: Infix: Postfix: Operator Syntax -2 5+17 N! Normal Syntax -(2) +(17,5) !(N)
Associativity: left, right, none. X+Y+Z is parsed as (X+Y)+Z because addition is left-associative.
Precedence: an integer. X+Y*Z is parsed as X+(Y*Z) because multiplication has higher precedence.
These are all the same as the normal rules of arithmetic.
The last point about Compound Terms
Constants are simply compound terms of arity 0. badger means the same as badger()
Structure of Programs
Programs consist of procedures. Procedures consist of clauses. Each clause is a fact or a rule. Programs are executed by posing queries.
An example
Example
Predicate Procedure for elephant Facts elephant(george). elephant(mary). elephant(X) :- grey(X), mammal(X), hasTrunk(X).
Clauses Rule
Example
Queries
?- elephant(george). yes ?- elephant(jane).
Replies
no
Clauses: Facts and Rules
if provided that turnstile
Head :- Body. Head.
This is a rule. This is a fact.
Full stop at the end.
Body of a (rule) clause contains goals.
Head Body
likes(mary, X) :- human(X), honest(X).
Goals
Exercise: Identify all the parts of Prolog text you have seen so far.
Interpretation of Clauses
Clauses can be given a declarative reading or a procedural reading. Form of clause: Declarative reading: H :- G1, G2, , Gn. That H is provable follows from goals G1, G2, , Gn being provable.
Procedural reading:
To execute procedure H, the procedures called by goals G1, G2, , Gn are executed first.
male(bertram). male(percival). female(lucinda). female(camilla). pair(X, Y) :- male(X), female(Y).
?- pair(percival, X). ?- pair(apollo, daphne). ?- pair(camilla, X). ?- pair(X, lucinda). ?- pair(X, X). ?- pair(bertram, lucinda). ?- pair(X, daphne). ?- pair(X, Y).
Worksheet 2
drinks(john, martini). drinks(mary, gin). drinks(susan, vodka). drinks(john, gin). drinks(fred, gin). pair(X, Y, Z) :drinks(X, Z), drinks(Y, Z). ?- pair(X, john, martini). ?- pair(mary, susan, gin). ?- pair(john, mary, gin). ?- pair(john, john, gin). ?- pair(X, Y, gin). ?- pair(bertram, lucinda). ?- pair(bertram, lucinda, vodka). ?- pair(X, Y, Z).
This definition forces X and Y to be distinct:
pair(X, Y, Z) :- drinks(X, Z), drinks(Y, Z), X \== Y.
(a) Representing a symmetric relation. (b) Implementing a strange ticket condition.
Worksheet 3
berkshire
surrey kent
wiltshire
hampshire
sussex
How to represent this relation? Note that borders are symmetric.
WS3
This relation represents one direction of border:
border(sussex, kent). border(sussex, surrey). border(surrey, kent). border(hampshire, sussex). border(hampshire, surrey). border(hampshire, berkshire). border(berkshire, surrey). border(wiltshire, hampshire). border(wiltshire, berkshire).
What about the other?
(a) Say border(kent, sussex). border(sussex, kent).
(b) Say adjacent(X, Y) :- border(X, Y). adjacent(X, Y) :- border(Y, X).
(c) Say border(X, Y) :- border(Y, X).
WS3
Now a somewhat strange type of discount ticket. For the ticket to be valid, one must pass through an intermediate county. A valid ticket between a start and end county obeys the following rule: valid(X, Y) :- adjacent(X, Z), adjacent(Z, Y)
WS3
border(sussex, kent). border(sussex, surrey). border(surrey, kent). border(hampshire, sussex). border(hampshire, surrey). border(hampshire, berkshire). border(berkshire, surrey). border(wiltshire, hampshire). border(wiltshire, berkshire). adjacent(X, Y) :- border(X, Y). adjacent(X, Y) :- border(Y, X).
valid(X, Y) :adjacent(X, Z), adjacent(Z, Y)
?- valid(wiltshire, sussex). ?- valid(wiltshire, kent). ?- valid(hampshire, hampshire). ?- valid(X, kent). ?- valid(sussex, X). ?- valid(X, Y).
Worksheet 4
arc
a(g, h). a(g, d). a(e, d). a(h, f). a(e, f). a(a, e). a(a, b). a(b, f). a(b, c). a(f, c).
a e g h
b f
d Note that Prolog can distinguish between the 0-ary constant a (the name of a node) and the 2-ary functor a (the name of a relation).
path(X, X). path(X, Y) :- a(X, Z), path(Z, Y). ?- path(f, f). ?- path(a, c). ?- path(g, e). ?- path(g, X). ?- path(X, h).
But what happens if
a(g, h). a(g, d). a(e, d). c a(h, f). a(e, f). a(a, e). a(a, b). a(b, f). a(b, c). a(f, c). a(d, a).
path(X, X). path(X, Y) :- a(X, Z), path(Z, Y).
a d g e h
b f
This program works only for acyclic graphs. The program may infinitely loop given a cyclic graph. We need to leave a trail of visited nodes. This is accomplished with a data structure (to be seen later).
Unification
Two terms unify if substitutions can be made for any variables in the terms so that the terms are made identical. If no such substitution exists, the terms do not unify. The Unification Algorithm proceeds by recursive descent of the two terms. Constants unify if they are identical Variables unify with any term, including other variables Compound terms unify if their functors and components unify.
Examples
The terms f(X, a(b,c)) and f(d, a(Z, c)) unify.
f f X b a c d Z a c
The terms are made equal if d is substituted for X, and b is substituted for Z. We also say X is instantiated to d and Z is instantiated to b, or X/d, Z/b.
Examples
The terms f(X, a(b,c)) and f(Z, a(Z, c)) unify.
f f X b a c Z Z a c
Note that Z co-refers within the term. Here, X/b, Z/b.
Examples
The terms f(c, a(b,c)) and f(Z, a(Z, c)) do not unify. f
f c b a c Z Z a c
No matter how hard you try, these two terms cannot be made identical by substituting terms for variables.
Exercise
Do terms g(Z, f(A, 17, B), A+B, 17) and g(C, f(D, D, E), C, E) unify?
g Z f B A + B 17 C f E g C E
A 17
D D
Exercise
First write in the co-referring variables.
g Z f B A + B 17 C f E g C E
A 17
D D
Exercise
Z/C, C/Z
g Z f B A + B 17
Now proceed by recursive descent We go top-down, left-to-right, but the order does not matter as long as it is systematic and complete. g C f E C E
A 17
D D
Exercise
Z/C, C/Z, A/D, D/A
g Z f B A + B 17 C f E
g C E
A 17
D D
Exercise
Z/C, C/Z, A/17, D/17
g Z f B A + B 17 C f E
g C E
A 17
D D
Exercise
Z/C, C/Z, A/17, D/17, B/E, E/B
g Z f B A + B 17 C f E
g C E
A 17
D D
Exercise
Z/17+B, C/17+B, A/17, D/17, B/E, E/B
g Z f B A + B 17 C f E
g C E
A 17
D D
Exercise
Z/17+17, C/17+17, A/17, D/17, B/17, E/17
g Z f B A + B 17 C f E
g C E
A 17
D D
Exercise Alternative Method
Z/C
g Z f B A + B 17 C f E g C E
A 17
D D
Exercise Alternative Method
Z/C
g C f B A + B 17 C f E g C E
A 17
D D
Exercise Alternative Method
A/D, Z/C
g C f B A + B 17 C f E g C E
A 17
D D
Exercise Alternative Method
D/17, A/D, Z/C
g C f B D + B 17 C f E g C E
D 17
D D
Exercise Alternative Method
D/17, A/17, Z/C
g C f B 17 + B 17 C f E g C E
17 17
17 17
Exercise Alternative Method
B/E, D/17, A/17, Z/C
g C f B 17 + B 17 C f E g C E
17 17
17 17
Exercise Alternative Method
B/E, D/17, A/17, Z/C
g C f E 17 + E 17 C f E g C E
17 17
17 17
Exercise Alternative Method
C/17+E, B/E, D/17, A/17, Z/C
g C f E 17 + E 17 C f E g C E
17 17
17 17
Exercise Alternative Method
C/17+E, B/E, D/17, A/17, Z/17+E
g + f 17 E 17 17 E 17 E + 17 17 + f E 17 g + E E
E 17 17
Exercise Alternative Method
E/17, C/17+E, B/E, D/17, A/17, Z/C
g + f 17 E 17 17 E 17 E + 17 17 + f E 17 g + E E
E 17 17
Exercise Alternative Method
E/17, C/17+17, B/17, D/17, A/17, Z/C
g + f 17 17 17 17 17 17 17 + 17 17 + f 17 17 g + 17 17
17 17 17
Lists
Lists are the same as other languages (such as ML) in that a list of terms of any length is composed of list cells that are consed together. The list of length 0 is called nil, written []. The list of length n is .(head,tail), where tail is a list of length n-1. So a list cell is a functor . of arity 2. Its first component is the head, and the second component is the tail.
Examples of lists
nil .(a, nil) .(a, .(b, nil) .(a, .(b, .(c, .(d, .(e. nil))))) .(a,b) (note this is a pair, not a proper list) .(a, X) (this might be a list, or might not!) .(a, .(b, nil)), .(c, nil))
They can be written as trees
a nil a b nil a b a X
a b c d e nil a b nil a nil
Prolog Syntax for Lists
Nil is written []. The list consisting of n elements t1, t2, ,tn is written [t1, t2, ,tn]. .(X,Y) is written [X|Y] [X|[]] is written [X] The term .(a, .(b, .(c,Y))) is written [a,b,c|Y]. If Y is instantiated to [], then the term is a list, and can be written [a,b,c|[]] or simply [a,b,c].
Exercises
Identify the heads and tails of these lists (if any): [a, b, c] [a] [] [[the, cat], sat] [[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]
Exercises
Identify the heads and tails of these lists (if any): a [b, c] [a] [] [[the, cat], sat] [[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]
Exercises
Identify the heads and tails of these lists (if any): [a, b, c] a [] [] [[the, cat], sat] [[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]
Exercises
Identify the heads and tails of these lists (if any): [a, b, c] [a] [] (not a list, so doesnt have head and tail. nil is a constant) [[the, cat], sat] [[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]
Exercises
Identify the heads and tails of these lists (if any): [a, b, c] [a] [] [the, cat] [sat] [[the, cardinal], [pulled, [off]], [each, [plum, coloured], shoe]
Exercises
Identify the heads and tails of these lists (if any): [a, b, c] [a] [] [[the, cat], sat] [the, cardinal] [pulled, [off]], [each, [plum, coloured], shoe]
Exercises
For each pair of terms, determine whether they unify, and if so, to which terms are the variables instantiated? [X, Y, Z] [cat] [X,Y|Z] [[the,Y]|Z] [X, Y, X] [[X], [Y], [X]] [john, likes, fish] [X|Y] [mary, likes, wine] (picture on next slide) [[X,answer], [is, here]] [a, Z, Z] [[a], [X], [X]]
Remember
A variable may be instantiated to any term.
X mary likes wine [] Y Z
[mary, likes, wine]
[X,Y|Z]
Fun with Lists (Worksheet 5)
/* member(Term, List) */ member(X, [X|T]). member(X, [H|T]) :- member(X, T). Examples: ?- member(john, [paul, john]). ?- member(X, [paul, john]). ?- member(joe, [marx, darwin, freud]). ?- member(foo, X).
Exercises
Here is a mystery predicate. What does it do?
mystery(X, A, B) :- member(X, A), member(X, B).
?- mystery(a, [b, c, a], [p, a, l]). ?- mystery(b, [b, l, u, e], [y, e, l, l, o, w]). ?- mystery(X, [r, a, p, i, d], [a, c, t, i, o, n]). ?- mystery(X, [w, a, l, n, u, t], [c, h, e, r, r, y]).
A Brief Diversion into Anonymous Variables
/* member(Term, List) */ member(X, [X|T]).
Notice T isnt used
member(X, [H|T]) :- member(X, T). member(X, [X|_]). member(X, [_|T]) :- member(X, T).
Notice H isnt used
A Brief Diversion into Arithmetic
The built-in predicate is takes two arguments. It interprets its second as an arithmetic expression, and unifies it with the first. Also, is is an infix operator. ?- X is 2 + 2 * 2. X=6 ?- 10 is (2 * 0) + 2 << 4. no ?- 32 is (2 * 0) + 2 << 4. yes
is
But is cannot solve equations, so the expression must be ground (contain no free variables. ?- Y is 2 * X. no ?- X is 15, Y is 2 * X. X = 15, Y= 30.
Worksheet 6: Length of a List
/* length(List, Length) */ Nave method:
length([], 0). length([H|T], N) :- length(T, NT), N is NT + 1.
Worksheet 6
/* length(List, Length) */
Tail-recursive method:
length(L, N) :- acc(L, 0, N). /* acc(List, Before, After) */ acc([], A, A). acc([H|T], A, N) :- A1 is A + 1, acc(T, A1, N).
Exercises
?- length([apple, pear], N). ?- length([alpha], 2). ?- length(L, 3). Modify length to give a procedure sum such that sum(L,N) succeeds if L is a list of integers and N is their sum.
Worksheet 7: Inner Product
A list of n integers can be used to represent an n-vector (a point in n-dimensional space). Given two vectors a and b, the inner product (dot product) of a and b is defined
As you might expect, there are nave and tail-recursive ways to compute this.
Worksheet 7
The nave method:
inner([], [], 0). inner([A|As],[B|Bs],N) :inner(As, Bs, Ns), N is Ns + (A * B).
Worksheet 7
Tail-recursive method: inner(A, B, N) :- dotaux(A, B, 0, N). dotaux([], [], V, V). dotaux([A|As],[B|Bs],N,Z) :N1 is N + (A * B), dotaux(As, Bs, N1, Z).
Worksheet 8: Maximum of a List
Tail-recursive method has a base case and two recursive cases: /* max(List, Accumulator, Result) */ max([], A, A). max([H|T], A, M) :- H > A, max(T, H, M). max([H|T], A, M) :- H =< A, max(T, A, M). How to initialise the accumulator?
Worksheet 8
maximum(L, M) :- max(L, -10000, M). Magic numbers are a bad idea. maximum(L, M) :- max(L, minint, M) Need to change definitions of arithmetic. maximum([H|T], M) :- max(T, H, M). And know that ?- maximum([],X) fails.
Worksheet 9
arc
a(g, h). a(d, a). a(g, d). a(e, d). a(h, f). a(e, f). a(a, e). a(a, b). a(b, f). a(b, c). a(f, c).
a d g e h
b f
Here we have added a new arc from d to a. If you use the program from WS 4, some goals will cause an infinite loop.
Keep a trail of nodes visited so far. Visit only legal nodes, not already on the trail. Represent the trail as an accumulator, an extra argument of path.
Worksheet 9
path(X, X, T). path(X, Y, T) :a(X, Z), legal(Z, T), path(Z, Y, [Z|T]). legal(Z, []). legal(Z, [H|T]) :- Z \== H, legal(Z, T). Notice that legal is like the negation of member.