Node:Control, Next:, Previous:Term Compare, Up:Built Intro

### Control

`+P , +Q ISO`

P and Q.

`+P ; +Q ISO`

P or Q.

`! ISO`

See Cut.

`\+ +P ISO`

Fails if the goal P has a solution, and succeeds otherwise. This is not real negation ("P is false"), but a kind of pseudo-negation meaning "P is not provable". It is defined as if by

```\+(P) :- P, !, fail.
\+(_).
```

In `sicstus` execution mode no cuts are allowed in P. In `iso` execution mode cuts are allowed in P and their scope is the goal P.

Remember that with prefix operators such as this one it is necessary to be careful about spaces if the argument starts with a `(`. For example:

```| ?- \+ (P,Q).
```

is this operator applied to the conjunction of P and Q, but

```| ?- \+(P,Q).
```

would require a predicate `\+ /2` for its solution. The prefix operator can however be written as a functor of one argument; thus

```| ?- \+((P,Q)).
```

is also correct.

`+P -> +Q ; +R ISO`

Analogous to

```if P then Q else R
```

and defined as if by

```(P -> Q; R) :- P, !, Q.
(P -> Q; R) :- R.
```

except the scope of any cut in Q or R extends beyond the if-then-else construct. In `sicstus` execution mode no cuts are allowed in P. In `iso` execution mode cuts are allowed in P and their scope is the goal P.

Note that this form of if-then-else only explores the first solution to the goal P.

Note also that the `;` is not read as a disjunction operator in this case; instead, it is part of the if-then-else construction.

The precedence of `->` is less than that of `;` (see Operators), so the expression is read as

```;(->(P,Q),R)
```

`+P -> +Q ISO`

When occurring as a goal, this construction is read as equivalent to

```(P -> Q; fail)
```

`if(+P,+Q,+R)`

Analogous to

```if P then Q else R
```

but differs from `P -> Q ; R` in that `if(P, Q, R)` explores all solutions to the goal P. There is a small time penalty for this--if P is known to have only one solution of interest, the form `P -> Q ; R` should be preferred.

In `sicstus` execution mode no cuts are allowed in P. In `iso` execution mode cuts are allowed in P and their scope is the goal P.

`once(+P) ISO`

Finds the first solution, if any, of goal P. Fails if no solutions are found. Will not explore further solutions on backtracking. Equivalent to

```(P -> true; fail)
```

`otherwise`
`true ISO`

These always succeed. Use of `otherwise/0` is discouraged, because it is not as portable as `true/0`, and because the former may suggest a completely different semantics than the latter.

`false`
`fail ISO`

These always fail. Use of `false/0` is discouraged, because it is not as portable as `fail/0`, and because the latter has a more procedural flavor to it.

`repeat ISO`

Generates an infinite sequence of backtracking choices. In sensible code, `repeat/0` is hardly ever used except in repeat loops. A repeat loop has the structure

```Head :-
...
save_state(OldState),
repeat,
generate(Datum),
action(Datum),
test(Datum),
!,
restore_state(OldState),
...
```

The purpose is to repeatedly perform some action on elements that are somehow generated, e.g. by reading them from a stream, until some test becomes true. Usually, generate, action, and test are all determinate. Repeat loops cannot contribute to the logic of the program. They are only meaningful if the action involves side-effects.

The only reason for using repeat loops instead of a more natural tail-recursive formulation is efficiency: when the test fails back, the Prolog engine immediately reclaims any working storage consumed since the call to `repeat/0`.

`call(:Term) ISO`
`incore(:Term) obsolescent`
`:Term`

If Term is instantiated to a term that would be acceptable as the body of a clause, then the goal `call(Term)` is executed exactly as if that term appeared textually in its place, except that any cut (`!`) occurring in Term only cuts alternatives in the execution of Term. Use of `incore/1` is not recommended.

If Term is not instantiated as described above, an error message is printed and the call fails.

`call_cleanup(:Goal,:Cleanup)`

This construction can be used to ensure that Cleanup is executed as soon as Goal has completed execution, no matter how it finishes. In more detail:

When `call_cleanup/2` with a continuation C is called or backtracked into, first Goal is called or backtracked into. Then there are four possibilities:

1. Goal succeeds determinately, possibly leaving some blocked subgoals. Cleanup is executed with continuation C.
2. Goal succeeds with some alternatives outstanding. Execution proceeds to C. If a cut that removes the outstanding alternatives is encountered, Cleanup is executed with continuation to proceed after the cut. Also, if an exception E that will be caught by an ancestor of the `call_cleanup/2` Goal is raised, Cleanup is executed with continuation `raise_exception(E)`.
3. Goal fails. Cleanup is executed with continuation `fail`.
4. Goal raises an exception E. Cleanup is executed with continuation `raise_exception(E)`.

In a typical use of `call_cleanup/2`, Cleanup succeeds determinately after performing some side-effect; otherwise, unexpected behavior may result.

Note that the Prolog top-level operates as a read-execute-fail loop, which backtracks into or cuts the query when the user types ; or <RET> respectively. Also, the predicates `halt/0` and `abort/0` are implemented in terms of exceptions. All of these circumstances can trigger the execution of Cleanup.