You are on page 1of 3

Logic Programming SuSe 22

Exercise Sheet 7 (due Wednesday, June 22, 2022, 16:00 pm)


Prof.aa
Dr. Jürgen Giesl Nils Lommen and Fabian Meyer

Notes:
• To solve the programming exercises you can use the Prolog interpreter SWI-Prolog, available for free
on this website. For Debian and Ubuntu it suffices to install the swi-prolog package. You can use the
command “swipl” to start it and use “[foo].” to load the clauses from the file foo.pl in the current
directory.
• Please solve these exercises in groups of four!
• Please upload a PDF with your solutions in a ZIP-archive via RWTHmoodle before the exercise course on
Wednesday, June 22, 2022, 16:00 pm. Please name your archive Sheet_i_Mat1_Mat2_Mat3_Mat4.zip,
where i is the number of the sheet and Mat_1. . . Mat_4 are the immatriculation numbers of the group
members in ascending order. Please make sure that only one of the group members uploads your
solution.
• Make sure that your solutions for the programming exercises are accepted by SWI-Prolog. Files which
are not accepted by SWI-Prolog will not be marked.

• The exercise course will take place on Wednesday, June 22, 2022, 16:30 pm in the lecture hall AH 4.

Exercise 1 (Lists): (2 + 1 + 2 + 1 + 1 + 2 + 1 + 1 = 11 points)


In this exercise we investigate algorithms on certain lists in Prolog. Our lists are only allowed to contain
lists as elements. A list can contain arbitrary many lists. For example, [[],[[]]] is such a list, whereas
[[1,2],[3,4]] is not, because the inner lists contain elements that are not lists.
All predicates have to be implemented in Prolog. You may not use any predefined Prolog predicates in
this exercise (unless allowed explicitly)! However, you can define your own auxiliary predicates. In all
subexercises, you may use the predicates of previous subexercises, even if you have not implemented them. In
all subexercises, your program may give the final answer false if the previous answers are correct. However,
error-free termination of the program is mandatory.
The predefined predicate member/2 may be used. It yields the answer true iff the first argument appears
in the list given in the second argument. For example, the query member([],[[]]) returns the only answer
true. The query member(X,[[],[[]]]) returns exactly the two answers X = [] and X = [[]].

a) Implement a predicate lists_not_equal/2 which compares two lists of our form. The predicate should
evaluate to true iff the list given in the first argument is not identical to the list given in the second
argument.

b) Implement a predicate not_member/2 for lists of our form which yields true iff the first argument does
not appear in the list given in the second argument.
c) Implement a predicate remove_duplicates/2 where the list in the second argument results from removing
all duplicates from the list given in the first argument, i.e., it is true iff the second list contains all elements
that appear in the first list (in the same order), but for each element one removes all of its occurrences
except the last one. For example, the query remove_duplicates([[],[[]],[]],XS) returns the only
answer XS = [[[]], []].
d) The lists in this and in the following subexercises are meant to represent sets, i.e., unordered lists without
duplicates. Implement a predicate setify/2 where the list in the second argument results from removing
all duplicates from the list given in the first argument, regarding not only the top level of the list, but
also all of its sublists recursively.
For example, the query setify([[],[]],Set) should return the only answer Set = [[]]. The query
setify([[[],[]],[[],[]]],Set) should return the only answer Set = [[[]]]. The slightly different
query setify([[[],[]],[[]]],Set) should also return the only answer Set = [[[]]].

1
Logic Programming SuSe 22
Exercise Sheet 7 (due Wednesday, June 22, 2022, 16:00 pm)

e) We have already studied the representation of the natural numbers by terms over 0 and s. In the
Zermelo-Fraenkel set theory a natural number n ∈ N is equivalently represented by the unique set
(
∅ if n = 0
n=
{n − 1} ∪ n − 1 otherwise.

For example, we have 0 = ∅, 1 = {∅}, 2 = {{∅}, ∅}, and 3 = {{{∅}, ∅}, {∅}, ∅}. Implement a
predicate zf/2 where zf(N,S) holds iff S is a list of our form which corresponds to the set N for a natural
number N and where the elements in S, and recursively the elements of every element of S, and so on are
in descending order with respect to their cardinality. For example, the query zf(3,S) should return the
only answer S = [[[[]],[]],[[]],[]].
Hints:
• You are allowed to use built-in predicates and built-in functions like +, -, max, etc. on numbers.
f ) Implement a predicate add/3 which computes the sum m + n for two natural numbers m and n in the
representation of the previous task. So add(M,N,R) holds iff M,N,R are lists representing numbers m, n, r
as in the previous task and r = m + n. The query add([[]],[[[[]],[]],[[]],[]],X) results in the
only answer X = [[[[[]],[]],[[]],[]],[[[]], []],[[]],[]], for example.
Hints:
• Write an auxiliary predicate iszf/2, where iszf(N) holds iff N is a list representing a natural
number as in the previous task.
g) Implement a predicate shrink/2 which removes all occurrences of the empty set ([]) from the list in
the first argument to obtain the list in the second argument.
For example, the query shrink([[[]]],XS) should return the only answer XS = [[]] and the query
shrink([[[[]]],[[],[[]]]],XS) should return the only answer XS = [[[]], [[]]].
h) Implement a predicate shrinkdist/2 to compute the shrink distance. It calls the predicate shrink/2
on the list in the first argument recursively until the empty list is reached. The second argument is then
the number of steps necessary for this procedure.
For example, the query shrinkdist([[],[[]]],N) should return the only answer N = 2. This is because
shrink([[],[[]]],XS) returns XS = [[]] and shrink([[]],XS) returns XS = [], which are two steps
until the empty list is reached.
Hints:
• You are allowed to use built-in predicates and built-in functions like +, -, max, etc. on numbers.

