## 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).

[ISO]fail
  Always fail. The predicate fail/0 is translated into a single virtual machine instruction.
false
  Same as fail, but the name has a more declarative connotation.
[ISO]true
  Always succeed. The predicate true/0 is translated into a single virtual machine instruction.
[ISO]repeat
  Always succeed, provide an infinite number of choice points.
[ISO]!
  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.32Up 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).