Knowing when to use cut in prolog - prolog

I've took a course in which I learned some prolog. I couldn't figure out how / when to use cuts. Even though I get the general idea of cuts, I can't seem to use them properly.
Can anyone explain it briefly or give a good tutorial (that's not learnprolognow.org) on "cuts" that they can recommend?

TL;DR: Don't.
The cut prunes Prolog's search tree. That is, given a pure Prolog program without cut and the same program with cuts the only difference is that the program with cuts might spend less time in fruitless branches, and thus is more efficient ; might have fewer answers ; it might also terminate whereas the original program doesn't.
Sounds pretty harmless ... or even useful, doesn't it?
Well, most of the time things are more complex.
Red cuts
Cuts are often used in a way such that the program without cuts has no sensible meaning at all. Such cuts are called red cuts. In the better cases it is used to implement a crude form of non-monotonic negation. And in some other cases it is half negation, half some procedural meaning that is very difficult to understand. Not only for the reader of the program but also for its writer. In fact, often such uses unintentionally lack steadfastness. In any case: these cuts are not placed into an existing program. They are meant to be in that program right from the beginning.
For the more structured uses of such red cuts, better use once/1, (\+)/1, or (;)/2 – if-then-else like ( If -> Then ; Else ) instead. Even better, try to guard such constructs against unintended uses by issuing instantiation_errors. Or use iwhen/2 which produces instantiation errors or when/2 (offered in SWI, YAP, SICStus) which delays goals.
Green cuts
Cuts that remove useless choicepoints (and also redundant answers) are called green cuts. But beware: You cannot place them into your program simply pressing ! and some #00ff00. Most of the time you need a clean read-only guard to ensure that there is no way this cut turns #ff0000. There is also a simple way to remove some leftover choicepoints safely: call_semidet/1. Here are some related cases:
What's the SLD tree for this query?
Prolog append with cut operator
What are the optimal green cuts for successor arithmetics sum?
Implementing "last" in Prolog
Cut is not commit
Finally, let me point out that cut is not a commit-operator. It sometimes acts a bit like it, but would need lots of restrictions to be one. A commit-operator cannot be (ab)used to implement (\+)/1. A commit requires that each clause is tried independently of each other. Each clause thus needs a full guard ; it cannot rely on being tried only after some other clauses have been tried first. Also, a commit would have to occur in each clause of a predicate. The cut can occur anywhere.

A cut commits the Prolog goal being proved to the choices done.
It must be used then when the programmer knows that any alternative available must not be tried.
The most prominent use it's the implementation of negation by failure.
fact(a).
fact(b).
/* 1 */ neg(X) :- call(X), !, fail.
/* 2 */ neg(_).
Here I've (re)defined the standard negation operator, normally it's (\+)/1
?- neg(fact(c)).
true.
call(fact(c)) by rule 1 can't be proved, and the alternative rule 2 then succeeds.
?- neg(fact(a)).
false.
because fact(a) can be proved, the cut discard the alternative before failing.
?- neg(fact(X)).
false.
there exist at least an unknown X such that fact(X) succeed.
?- neg(neg(fact(X))).
true.
the double negation has the effect that variables don't get bound. This can be useful when doing meta programming, to fetch clauses without altering their 'structure'. From the operational viewpoint, it's clear (?) what's going on, but the program does lose its declarative property.
Another use, useful only in rudimentary interpreters, was to instruct the system to perform last call optimization, prefixing the recursive call with a cut. Then the system can avoid to allocate the stack space normally required to keep track of alternative point. A dummy example:
print_list([E|Es]) :- print_element(E), !, print_list(Es).
print_list([]).
edit about a tutorial: I found that 'Clause and Effect' by William Clocksin contains a detailed survey related to cut: chapter 4 'Choice and Commitment' it's fully devoted to cut pros and cons. At bottom line, mainly cons...

Before using a cut, I require that my predicates meet these two criteria:
it gives correct answers without a cut
it gives correct answers if clauses are reordered
Once my predicate behaves that way, I sometimes add a cut to trim away unwanted nondeterminism.
For example, a predicate to test whether a number is positive, negative or zero.
sign(N, positive) :-
N > 0.
sign(N, negative) :-
N < 0.
sign(N, zero) :-
N =:= 0.
Each clause stands completely independent of the others. I can reorder these clauses or remove a clause and the remaining clauses still give the expected answer. In this case, I might put a cut at the end of the positive and negative clauses just to tell the Prolog system that it won't find any more solutions by examining the other clauses.
One could write a similar predicate without cut by using -> ;, but some dislike how it looks:
sign(N, Sign) :-
( N > 0 -> Sign=positive
; N < 0 -> Sign=negative
; Sign=zero
).

Cuts all but disappeared from my code once I found the once predicate. Internally it acts like
once(X) :- X, !.
and I found it very useful for making a firm decision on how to do something before I did that something.
For example, here is my standard meta-interpreter. The maybe1/1 clause has unique functors in its arguments so once they known, then the right maybe1/1 can be selected, perfectly.
The job of finding that unique function is given to the maybe0/2 pre-processor that sets Y to a "what to do statement" about X.
Without once, this could would have to be riddled with cuts. E.g. in maybe1, there are three/two different interpretations of X/Y,and or that we need to check in a top down manner. But check it out- no cuts.
maybe(X) :-
once(maybe0(X,Y)), maybe1(Y).
maybe0(true, true).
maybe0((X,Y), (X,Y)).
maybe0((X;Y), or(L)) :- o2l((X;Y),L).
maybe0(X, calls(X)) :- calls(X).
maybe0(X/Y, fact(X/Y)) :- clause(X/_, true).
maybe0(X/Y, rule(X/Y)) :- clause(X/_,_).
maybe0(X/Y, abducible(X/Y)).
maybe0(or([H|T]), or([H|T])).
maybe0(or([]), true).
maybe1(true).
maybe1((X,Y)) :- maybe(X),maybe(Y).
maybe1((X;Y)) :- maybe(X);maybe(Y).
maybe1(abducible(X)) :- assume(X,0).
maybe1(fact(X)) :- assume(X,1), one(X).
maybe1(rule(X)) :- assume(X,2), one(clause(X,Y)), maybe(Y).
maybe1(calls(X)) :- one(clause(X,Y)), maybe(Y).
maybe1(or([H|T])) :- any(One,Rest,[H|T]), ignore(maybe(One)), maybe(or(Rest)).

Cut predicate prevents backtracking.Cut predicate is specified as an exclamation point (!). Cut prunes the search tree and shortens the path track by prolog interpreter.Semantically it always succeed.
read(a).
read(b).
color(p, red) :- red(p).
color(p,black) :- black(p),!.
color(p,unknown).
?-color(X,Y).
X = a,
Y = red;
X = b,
Y = black;
Without cut the goals shows Y=unknown after Y=black.
There are two types of cut predicate :
Green Cut : Green cut is one type of cut which had no effect on the declarative meaning. It is only use to improve efficiency as well as avoid unnecessary computation. The removal of green cut from the program does not changes the meaning of the program.
Red Cut : Red cut is one which had effect on the the declarative meaning. The removal of red cut from the program changes the meaning of the program.

Related

Is it possible to express Prolog's cut in first order logic?

In conversations around Prolog's cut operator !/0, I have only ever heard it described in terms of choice points and Prolog's execution model. It also seems to me that cut was introduced to give more "imperative" control over the search procedure, and to potentially improve the performance of some programs, but not so much for theoretical reasons. For examples of such discussions, see SWI Prolog's documentation, SICStus Prolog's documentation, and the Wikipedia article on cuts.
I'm curious if there are other ways of thinking about cuts in Prolog code? Specifically, can cut be given (possibly messy) declarative semantics in the language of first order logic? Second order logic? Higher order logic? If not, are there extensions to these logics that make it possible to implement cut?
There is no declarative semantics for the cut in the general case. It suffices to consider one counterexample:
?- X = 2, ( X = 1 ; X = 2 ), !.
X = 2.
?- ( X = 1 ; X = 2 ), !, X = 2.
false.
So once it is the case and once not. Therefore, conjunction is not commutative. But to have a declarative semantics, conjunction must be commutative. And even in Pure Prolog commutativity of conjunction holds1. So maybe there is some way to twist the meaning of declarative. But twisting it that far is just too much.
The only statement we can say is that in a program with cuts the search space is somehow pruned compared to the very same program without cuts. But usually that is not that interesting. Think of Prolog negation.
mynot(G_0) :-
G_0,
!,
false.
mynot(_G_0).
So this is compared to its cut free version where the fact will always ensure success. The meaning of negation is therefore lost in the cut free program.
However, some uses of cuts do have a declarative semantics. But those cuts are typically guarded to ensure that it does not cut too often. These guards may come in different styles. One possibility is to produce an instantiation error in case the arguments are not sufficiently instantiated. Another is to fail and resort to the original definition. Another is to ensure that arguments are sufficiently instantiated by some mode system. As long as such mode system is actually enforced it is a declarative option. However, if modes are only commentary decorum, the declarative meaning is lost.
1 Conjunction in Pure Prolog is commutative modulo termination and errors.
"Purely for performance"?
Cuts are convenient, as a sometimes-more-elegant alternative to if-then-else.

Is it possible to write a prolog interpreter that avoids infinite recursion?

Main features
I recently have been looking to make a Prolog meta-interpreter with a certain set of features, but I am starting to see that I don't have the theoretical knowledge to work on it.
The features are as follows :
Depth-first search.
Interprets any non-recursive Prolog program the same way a classic interpreter would.
Guarantees breaking out of any infinite recursion. This most-likely means breaking Turing-completeness, and I'm okay with that.
As long as each step of the recursion reduces the complexity of the expression, keep evaluating it. To be more specific, I want predicates to be allowed to call themselves, but I want to prevent a clause to be able to call a similarly or more complex version of itself.
Obviously, (3) and (4) are the ones I am having problems with. I am not sure if those 2 features are compatible. I am not even sure if there is a way to define complexity such that (4) makes logical sense.
In my researches, I have come across the concept of "unavoidable pattern", which, I believe, provides a way to ensure feature (3), as long as feature (4) has a well-formed definition.
I specifically want to know if this kind of interpreter has been proven impossible, and, if not, if theoretical or concrete work on similar interpreters has been done in the past.
Extra features
Provided the above features are possible to implement, I have extra features I want to add, and would be grateful if you could enlighten me on the feasibility of such features as well :
Systematically characterize and describe those recursions, such that, when one is detected, a user-defined predicate or clause could be called that matches this specific form of recursion.
Detect patterns that result in an exponential number of combinatorial choices, prevent evaluation, and characterize them in the same way as step (5), such that they can be handled by a built-in or user-defined predicate.
Example
Here is a simple predicate that obviously results in infinite recursion in a normal Prolog interpreter in all but the simplest of cases. This interpreter should be able to evaluate it in at most PSPACE (and, I believe, at most P if (6) is possible to implement), while still giving relevant results.
eq(E, E).
eq(E, F):- eq(E,F0), eq(F0,F).
eq(A + B, AR + BR):- eq(A, AR), eq(B, BR).
eq(A + B, B + A).
eq(A * B, B * A).
eq((A * B) / B, A).
eq(E, R):- eq(R, E).
Example of results expected :
?- eq((a + c) + b, b + (c + a)).
true.
?- eq(a, (a * b) / C).
C = b.
The fact that this kind of interpreter might prove useful by the provided example hints me towards the fact that such an interpreter is probably impossible, but, if it is, I would like to be able to understand what makes it impossible (for example, does (3) + (4) reduce to the halting problem? is (6) NP?).
If you want to guarantee termination you can conservatively assume any input goal is nonterminating until proven otherwise, using a decidable proof procedure. Basically, define some small class of goals which you know halt, and expand it over time with clever ideas.
Here are three examples, which guarantee or force three different kinds of termination respectively (also see the Power of Prolog chapter on termination):
existential-existential: at least one answer is reached before potentially diverging
universal-existential: no branches diverge but there may be an infinite number of them, so the goal may not be universally terminating
universal-universal: after a finite number of steps, every answer will be reached, so in particular there must be a finite number of answers
In the following, halts(Goal) is assumed to correctly test a goal for existential-existential termination.
Existential-Existential
This uses halts/1 to prove existential termination of a modest class of goals. The current evaluator eval/1 just falls back to the underlying engine:
halts(halts(_)).
eval(Input) :- Input.
:- \+ \+ halts(halts(eval(_))).
safe_eval(Input) :-
halts(eval(Input)),
eval(Input).
?- eval((repeat, false)).
C-c C-cAction (h for help) ? a
abort
% Execution Aborted
?- safe_eval((repeat, false)).
false.
The optional but highly recommended goal directive \+ \+ halts(halts(eval(_))) ensures that halts will always halt when run on eval applied to anything.
The advantage of splitting the problem into a termination checker and an evaluator is that the two are decoupled: you can use any evaluation strategy you want. halts can be gradually augmented with more advanced methods to expand the class of allowed goals, which frees up eval to do the same, e.g. clause reordering based on static/runtime mode analysis, propagating failure, etc. eval can itself expand the class of allowed goals by improving termination properties which are understood by halts.
One caveat - inputs which use meta-logical predicates like var/1 could subvert the goal directive. Maybe just disallow such predicates at first, and again relax the restriction over time as you discover safe patterns of use.
Universal-Existential
This example uses a meta-interpreter, adapted from the Power of Prolog chapter on meta-interpreters, to prune off branches which can't be proven to existentially terminate:
eval(true).
eval((A,B)) :- eval(A), eval(B).
eval((A;_)) :- halts(eval(A)), eval(A).
eval((_;B)) :- halts(eval(B)), eval(B).
eval(g(Head)) :-
clause(Head, Body),
halts(eval(Body)),
eval(Body).
So here we're destroying branches, rather than refusing to evaluate the goal.
For improved efficiency, you could start by naively evaluating the input goal and building up per-branch sets of visited clause bodies (using e.g. clause/3), and only invoke halts when you are about to revisit a clause in the same branch.
Universal-Universal
The above meta-interpreter rules out at least all the diverging branches, but may still have an infinite number of individually terminating branches. If we want to ensure universal termination we can again do everything before entering eval, as in the existential-existential variation:
...
:- \+ \+ halts(halts(\+ \+ eval(_))).
...
safe_eval(Input) :-
halts(\+ \+ eval(Input)),
eval(Input).
So we're just adding in universal quantification.
One interesting thing you could try is running halts itself using eval. This could yield speedups, better termination properties, or qualitatively new capabilities, but would of course require the goal directive and halts to be written according to eval's semantics. E.g. if you remove double negations then \+ \+ would not universally quantify, and if you propagate false or otherwise don't conform to the default left-to-right strategy then the (goal, false) test for universal termination (PoP chapter on termination) also would not work.

misconception about how prolog works

So I am currently learning prolog and I can't get my head around how this language works.
"It tries all the possible solutions until it finds one, if it doesn't it returns false" is what I've read that this language does. You just Describe the solution and it finds it for you
With that in mind, I am trying to solve the 8 queens problem ( how to place 8 queens on a chess board without anyone threatening the others).
I have this predicate, 'safe' that gets a list of pairs, the positions of all the queens and succeeds when they are not threatening each other.
When I enter in the terminal
?- safe([(1,2),(3,5)]).
true ?
| ?- safe([(1,3),(1,7)]).
no
| ?- safe([(2,2),(3,3)]).
no
| ?- safe([(2,2),(3,4),(8,7)]).
true ?
it recognizes the correct from the wrong answers, so it knows if something is a possible solution
BUT
when I enter
| ?- safe(L).
L = [] ? ;
L = [_] ? ;
it gives me the default answers, even though it recognizes a solution for 2 queens when I enter them.
here is my code
threatens((_,Row),(_,Row)).
threatens((Column,_),(Column,_)).
threatens((Column1,Row1),(Column2,Row2)) :-
Diff1 is Column1 - Row1,
Diff2 is Column2 - Row2,
abs(Diff1) =:= abs(Diff2).
safe([]).
safe([_]).
safe([A,B|T]) :-
\+ threatens(A,B),
safe([A|T]),
safe(T).
One solution I found to the problem is to create predicates 'position' and modify the 'safe' one
possition((0,0)).
possition((1,0)).
...
...
possition((6,7)).
possition((7,7)).
safe([A,B|T]) :-
possition(A),
possition(B),
\+ threatens(A,B),
safe([A|T]),
safe(T).
safe(L,X):-
length(L,X),
safe(L).
but this is just stupid, as you have to type everything explicitly and really really slow,
even for 6 queens.
My real problem here, is not with the code itself but with prolog, I am trying to think in prolog, But all I read is
Describe how the solution would look like and let it work out what is would be
Well that's what I have been doing but it does not seem to work,
Could somebody point me to some resources that don't teach you the semantics but how to think in prolog
Thank you
but this is just stupid, as you have to type everything explicitly and really really slow, even for 6 queens.
Regarding listing the positions, the two coordinates are independent, so you could write something like:
position((X, Y)) :-
coordinate(X),
coordinate(Y).
coordinate(1).
coordinate(2).
...
coordinate(8).
This is already much less typing. It's even simpler if your Prolog has a between/3 predicate:
coordinate(X) :-
between(1, 8, X).
Regarding the predicate being very slow, this is because you are asking it to do too much duplicate work:
safe([A,B|T]) :-
...
safe([A|T]),
safe(T).
Once you know that [A|T] is safe, T must be safe as well. You can remove the last goal and will get an exponential speedup.
Describe how the solution would look like and let it work out what is
would be
demands that the AI be very strong in general. We are not there yet.
You are on the right track though. Prolog essentially works by enumerating possible solutions and testing them, rejecting those that don't fit the conditions encoded in the program. The skill resides in performing a "good enumeration" (traversing the domain in certain ways, exploiting domain symmetries and overlaps etc) and subsequent "fast rejection" (quickly throwing away whole sectors of the search space as not promising). The basic pattern:
findstuff(X) :- generate(X),test(X).
And evidently the program must first generate X before it can test X, which may not be always evident to beginners.
Logic-wise,
findstuff(X) :- x_fulfills_test_conditions(X),x_fullfills_domain_conditions(X).
which is really another way of writing
findstuff(X) :- test(X),generate(X).
would be the same, but for Prolog, as a concrete implementation, there would be nothing to work with.
That X in the program always stands for a particular value (which may be uninstantiated at a given moment, but becomes more and more instantiated going "to the right"). Unlike in logic, where the X really stands for an unknown object onto which we pile constraints until -ideally- we can resolve X to a set of concrete values by applying a lot of thinking to reformulate constraints.
Which brings us the the approach of "Constraint Logic Programming (over finite domains)", aka CLP(FD) which is far more elegant and nearer what's going on when thinking mathematically or actually doing theorem proving, see here:
https://en.wikipedia.org/wiki/Constraint_logic_programming
and the ECLiPSe logic programming system
http://eclipseclp.org/
and
https://www.metalevel.at/prolog/clpz
https://github.com/triska/clpfd/blob/master/n_queens.pl
N-Queens in Prolog on YouTube. as a must-watch
This is still technically Prolog (in fact, implemented on top of Prolog) but allows you to work on a more abstract level than raw generate-and-test.
Prolog is radically different in its approach to computing.
Arithmetic often is not required at all. But the complexity inherent in a solution to a problem show up in some place, where we control how relevant information are related.
place_queen(I,[I|_],[I|_],[I|_]).
place_queen(I,[_|Cs],[_|Us],[_|Ds]):-place_queen(I,Cs,Us,Ds).
place_queens([],_,_,_).
place_queens([I|Is],Cs,Us,[_|Ds]):-
place_queens(Is,Cs,[_|Us],Ds),
place_queen(I,Cs,Us,Ds).
gen_places([],[]).
gen_places([_|Qs],[_|Ps]):-gen_places(Qs,Ps).
qs(Qs,Ps):-gen_places(Qs,Ps),place_queens(Qs,Ps,_,_).
goal(Ps):-qs([0,1,2,3,4,5,6,7,8,9,10,11],Ps).
No arithmetic at all, columns/rows are encoded in a clever choice of symbols (the numbers indeed are just that, identifiers), diagonals in two additional arguments.
The whole program just requires a (very) small subset of Prolog, namely a pure 2-clauses interpreter.
If you take the time to understand what place_queens/4 does (operationally, maybe, if you have above average attention capabilities), you'll gain a deeper understanding of what (pure) Prolog actually computes.

Making "deterministic success" of Prolog goals explicit

The matter of deterministic success of some Prolog goal has turned up time and again in—at least—the following questions:
Reification of term equality/inequality
Intersection and union of 2 lists
Remove duplicates in list (Prolog)
Prolog: How can I implement the sum of squares of two largest numbers out of three?
Ordering lists with constraint logic programming)
Different methods were used (e.g., provoking certain resource errors, or looking closely at the exact answers given by the Prolog toplevel), but they all appear somewhat ad-hack to me.
I'm looking for a generic, portable, and ISO-conformant way to find out if the execution of some Prolog goal (which succeeded) left some choice-point(s) behind. Some meta predicate, maybe?
Could you please hint me in the right direction? Thank you in advance!
Good news everyone: setup_call_cleanup/3 (currently a draft proposal for ISO) lets you do that in a quite portable and beautiful way.
See the example:
setup_call_cleanup(true, (X=1;X=2), Det=yes)
succeeds with Det == yes when there are no more choice points left.
EDIT: Let me illustrate the awesomeness of this construct, or rather of the very closely related predicate call_cleanup/2, with a simple example:
In the excellent CLP(B) documentation of SICStus Prolog, we find in the description of labeling/1 a very strong guarantee:
Enumerates all solutions by backtracking, but creates choicepoints only if necessary.
This is really a strong guarantee, and at first it may be hard to believe that it always holds. Luckily for us, it is extremely easy to formulate and generate systematic test cases in Prolog to verify such properties, in essence using the Prolog system to test itself.
We start with systematically describing what a Boolean expression looks like in CLP(B):
:- use_module(library(clpb)).
:- use_module(library(lists)).
sat(_) --> [].
sat(a) --> [].
sat(~_) --> [].
sat(X+Y) --> [_], sat(X), sat(Y).
sat(X#Y) --> [_], sat(X), sat(Y).
There are in fact many more cases, but let us restrict ourselves to the above subset of CLP(B) expressions for now.
Why am I using a DCG for this? Because it lets me conveniently describe (a subset of) all Boolean expressions of specific depth, and thus fairly enumerate them all. For example:
?- length(Ls, _), phrase(sat(Sat), Ls).
Ls = [] ;
Ls = [],
Sat = a ;
Ls = [],
Sat = ~_G475 ;
Ls = [_G475],
Sat = _G478+_G479 .
Thus, I am using the DCG only to denote how many available "tokens" have already been consumed when generating expressions, limiting the total depth of the resulting expressions.
Next, we need a small auxiliary predicate labeling_nondet/1, which acts exactly as labeling/1, but is only true if a choice-point still remains. This is where call_cleanup/2 comes in:
labeling_nondet(Vs) :-
dif(Det, true),
call_cleanup(labeling(Vs), Det=true).
Our test case (and by this, we actually mean an infinite sequence of small test cases, which we can very conveniently describe with Prolog) now aims to verify the above property, i.e.:
If there is a choice-point, then there is a further solution.
In other words:
The set of solutions of labeling_nondet/1 is a proper subset of that of labeling/1.
Let us thus describe what a counterexample of the above property looks like:
counterexample(Sat) :-
length(Ls, _),
phrase(sat(Sat), Ls),
term_variables(Sat, Vs),
sat(Sat),
setof(Vs, labeling_nondet(Vs), Sols),
setof(Vs, labeling(Vs), Sols).
And now we use this executable specification in order to find such a counterexample. If the solver works as documented, then we will never find a counterexample. But in this case, we immediately get:
| ?- counterexample(Sat).
Sat = a+ ~_A,
sat(_A=:=_B*a) ? ;
So in fact the property does not hold. Broken down to the essence, although no more solutions remain in the following query, Det is not unified with true:
| ?- sat(a + ~X), call_cleanup(labeling([X]), Det=true).
X = 0 ? ;
no
In SWI-Prolog, the superfluous choice-point is obvious:
?- sat(a + ~X), labeling([X]).
X = 0 ;
false.
I am not giving this example to criticize the behaviour of either SICStus Prolog or SWI: Nobody really cares whether or not a superfluous choice-point is left in labeling/1, least of all in an artificial example that involves universally quantified variables (which is atypical for tasks in which one uses labeling/1).
I am giving this example to show how nicely and conveniently guarantees that are documented and intended can be tested with such powerful inspection predicates...
... assuming that implementors are interested to standardize their efforts, so that these predicates actually work the same way across different implementations! The attentive reader will have noticed that the search for counterexamples produces quite different results when used in SWI-Prolog.
In an unexpected turn of events, the above test case has found a discrepancy in the call_cleanup/2 implementations of SWI-Prolog and SICStus. In SWI-Prolog (7.3.11):
?- dif(Det, true), call_cleanup(true, Det=true).
dif(Det, true).
?- call_cleanup(true, Det=true), dif(Det, true).
false.
whereas both queries fail in SICStus Prolog (4.3.2).
This is the quite typical case: Once you are interested in testing a specific property, you find many obstacles that are in the way of testing the actual property.
In the ISO draft proposal, we see:
Failure of [the cleanup goal] is ignored.
In the SICStus documentation of call_cleanup/2, we see:
Cleanup succeeds determinately after performing some side-effect; otherwise, unexpected behavior may result.
And in the SWI variant, we see:
Success or failure of Cleanup is ignored
Thus, for portability, we should actually write labeling_nondet/1 as:
labeling_nondet(Vs) :-
call_cleanup(labeling(Vs), Det=true),
dif(Det, true).
There is no guarantee in setup_call_cleanup/3 that it detects determinism, i.e. missing choice points in the success of a goal. The 7.8.11.1 Description draft proposal only says:
c) The cleanup handler is called exactly once; no later than
upon failure of G. Earlier moments are:
If G is true or false, C is called at an implementation
dependent moment after the last solution and after the last
observable effect of G.
So there is currently no requirement that:
setup_call_cleanup(true, true, Det=true)
Returns Det=true in the first place. This is also reflected in the test cases 7.8.11.4 Examples that the draf proposal gives, we find one test case which says:
setup_call_cleanup(true, true, X = 2).
Either: Succeeds, unifying X = 2.
Or: Succeeds.
So its both a valid implementation, to detect determinism and not to detect determinism.

What are the uses of the fail predicate in Prolog?

I can't come up with a situation where I would need it.
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. :)
fail/0 is a special symbol that will immediately fail when prolog encounters it as a goal.
fail is often used in conjunction with CUT(!) to enforce failure.
like(me,X) :- chess(X),!,fail.
like(me,X) :- games(X).

Resources