## 10.5 Practical Session 10

The purpose of Practical Session 10 is to help you get familiar with cuts and negation as failure.

First some keyboard exercises:

1. First of all, try out all three versions of the `max/3` predicate defined in the text: the cut-free version, the green cut version, and the red cut version. As usual, ``try out'' means ``run traces on'', and you should make sure that you trace queries in which all three arguments are instantiated to integers, and queries where the third argument is given as a variable.

2. OK, time for a burger. Try out all the methods discussed in the text for coping with Vincent's preferences. That is, try out the program that uses a cut-fail combination, the program that uses negation as failure correctly, and also the program that gets it wrong by using negation in the wrong place.

Now for some programming:

1. Define a predicate `nu/2` ("not unifiable") which takes two terms as arguments and succeeds if the two terms do not unify. For example:

`    nu(foo,foo).    no     nu (foo,blob).    yes     nu(foo,X).    no`

You should define this predicate in three different ways:

1. First (and easiest) write it with the help of `=` and `\+`.

2. Second write it with the help of `=`, but don't use `\+`.

3. Third, write it using a cut-fail combination. Don't use = and don't use \+.

2. Define a predicate `unifiable(List1,Term,List2)` where `List2` is the list of all members of `List1` that match `Term `, but are not instantiated by the matching. For example,

`    unifiable([X,b,t(Y)],t(a),List]`

should yield

`    List = [X,t(Y)].`

Note that `X` and `Y` are still not instantiated. So the tricky part is: how do we check that they match with `t(a)` without instantiating them? (Hint: consider using the test `\+ (term1 = term2)`. Why? Think about it. You might also like to think about the test `\+(\+ (term1 = term2))`.)

Patrick Blackburn, Johan Bos and Kristina Striegnitz
Version 1.2.5 (20030212)