Home Contents Index Summary Previous Next

4.7 Control Predicates

The predicates of this section implement control structures. Normally these constructs are translated into virtual machine instructions by the compiler. It is still necessary to implement these constructs as true predicates to support meta-calls, as demonstrated in the example below. The predicate finds all currently defined atoms of 1 character long. Note that the cut has no effect when called via one of these predicates (see !/0).


one_character_atoms(As) :-
        findall(A, (current_atom(A), atom_length(A, 1)), As).

fail
Always fail. The predicate fail/0 is translated into a single virtual machine instruction.

true
Always succeed. The predicate true/0 is translated into a single virtual machine instruction.

repeat
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. (18)

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

+Goal1 , +Goal2
Conjunction. Succeeds 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.

+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.

+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 choicepoint 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 branche, is translated as the normal conjunction A, B. (19)

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