2 Fundamentals 3
2 Fundamentals 3
Fundamentals of Prolog
1 Introduction
These exercises are intended to help reinforce material taught in the lectures of the Declar-
ative Peogramming. They do not contribute any marks to the total for that module, and
they are meant to be self-assessed. This work should take around 3 hours, including the
self-assessment. No material is to be handed in. The work is not meant to be particularly
difficult, but merely to remind you of what we have covered in the lectures – don’t be
surprised if the answers are obvious! On the other hand, don’t be downhearted if you find
some of the material hard to follow – there’s plenty of time yet.
If you have problems with the material, please feel free to discuss it with fellow stu-
dents, or with me ([email protected]). Your feedback is welcome, and if you feel the
exercises could be made more useful, please let me know how.
2 Prolog Syntax
Identify the errors in the following Prolog program syntax. If you are unsure, type your
answers into a file to see if they load correctly. NB these are syntax errors, not logical
program errors.
% Problem 2.1
simple( program ) :- .
% Problem 2.2
simple( Program ) :- Small( Program ).
% Problem 2.3
simple( program1, X ) :- X = 2,
simple( program2, X ) :- X = 1.
% Problem 2.4
simple( ’simple program ).
% Problem 2.5
simple( %program% ).
% Problem 2.6
6thprogram( program ) :- too many( Errors ).
1
% Problem 2.7
simple program :- program(simple)
% Problem 2.8
simple program :- program(simple).
3 List Processing
The two example predicates append/3 and flatten/2 can be found in
Think about how the program works, and then answer the following questions (in your
head – not on the computer!). Remember that some queries may return more than one
answer – work out what all the possibilities are, and what order they appear in. Then
check it out on the computer.
% Problem 3.1.1
?- append( [a], [b], [c] ).
% Problem 3.1.2
?- append( [a], [b], X ).
% Problem 3.1.3
?- append( [a], [], X ).
% Problem 3.1.4
?- append( [a], b, X ).
% Problem 3.1.5
?- append( [a], X, Y ).
2
% Problem 3.1.6
?- append( X, [b,c], Y ).
% Problem 3.1.7
?- append( X, Y, [a,b,c] ).
% Problem 3.2.1
?- [A|B] = [a,a].
% Problem 3.2.2
?- [A,b,C|D] = [d,C,b,a].
% Problem 3.2.3
?- [a,[a|[]]] = X.
% Problem 3.2.4
?- [A,g,d,A] = [x,D,G,z].
[pair( a, b ),pair( c, d )]
[a,b,c,d]
The programmer types in the code, runs it with the query shown, and the answer is no.
Why? (Hint: think about how unification works – how many values can a variable be
unified with at once?)
3
% Problem 4.1.1
% append( List1, List2, BothLists )
append( [], List, List ).
append( [Head|Tail], Rest, [Head|All] ) :- append( Tail, Rest, All ).
How would you correct the code? There is one choice of input for which the incorrect
program would produce the correct answer. What is it? How many times will it be
produced? To check, try running the program with the query
?- flatten( A, B ).
(Note: look carefully at how this program uses the list to control recursion. The two
clauses represent two mutually exclusive cases – where the input is an empty list and where
it is a non-empty list.)
4 Unification
This, the main section of the practical, is aimed understanding unification. The idea is to
build a basic unification algorithm (automated reasoners please note: this is not the same
as the algorithm you are given in that mmodule – it does not have the occurs check; even if
you are doing the AR course, this practical should help deepen your understanding). This
is quite hard, so do not be dismayed if you find it tricky. Feel free to ask for help from
your tutor, me, or your fellow students. Those who don’t have problems – remember that
explaining things to others is a valuable part of the learning process.
We are going to use a special representation for variables, so that we don’t have to
worry about what is a Prolog variable and what is one of our own variables. So we use
in an operator, +, to mark a variable, and we make its name a Prolog constant, like this:
+variable – note the lower case “v”. We will also use a special notation for terms, like
this:
functor-[term1,term2,...]
so a term with no arguments is written noargs-[]; and we will restrict ourselves to symbols
with only lower case letters in them. Choosing these notations will make life very much
simpler.
4
We want a predicate called unify/3 which will take two terms, and try to unify them.
If it succeeds, the third argument will be a list of binary unifiers, which are pairs like this:
u( +a, v-[] )
which (in this example) means that variable a has been unified with term v.
You can find a file called “unification partial.pl” in the Prolog module code directory,
http://www.dai.ed.ac.uk/dai/teaching/modules/prolog/code/. It contains some of
the code needed for this assignment. You are required to add in the parts which are missing;
to do this, you will need to understand all the code which is present. Missing parts are
marked /* MISSING N */ where N is a number between 1 and 10 inclusive; fill in the
missing parts in order of the numbers. Make up around 10 goals to test your program,
deciding in advance what the answers should be. Remember to check that you don’t get
too many answers, and that non-unifiable terms don’t unify!
Here are some example questions and answers:
B = [u(+(x),+(y))] ?
yes
| ?- unify( f-[g-[h-[],+y],+x], f-[+x,g-[+a,+a]], B ).
B = [u(+(y),+(a)),u(+(a),h-[]),u(+(x),g-[h-[],+(y)])] ?
yes
| ?- unify( f-[], +x, B ).
B = [u(+(x),f-[])] ?
yes
| ?- unify( f-[+x,+y], f-[g-[],+x], B ).
B = [u(+(y),+(x)),u(+(x),g-[])] ?
yes
| ?- unify( f1-[], f2-[], B ).
no
| ?-