Concepts of Programming Languages

(Sean Pound) #1
16.7 Deficiencies of Prolog 755

information than positive information. For example, most people have 364
more unbirthdays than they have birthdays.
A simple alternative solution is to state in the goal that X must not be the
same as Y, as in


sibling(X, Y) :- parent(M, X), parent(M, Y), not(X = Y).


In other situations, the solution is not so simple.
The Prolog not operator is satisfied in this case if resolution cannot sat-
isfy the subgoal X = Y. Therefore, if the not succeeds, it does not necessarily
mean that X is not equal to Y; rather, it means that resolution cannot prove
from the database that X is the same as Y. Thus, the Prolog not operator is not
equivalent to a logical NOT operator, in which NOT means that its operand
is provably true. This nonequivalency can lead to a problem if we happen to
have a goal of the form


not(not(some_goal)).


which would be equivalent to


some_goal.


if Prolog’s not operator were a true logical NOT operator. In some cases,
however, they are not the same. For example, consider again the member rules:


member(Element, [Element | ]) :- !.
member(Element, [
| List]) :- member(Element, List).


To discover one of the elements of a given list, we could use the goal


member(X, [mary, fred, barb]).


which would cause X to be instantiated with mary, which would then be
printed. But if we used


not(not(member(X, [mary, fred, barb]))).


the following sequence of events would take place: First, the inner goal would
succeed, instantiating X to mary. Then, Prolog would attempt to satisfy the
next goal:


not(member(X, [mary, fred, barb])).


This statement would fail because member succeeded. When this goal failed,
X would be uninstantiated, because Prolog always uninstantiates all variables
in all goals that fail. Next, Prolog would attempt to satisfy the outer not goal,

Free download pdf