Programs that make use of cut (!) are most of the time
sensitive to the ordering of goals and clauses in their
meaning and not only in their termination, so they are
often not declarative.
The negation as failure (\+) ecapsulates in a certain way
the cut. It is defined and even implemented by most Prolog
systems as follows:
\+ X :- X, !, fail.
\+ _ .
Although it hints a logical meaning and thus declarativity,
the negation as failure is still sensitive to ordering of
goals. Here is an example. Assume we have the following
database:
p(a).
q(b,c).
Then the following query produces X=a as a solution:
?- p(X), \+ q(X,Y).
X = a.
But if the arguments of the conjunction (,)/2 switch side,
a different result is obtained:
?- \+ q(X,Y), p(X).
false.
Ergo, negation as failure is not declarative per se. For
ground term flow of arguments, negation as failure sneeks
in an existential quantifiers. So a query of the form:
?- A(X), \+ B(X,Y).
Has essentially the meaning that it quantifies the fresh
variables Y inside the negation:
?- A(X), ~ exists Y B(X,Y).
So in the above example where conjunction is switched, the
set of fresh variables in the negation as failure changes, thats
why different solutions are obtained.
Bye