I can't come up with a situation where I would need it.
A Prolog program consists of predicate definitions. A predicate denotes a property or relationship between objects. Definitions consist of clauses. A clause has a head and a body (Rule) or just a head (Fact).
While backtracking or 'standard' evaluation left-to-right, the fail predicate always fails, as the name implies. We can take advantage of this by combining it with Prolog's automatic backtracking to find all the clauses in the database with a specified property.
To cut or not to cut - Negation The negation predicate in prolog is \+ and therefore \+ round(earth) returns true. This limitation of prolog that is a goal cannot be proved then it is false, is called the close world assumption (CWA).
Because of the problems of negation-as-failure, negation in Prolog is represented in modern Prolog interpreters using the symbol \+ , which is supposed to be a mnemonic for not provable with the \ standing for not and the + for provable.
Elegant systems provide false/0
as a declarative synonym for the imperative fail/0
. An example where it is useful is when you manually want to force backtracking for side-effects, like:
?- between(1,3,N), format("line ~w\n", [N]), false.
line 1
line 2
line 3
Instead of false/0
, you can also use any goal that fails, for example a bit shorter:
?- between(1,3,N), format("line ~w\n", [N]), 0=1.
line 1
line 2
line 3
Thus, false/0
is not strictly needed but quite nice.
EDIT: I sometimes see beginners who want to state for example "my relation does not hold for the empty list", and then add:
my_relation([]) :- false.
to their code. This is not necessary, and not a good example of using false/0
, except for example in failure slices that are programmatically generated. Instead, concentrate on stating the things that hold about your relation. In this case, just leave out the entire clause, and define the relation only for lists that are not empty, i.e., have at least one element:
my_relation([L|Ls]) :- etc.
or, if you are describing other terms in addition to lists as well, use a constraint like:
my_relation(T) :- dif(T, []), etc.
Given only either (or even both) of these two clauses, the query ?- my_relation([]).
will automatically fail. It is not necessary to introduce an additional clause which never succeeds for that purpose.
Explicit failure. fail
is often used in conjunction with cut: ... !, fail.
to enforce failure.
For all construct. Explicit usage of fail
/false
to enumerate via backtracking is a very error prone activity. Consider a case:
... ( generator(X), action(X), fail ; true ), ...
The idea is thus to "do" action for all X
. But what happens, if action(X)
fails? This construct simply continues with the next candidate — as if nothing happened. In this manner certain errors may remain undetected for very long.
For such cases it is better to use \+ ( generator(X), \+ action(X) )
which fails, should action(X)
fail for some X
. Some systems offer this as a built-in forall/2
. Personally, I prefer to use \+
in this case because the \+
is a bit clearer that the construct does not leave a binding.
Failure-slice. For diagnostic purposes it is often useful to add on purpose false
into your programs. See failure-slice for more details.
One case (taken from Constraint Logic Programming using Eclipse) is an implementation of not/1:
:- op(900, fy, not).
not Q :- Q, !, fail.
not _ .
If Q succeeds, the cut (!) causes the second not clause to be discarded, and the fail ensures a negative result. If Q fails, then the second not clause fires first.
Another use for fail is to force backtracking through alternatives when using predicates with side effects:
writeall(X) :- member(A,X), write(A), fail.
writeall(_).
Some people might not consider this particularly good programming style though. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With