4.7 Control Predicates

The predicates of this section implement control structures. Normally the constructs in this section, except for repeat/0, are translated by the compiler. Please note that complex goals passed as arguments to meta-predicates such as findall/3 below cause the goal to be compiled to a temporary location before execution. It is faster to define a sub-predicate (i.e. one_character_atom/1 in the example below) and make a call to this simple predicate.

one_character_atoms(As) :-
        findall(A, (current_atom(A), atom_length(A, 1)), As).
Always fail. The predicate fail/0 is translated into a single virtual machine instruction.
Always succeed. The predicate true/0 is translated into a single virtual machine instruction.
Always succeed, provide an infinite number of choice points.
Cut. Discard choice points of parent frame and frames created after the parent frame. As of SWI-Prolog 3.3, the semantics of the cut are compliant with the ISO standard. This implies that the cut is transparent to ;/2, ->/2 and *->/2. Cuts appearing in the condition part of ->/2 and *->/2 as well as in \+/1 are local to the condition.29Up to version 4.0.6, the sequence X=!, X acted as a true cut. This feature has been deleted for ISO compliance.

t1 :- (a, !, fail ; b). % cuts a/0 and t1/0
t2 :- (a -> b, ! ; c). % cuts b/0 and t2/0
t3 :- call((a, !, fail ; b)). % cuts a/0
t4 :- \+(a, !, fail ; b). % cuts a/0
[ISO]+Goal1 , +Goal2
Conjunction. True if both `Goal1' and `Goal2' can be proved. It is defined as (this definition does not lead to a loop as the second comma is handled by the compiler):
Goal1, Goal2 :- Goal1, Goal2.
[ISO]+Goal1 ; +Goal2
The `or' predicate is defined as:
Goal1 ; _Goal2 :- Goal1.
_Goal1 ; Goal2 :- Goal2.
+Goal1 | +Goal2
Equivalent to ;/2. Retained for compatibility only. New code should use ;/2.
[ISO]+Condition -> +Action
If-then and If-Then-Else. The ->/2 construct commits to the choices made at its left-hand side, destroying choice-points created inside the clause (by ;/2), or by goals called by this clause. Unlike !/0, the choice-point of the predicate as a whole (due to multiple clauses) is not destroyed. The combination ;/2 and ->/2 acts as if defines by:
If -> Then; _Else :- If, !, Then.
If -> _Then; Else :- !, Else.
If -> Then :- If, !, Then.

Please note that (If -> Then) acts as (If -> Then ; fail), making the construct fail if the condition fails. This unusual semantics is part of the ISO and all de-facto Prolog standards.

+Condition *-> +Action ; +Else
This construct implements the so-called `soft-cut'. The control is defined as follows: If Condition succeeds at least once, the semantics is the same as (Condition, Action). If Condition does not succeed, the semantics is that of (\+ Condition, Else). In other words, If Condition succeeds at least once, simply behave as the conjunction of Condition and Action, otherwise execute Else.

The construct A *-> B, i.e. without an Else branch, is translated as the normal conjunction A, B.bugThe decompiler implemented by clause/2 returns this construct as a normal conjunction too.

[ISO]\+ +Goal
True if `Goal' cannot be proven (mnemonic: + refers to provable and the backslash (\) is normally used to indicate negation in Prolog).