|Did you know ...||Search Documentation:|
|Debugging and declaring determinism|
A common issue with Prolog programs of a procedural nature is to guarantee deterministic behaviour and debug possible problems with determinism. SWI-Prolog provides several mechanisms to make writing, debugging and maintaining deterministic code easier. One of them is Single Sided Unification using =>/2 rules as described in section 5.6. This section deals with annotating your program.
WARNING: The primitives in this section are experimental. The naming and exact semantics may change. If you are interested in this, please follow and contribute to discussion on the Discourse forum.
det, deterministic. As a result, both failure and success with a choicepoint is considered an error. The behaviour if the declaration is violated is controlled with the Prolog flag determinism_error. The default is to raise an exception (
error). Consider the following program:
:- det(p/1). p(1). p(2).
Now, a call
?- p(1). behaves normally. However:
?- p(X). ERROR: Deterministic procedure p/1 succeeded with a choicepoint ERROR: In: ERROR:  p(1) ?- p(a). ERROR: Deterministic procedure p/1 failed ERROR: In: ERROR:  p(a)
Note that if $/1 is
used for the last call, last call optimization is not effective. This
behaviour ensures consistent errors or warnings. Last call optimization
with determinism checking can be realised using
..., $, Last.,
i.e. by executing
$/0 before the last call
rather than wrapping the last call in $/1.
A deterministic predicate may call normal predicates. No error is triggered as long as the deterministic predicate either ignores a possible failure, e.g., using \+/1 and prunes possible choice points created by called predicates. If the last predicate is a normal predicate the requirement to succeed deterministically is transferred to the new goal. As last-call optimization causes the information which predicate initially claimed to be deterministic to be lost, the error is associated with the called predicate. Debug mode (see debug/0 or the Prolog flag debug) may be used to avoid last call optimization and find the call stack that causes the issue.