Exercise 2 (Equalities): (5 points)


In Prolog there are the following five built-in predicates of arity 2 computing some kind of equality:
• =
• ==
• =:=
• is
• unify_with_occurs_check
For each combination of two of these predicates (i.e., for any p, p' ∈ {=, ==, =:=, is, unify_with_occurs_check}
with p 6= p') and for any terms t, t', answer whether the following implication holds: If the query ?- t p t'
is successful, then the query ?- t p' t' is sucessful as well.
For this, take into account that there are two choices which predicate is first or second (i.e., you have to
consider 20 implications)! Explain why the implication holds or why it does not.

2
Logic Programming SuSe 22
Exercise Sheet 7 (due Wednesday, June 22, 2022, 16:00 pm)

Exercise 3 (Arithmetic Operators): (4 · 1 = 4 points)


In this task you may use the predefined predicates =, is, =:=, the predefined relations <, >, =<, >=, and the
predefined operators + and -. You may also use predicates that you have defined in previous subexercises.
In exercises a) - c) you will have to define new operators. The following table displays the types and the
precedences of some common operators and may help you to choose the precedences of the newly defined
operators correctly.
Precedence Type Operator
1000 yfx ,
700 xfx <, =, =:=, =<, >, >=, is
500 yfx +, -
a) Define a new operator /\ so that for two lists XS and YS, XS /\ YS can be written in Prolog programs
with the semantics that XS /\ YS is true if and only if XS and YS have the same length and the i-th
element of XS is a divisor of the i-th element of YS for all 1 ≤ i ≤ length(XS).
For example, the query ?- [1,6,2] /\ [3,6,8], [1,6,2] /\ [2,12,2] should yield the answer true,
while ?- [1,6,2] /\ [6,3,8] should yield false, because 6 is not a divisor of 3.
Define /\ to be an infix operator and also give clauses so that /\ has the desired semantics. You may
use the predefined operator mod.
b) On natural numbers, we define the powers function as follows:

powers(x, y) = (. . . (x x )x . . .)x
| {z }
y−1 times

For example, we have powers(2, 4) = ((22 )2 )2 = 256.


Please implement this function for non-negative numbers in Prolog by defining ^^ as an infix operator and
by adding clauses so that ^^ behaves like powers. These clauses should have the form ^^(t1 ,t2 ,t3 ) :- . . .
for suitable terms t1 , t2 , t3 . If the first argument t1 is negative or the second argument t2 is non-positive,
then the query ?- ^^(t1 ,t2 ,t3 ) should fail.
Define the type and the precedence of the operator ^^ such that the query X is 3 + 2 ^^ 1 ^^ 2 is
equivalent to the query X is 3 + ((2 ^^ 1) ^^ 2) and returns the answer X = 7. You may use the
predefined operator ^ for exponentiation.
Hints:
• In order to make ^^ behave like an arithmetic function (so that it can be used on the right-hand
side of is), you can use the arithmetic library (:- use_module(library(arithmetic)).) and
write :- arithmetic_function(’^^’/2). at the top of your program after the op-directive.
c) The binomial coefficient nk for n ≥ k is recursively defined by nk = n−1 + k−1 if n > k > 0, n0 = 1,
   n−1 
k
and nn = 1 for all n ∈ N.


Please implement the binomial coefficient for non-negative numbers in Prolog by defining choose as an
infix operator. So choose(N,K,R) holds iff KN
= R. Define the type and the precedence of the operator
choose such that the query X is (3 + 2 ^^ 5 choose 3 choose 2) mod 17 is equivalent to the query
X is (3 + (2 ^^ (5 choose (3 choose 2)))) mod 17 and returns the answer X = 4.
Hints:
• In order to make choose behave like an arithmetic function (so that it can be used on the right-hand
side of is), you can again use the arithmetic library (:- use_module(library(arithmetic)).)
and write :- arithmetic_function(’choose’/2). at the top of your program after the op directive.
d) Use your operator ^^ to implement the predicate powerSym/2 in Prolog such that for a positive number
n, powerSym(n,X) computes all numbers 0 < m ≤ n with powers(n, m) = powers(m, n). For example,
the query powerSym(2,X) should return the answer X = 2 and the query powerSym(4,X) should return
the answers X = 2 and X = 4.

You might also like