10.5 Practical Session
The purpose of this session is to help you get familiar with cuts and negation as failure. First some keyboard exercises:
- 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.
- 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 mucks it up by using negation in the wrong place.
Now for some programming:
- 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:
- First (and easiest) write it with the help of = and \+ .
- Second write it with the help of = , but don’t use \+ .
- Third, write it using a cut-fail combination. Don’t use = and don’t use \+ .
- Define a predicate
unifiable(List1,Term,List2)
where
List2
is the list of all members of
List1
that unify with
Term
. The elements of
List2
should
not be instantiated by the unification. 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 unify with t(a) without instantiating them?
(Hint: consider using tests of the form \+ term1 = term2 . Why? Think about it. You might also like to think about tests of the form \+ \+ term1 = term2 .)