you must not remove this paper from the examination room

UNIVERSITY OF LONDON
GOLDSMITHS COLLEGE
B.Sc. Examination 2005
COMPUTING AND INFORMATION SYSTEMS
IS53020A (CIS335)
Logic Programming
Duration: 2 hours and 15 minutes
Date and Time:
Full marks will be awarded for complete and correct answers to a total of three questions;
do not answer more than three questions. Each question carries 25 marks. The marks for
each part of a question are indicated at the end of the part in [.] brackets.
75 marks are available on this paper.
No calculators should be used.
YOU MUST NOT REMOVE THIS PAPER
FROM THE EXAMINATION ROOM
IS53020A (CIS335) 2005
1
TURN OVER
1. This question is about Prolog program syntax, unification and datatypes
(a) Write down the most specific syntactic category, in Prolog, of the underlined part of each
of the following items. For example, the most specific category of the underlined part of
p(X) is “variable”.
i. p(h(X)).
[1]
Answer: Term.
ii. q(2).
[1]
Answer: Clause or Fact (Not Term).
iii. grey(rhino).
[1]
Answer: Atom.
iv. p( X ) :- \+ q(X,Y), r(Y).
[1]
Answer: Literal
v. p( X ) :- \+ q(X,Y), r(Y).
[1]
Answer: Literal
(b) Write down the unification algorithm used by Prolog. You may assume the ability to detect
whether an object is a variable, and whether two atomic objects are identical.
[10]
Answer: To unify two terms, A and B:
i. If both A and B are atomic, and they are identical, then succeed;
[2]
ii. If either A or B is a variable, or both, make them identical and succeed;
[3]
iii. If A and B are terms, and their functors are identical, apply unification pairwise to the
respective lists of their arguments. It this succeeds, then succeed;
[4]
iv. Othewise, fail.
[1]
(Any equivalent algorithm—e.g., with optimisations—is acceptable.)
(c) It is possible to construct a datatype of difference lists in Prolog. Difference lists are almost
exactly like ordinary lists, except that they can be added to at both ends, instead of just at
the front, like ordinary lists. In Prolog, a difference list can be constructed syntactically
from an ordinary list and two references to a variable. One reference to the variable is
placed instead of the tail of the list, and then the resulting structure and the other reference
to the variable are paired together using an operator, usually minus, -. So the ordinary list
[1,2,3] is written as the difference list [1,2,3|X]-X.
Given this information, explain the purpose and operation of the following mystery predicate, by means of a step-by-step example on some difference list data of your own creation.
You may assume that the first two arguments are inputs and that the third is an output.
mystery( A-B, B-C, A-C ).
IS53020A (CIS335) 2005
2
[10]
TURN OVER
Answer: The predicate functions as the append/3 predicate for difference lists; it joins
together the two lists given in its first and second arguments and returns the results in
its third argument.[2] The predicate works by unification only. Suppose that we apply it
to the following three arguments: [1,2|X]-X, [3,4|Y]-Y, and Z. The sequence of
events is as follows: First, A (in the predicate) is unified with [1,2|X] (in the data). [1]
Then B is unified with X. [1] So A now contains [1,2|B]. [1] Next, B (in the predicate)
is unified with [3,4|Y] (in the data). [1] Because B is part of A, A now has the value
[1,2,3,4|Y]. [1] Next C (in the predicate) is unified with Y (in the data). [1] Because
Y is part of A, A is now equal to [1,2,3,4|C]. [1] Finally, Z is unified with A-C, giving
the answer [1,2,3,4|C]-C, [1] which is the difference list resulting from appending
the two input data.
IS53020A (CIS335) 2005
3
TURN OVER
2. This question is about Prolog lists and list processing and set predicates.
(a) What is the primary difference between a list and other structured datatypes from the point
of view of storing data items?
[2]
Answer: Lists can contain arbitrary numbers of elements, while the only other structured
datatype in Prolog, the term, can contain only fixed numbers of elements.
(b) The syntax commonly used for Prolog lists, such as [X|Y] is syntactic sugar for a less
readable internal representation. What are the two constructors from which the datatype
is built?
[6]
Answer: The two constructors are: the empty list atom [] [2]; and the “dot” functor, ./2,
[2] which, when constructing a well formed list, takes a term as its first argument and a
(possibly empty) list [2].
(c) The predicate member/2 can be used to test whether a term is an element of a list. It is
defined thus:
member( H, [H| ] ).
member( X, [ |T] )
:-
member( X, T ).
i. Using member/2, write a predicate, memberboth/3, which succeeds if its first
argument is a member of both its second and third arguments, assuming they are
lists.
[2]
Answer: memberboth( A, B, C )
:-
member( A, B ),
member( A, C ).
ii. Write a program which will use memberboth/1 with a Prolog set predicate to
compute the intersection (i.e., the list of common members) of two lists. Call your
program intersection/3.
[5]
Answer: intersection( A, B, C ) :findall( X, memberboth( X, A, B ), C ).
iii. Write another version of memberboth/3 which does not call any other predicates.
Your predicate will need 4 clauses, 3 of which will be recursive. To see how to write
the new predicate, consider all the different cases generated by the two clauses of
member/2 in your answer to (i) above.
[10]
Answer: memberboth( H, [H| ], [H| ] ).
memberboth( H, [H|T1], [ |T2] ) :memberboth( H, [H|T1], T2 ).
memberboth( H, [ |T1], [H|T2] ) :memberboth( H, T1, [H|T2] ).
memberboth( H1, [ |T1], [ |T2] ):memberboth( H, T1, T2 ).
If there is a mistake in (i), mark this accordingly.
IS53020A (CIS335) 2005
4
TURN OVER
3. This question is about metaprogramming.
(a) What distinguishes a metaprogram from an ordinary program?
[2]
Answer: A metaprogram operates over data which represents (names) a program.
(b) Explain the function of the following metapredicates in Prolog.
i. ground/1
[1]
Answer: ground/1 succeeds if and only if its argument is fully instantiated.
ii. =../2
[3]
Answer: =../2 (univ/2) succeeds if and only if its left argument is a term whose
functor is the first element of the list in its right argument and whose arguments are
the remaining elements of that list, in order.
iii. ==/2
[2]
Answer: ==/2 succeeds if and only if its two arguments are syntactically identical.
iv. clause/2
[2]
Answer: clause/2 succeeds when its first and second arguments unify with the
head and body, respectively, of a clause in the Prolog database.
(c) Explain in detail the behaviour of the metainterpreter solve1/1, below, and compare
and contrast the effects of using the alternative, solve2/1, on the simple Prolog program, p/2, also below. You need not discuss error handling; you will not be penalised for
minor syntactic errors in your example; and you need not write out any repeated sequences
of events more than once (i.e., just explain that there is a repeat). Use the numbers and
letters given in the comments to refer to individual clauses.
[10]
solve1( true ).
solve1(( Goal1, Goal2 ))
:-
solve1( Goal )
:-
solve2( true ).
solve2(( Goal1, Goal2 ))
:-
solve2( Goal )
:-
solve1(
solve1(
clause(
solve1(
Goal1 ),
Goal2 ).
Goal, Next ),
Next ).
solve2(
solve2(
clause(
solve2(
Goal2 ),
Goal1 ).
Goal, Next ),
Next ).
% Cl. 1
% Cl. 2
% Cl. 3
% Cl. A
% Cl. B
% Cl. C
p( X, Y ) :- q( X, Y ), r( Y ).
q( a, b ).
r( b ).
?- solve( p( a, T ) ).
IS53020A (CIS335) 2005
5
TURN OVER
Answer: solve1/1 interprets Prolog programs including conjunction using the default
Prolog unification mechanism. It operates on the given query and program as follows.
i. p( a, T ) is matched first against true from Clause 1, which fails; equally, it
cannot match against ( Goal1, Goal2 ), so Clause 3 is the only one that can
match. Goal is unified with p( a, T ).
ii. clause( p( a, T ), Next ) looks for a matching clause in the database and,
as a result, unifies Next with q( a, T ), r( T ). solve1/1 is then applied
to this term.
iii. This time, only Clause 2 will match with the term, so Goal1 is unified with q( a,
T ) and Goal2 is unified with r( T ).
iv. Now, the body of Clause 2 is executed. First, solve1( q( a, T )), is executed.
This can only be handled by Clause 3. A match is found, T is unified with b and Next
is unified with true, because this is a fact and not a rule.
v. true unifies with the argument of Clause 1 of solve1/1, so this branch of the
execution is finished.
vi. Prolog now returns to the second literal of the conjoined goal at 3(c)iv, above. The
sequence for this branch is identical to that for the first literal generated by Clause 2,
above.
vii. Clause 2 is now complete, and there is nothing else to execute, so the run has succeeded, with the instantiation T=b.
(d) Write one or more new clauses for solve1/1 so that the program can handle disjunction using the appropriate Prolog operators. Indicate where your new clause(s) go in the
program. You will not be penalised for minor syntactic errors.
[5]
Answer: solve1( true ).
solve1(( Goal1, Goal2 ))
solve1(( Goal1; Goal2 ))
solve1(( Goal1; Goal2 ))
solve1( Goal )
IS53020A (CIS335) 2005
6
::::-
solve1(
solve1(
solve1(
solve1(
clause(
solve1(
Goal1 ),
Goal2 ).
Goal1 ).
Goal2 ).
Goal, Body ),
Body ).
TURN OVER
4. This question is about Prolog program syntax and execution.
(a) Write down the syntactic categories of the underlined parts of the following items. For
example, in p(X), X is a “variable”. Parts (ii) and (iii) have two possible answers: give
both.
i. p(C,D) :- q(C,E), w(E,D)).
[1]
Answer: Clause body.
ii. X is A + 1
[2]
Answer: Operator or Functor.
iii. X is A + 1
[2]
Answer: Operator or Predicate.
(b) Explain in detail what the following Prolog program does when presented with a fully instantiated list of numbers as its first argument and an uninstantiated variable as its second.
(Hints: understand the select/3 predicate first, and then look at a/2 and b/1 separately; think about which variables will act as inputs and which as outputs as the program
runs; and don’t forget backtracking.)
[20]
t( L, V )
:-
a( L, V ),
b( V ).
a( [], [] ).
a( X, [H|T] )
:-
select( H, X, U ),
a( U, T ).
b( [] ).
b( [ ] ).
b( [X,Y|Z] )
:-
X =< Y,
b( [Y|Z] ).
select( P, [P|Q], Q ).
select( X, [P|Q], [P|R] )
:-
select( X, Q, R ).
Answer: This predicate sorts [2] a list of numbers by permuting it (a/2) and then testing
whether it is in order (b/1) [2]. The permutation predicate, a/2, is backtrackable, and
is able to produce all permutations of a list, and so eventually the sorted answer will be
found. [1]
select/3 unifies its first argument with an element of the list given in its second argument, and returns the remainder of the list in its third; it is backtrackable, and picks a
different element of the input list each time it backtracks. [5]
a/2 works by selecting a member of the list with select/3 and placing it at the beginning of a list which is being constructed recursively. [4] In itself, it is not backtrackable, but it builds a framework in which the backtracking of select/3 is controlled.
IS53020A (CIS335) 2005
7
TURN OVER
Thus, when backtracking happens in a/2, it is deferred into select/3; in this way,
each element of the input list is tried in each position of the list, until b/1 succeeds.
[5]
b/1 works by comparing each member of the list with the one next to it and requiring
them to be in increasing numerical order; otherwise it fails. Having made this comparison, it then recurses, with the higher value still on the front of the list. By this
means it checks whether the list is in increasing numerical order, and fails otherwise.
[5]
IS53020A (CIS335) 2005
8
TURN OVER
5. This question is about cut and negation in Prolog
(a)
i. Explain the function of the Prolog cut operator, !, in terms of both proof tree (you
may presuppose the concept of backtracking) and variable instantiation.
[6]
Answer: Cut is a commit operator. [1] Once Prolog execution has passed through
a cut, it may not backtrack past it, [1] during the current execution of the predicate
in which the cut occurred. [1] This means that any variable instantiations which
have been made before the cut are fixed and may not change subsequently. [1] In
terms of the proof tree, this means that branches which would have been traversed on
backtracking are pruned away, and any answers associated with them are not considered.[2]
ii. What is the difference between “red” and “green” cuts? What useful purpose do
“green” cuts serve?
[3]
Answer: A “green” cut is one which can be removed without changing the logic of the
program; a “red” cut cannot be so removed.[2] “Green” cuts prune away computation
which is logically unnecessary, and so speed up program execution. [1]
(b)
i. Given the notions of success and failure, corresponding with truth and falsehood in
logic, describe the logical meaning of the Negation as Failure (NAF) operation in
Prolog.
[3]
Answer: Under negation as failure, the negation of literal, P, succeeds (is true) if and
only if P fails (is false).
ii. What is floundering?
[3]
Answer: Floundering is the production of incorrect answers by a program, due to the
incorrect instantiation of variables under negation as failure.
iii. Give a detailed example of how floundering can happen.
[10]
Answer: Consider the query ?- \+ X=2, X=5. [2] This query should succeed,
with 5 as the value of X, but in fact fails. [2] The failure happens because the negated
literal is executed before the value of 5 is unified with X. So to prove \+ X=2, Prolog
first attempts to prove X=2; this succeeds, unifying X with 2, so the negated literal
fails, and so the whole query fails, incorrectly.[3] If, on the other hand, the query were
presented the other way round, thus: ?- X=5, \+ X=2., the first literal would
result in the unification of X with 5. Then, when the negated literal is called, the literal
itself, 2=5, is false, so the negation succeeds, and the correct output is achieved. [3]
IS53020A (CIS335) 2005
9
LAST PAGE