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). |
t1 :- (a, !, fail ; b). | % cuts a/0 and t1/0 |
t2 :- (a -> b, ! ; c). | % cuts b/0 and t2/0 |
t3(G) :- a, G, fail. | % if `G = !' cuts a/0 and t1/1 |
t4(G) :- a, call(G), fail. | % if `G = !' cut has no effect |
t5 :- call((a, !, fail ; b)). | % Cut has no effect |
t6 :- | % cuts a/0 and t6/0 |
Goal1, Goal2 :- Goal1, Goal2. |
Goal1 ; _Goal2 :- Goal1. _Goal1 ; Goal2 :- Goal2. |
If -> Then; _Else :- If, !, Then. If -> _Then; Else :- !, Else. If -> Then :- If, !, Then. |
Note that the operator precedence relation between
and
;
ensure ->
If -> Then ; Else
is actually a term of the form ;(->(If, Then), Else)
.
The first two clauses belong to the definition of ;/2),
while only the last defines
->/2.
+
refers to provable and the backslash (\
)
is normally used to indicate negation).