You are on page 1of 3

1

Lab 02 – Backtracking, Recursion, Cut and Lists

1. State which of the following pairs of Prolog expressions unify and (if they do) .what the result
of their unification is.
(i) male(X) male(phil)
(ii) parent(X, chas) parent(liz, Y)
(iii) parent(X, chas) parent(liz, X)
(iv) father(mother(bill)) father(Jane)
(v) Mary mother(child(Mary))
(vi) loves(john, _) loves(_, Mary)
(vii) f(X, a(b,c)) f(d, a(Z, c))
(viii) f(X, a(b,c)) f(Z, a(Z, c))
(ix) f(c, a(b,c)) f(Z, a(Z, c)) u
(x) g(Z, f(A, 17, B), A+B, 17) g(C, f(D, D, E), C, E)

(b) For each of the following Prolog unifications, state whether it will succeed, and if so,
what variable instantiation and/or variable sharing will be produced; if it will not succeed,
say (briefly) why.

(i) [X, a, [Y]] = [p, U, [U]].

(ii) [X, a, [Y]] = [Y, a, [Z]].

(iii) [X, a, [X]] = [b, Z, [Z]].

(iv) [X, a, [X]] = [Z, Z, [Z]].

(v) [X, a, [g(X)]] = [Z, a, [Z]].

2. Without using cut, write a predicate split/3 that splits a list of integers into two lists: one
containing the positive ones (and zero), the other containing the negative ones. For example:

split([3,4,-5,-1,0,4,-9],P,N)

should return:

P = [3,4,0,4]

N = [-5,-1,-9].

Then improve this program, without changing its meaning, with the help of cut.
2

3. Write a rule reverselist(X,Y) such that given list X, Y is the result of reversing X. Use
reverselist(X,Y) in queries.
4. Use cuts to write the rule delete_first(E, L, A), which deletes only the first occurrence of
element E from list L, producing answer A. For example:

?- delete_first(a, [b,a,n,a,n,a], A).


A = [b, n, a, n, a] ;
No
5. Write a rule oddeven(X,Y) that Y is set to “odd” if the number of elements in the list X is odd
and Y is set to “even” if the number of elements in the list X is even. Hint you need two sets of
rules (oddeven and oddeven1) each calling the other alternately. Use oddeven(X,Y) in
queries.

6. Consider following set of cities and distance in between.

Dundee -> Glasgow = 130 miles

Edinburgh ->Glasgow = 80 miles

Dundee->Edinburgh = 100 miles

Glasgow->Manchester=300 miles

Manchester->London=300 miles

London->Portsmouth=100 miles

Montreal->Toronto=300 miles

New York->Toronto=250 miles

Cane->Paris=200 miles

Amsterdam->Paris=400 miles

The links are directional, so if A and B are only connected by a single arrow from A -> B, then
there is no way to get from B to A using a direct link.

a. Write out these links using a predicate road(X, Y) which is true if there is a road leading from
X to Y.
Note that the intended interpretation of the road predicate is explicitly that road(X, Y) means
a road from X to Y. Thus, road (a,b) says nothing about how to get from b to a.

b. Now write a rule for road link/2 that is true if there is a road leading from the first argument to
the second.
HINT: your rule will have to be recursive.
3

c. Formulate queries for the following for your database


• What are all the cities that can be reached by a direct road link from Dundee?
• What are all the cities that can be reached by road from Dundee?
• What are all the cities from which you can get to Manchester?
• Use the trace tool to show all the cities between Glasgow and Portsmouth
• Can you get from Dundee to Toronto?

d. Now formulate the distances as a set of clauses using the predicate distance/3 that is true if
there is a direct road link from the first argument to the second with distance given by the third
argument (in miles).

7. Consider the digits: 1234567890. First remove one digit, then swap two adjacent digits and
then insert some number of plus signs between the digits. There is a way to do this so that
the answer to the resulting arithmetic expression is 2004!

Hints:
You should define the digits as a list in your code, i.e. put the fact:
digits([1,2,3,4,5,6,7,8,9,0]) in your program.

You'll have to represent the addition operator by a constant such as plus.


Don't use + as it may confuse Prolog. Also, if the solution (a list containing numbers and one
or more plus signs inserted) gets too long, Prolog may shorten it using the ... notation.
To see the full solution, add a write/1 clause in your program that outputs the solution once
one has been found.
You may need to use the number/1 predicate. This predicate is true if its single argument is a
number. Using number/1 you can differentiate between numbers and the plus operator. Then,
the problem is simplified to:
• Define a predicate that removes an element of a list.
• Define a predicate that swaps adjacent elements of a list.
• Define a predicate that, for each successive pair of numbers in a list, can either add a
plus constant between them or leave that pair unchanged.
• Define a predicate which returns the numeric value of a list that contains numbers and
occurrences of plus, as if it was a numerical expression

There is only one answer to this puzzle!

You might also like