This section describes a programming interface by means of which new constraints can be written. The interface consists of a set of predicates provided by this library module. Constraints defined in this way can take arbitrary arguments and may use any constraint solving algorithm, provided it makes sense. Reification cannot be expressed in this interface; instead, reification may be achieved by explicitly passing a 0/1-variable to the constraint in question.
Global constraints have state, which may be updated each time the constraint is resumed. The state information may be used e.g. in incremental constraint solving.
The following two predicates are the principal entrypoints for defining and posting new global constraints:
When defining a new constraint, a clause of this predicate must be added. Its body defines a constraint solving method and should always succeed determinately. When a global constraint is called or resumed, the solver will call this predicate to deal with the constraint.
Please note: the constraint is identified by its principal functor; there is no provision for having two constraints with the same name in different modules. It is good practice to include a cut in every clause of
State0 and State are the old and new state respectively.
The constraint solving method must not invoke the constraint solver recursively e.g. by binding variables or posting new constraints; instead, Actions should be unified with a list of requests to the solver. Each request should be of the following form:
Goal is executed as any Prolog goal, but in a context where some constraints may already be enqueued for execution, in which case those constraints will run after the completion of the call request.
Susp is a list of F(Var) terms where Var is a variable to suspend on and F is a functor encoding when to wake up:
Options is a list of zero or more of the following:
fd_copy_term/3, and shown in the answer constraint if
clpfd:full_answerholds, equals Constraint, module name expanded. With this option, the symbolic form will instead be Term. In particular, if Term equals
true, the constraint will not appear in the Body argument of
fd_copy_term/3. This can be useful if you are posting some redundant (implied) constraint.
true(the default), the constraint solving method is assumed to be idempotent. That is, in the scope of
clpfd:dispatch_global/4, the solver will not check for the resumption conditions for the given constraint, while performing its Actions. If
false, an action may well cause the solver to resume the constraint that produced the action.
If a variable occurs more than once in a global constraint that is being posted, or due to a variable-variable unification, the solver will no longer trust the constraint solving method to be idempotent.
For an example of usage, see A Global Constraint Example.
The following predicate controls operational aspects of the constraint solver:
off(the default). For iternal use by