Next: Reflection Predicates, Up: Defining Global Constraints [Contents][Index]
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; see CLPFD Desiderata. Reification cannot be expressed in this interface; instead, reification may be achieved by explicitly passing a Boolean argument to the constraint in question. Integer as well as real variables can be handled.
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:
clpfd:dispatch_global(+Constraint, +State0, -State, -Actions) hook
Tells the solver how to solve constraints of the form Constraint. Defined as a multifile predicate.
When defining a new constraint, a clause of this predicate must be added. Its body defines a propagator which should always succeed determinately. When a global constraint is resumed, the propagator will be executed and should perform the relevant pruning.
Please note: the constraint is identified by its principal functor; there is no way to have two constraints with the same name in different modules. It is good practice to include a cut in every clause of
clpfd:dispatch_global/4
.Please note: During propagation, if the domain of a variable becomes reduced to a single value, then the variable will eventually be bound to that value, but it is undefined exactly when that happens. Therefore, clauses of
clpfd:dispatch_global/4
should not usenonvar/1
ornumber/1
to check if a variable is fixed. Use, e.g.,fd_min/1
andfd_max/1
instead.
The propagator receives in State0 a term representing the current state and should unify State with a term representing the new state. That way, the propagator can be stateful if it wishes to.
The propagator should treat all domain variables as read-only: it must
not prune any domains, bind any domain variables, wake up any
suspended goals, or post any new constraints. Instead, Actions
should be unified with a list of requests to the solver. The list of
requests is executed as if in the scope of fd_batch/1
so that
any newly posted constraints are injected into the ongoing
propagation, and not propagated recursively. Each request should be
of one of the following forms:
exit
The constraint has become entailed, and ceases to exist.
fail
The constraint has become disentailed, causing a backtrack.
X = V
Binds X to V. X to V should be of the same type.
X in R
Constrains X to be a member of the IntegerRange or RealRange R, depending on the type of X (see Syntax of Range Expressions).
X in_set S
Constrains X to be a member of the FD set S (see FD Set Operations). X must be an integer variable.
call(Goal)
The solver calls the goal or constraint Goal, which should be
module prefixed unless it is a built-in predicate or an exported
predicate of the clpfd
module.
fd_global(:Constraint, +State, +Susp)
fd_global(:Constraint, +State, +Susp, +Options)
where Constraint is a constraint goal, State is its initial state, and Susp is a term encoding how the constraint should wake up in response to domain changes. This predicate posts the constraint.
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:
dom(X)
wake up when the domain of X has changed
min(X)
wake up when the lower bound of X has changed
max(X)
wake up when the upper bound of X has changed
minmax(X)
wake up when the lower or upper bound of X has changed
val(X)
wake up when X has been fixed
Options is a list of zero or more of the following:
source(Term)
By default, the symbolic form computed by copy_term/3
, and shown
in the answer constraint if clpfd:full_answer
holds, equals
Constraint, module name expanded. With this option, the symbolic
form will instead be Term. In particular, if Term equals
true
, then the constraint will not appear in the Body argument
of copy_term/3
. This can be useful if you are posting some
redundant (implied) constraint.
idempotent(Boolean)
If true
(the default), then the propagator 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
, then
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, then the solver will no longer trust the propagator to be idempotent.
For an example of usage, see Global Constraint Example.
The following predicate controls operational aspects of the constraint solver:
fd_setrand(+Seed) since release 4.10.0
Sets the random number generator seed. Seed should be a 32-bit integer.
fd_getrand(-Seed) since release 4.10.0
Gets the random number generator seed.
fd_flag(+FlagName, ?OldValue, ?NewValue)
OldValue is the value of the FD flag FlagName, and the new value of FlagName is set to NewValue. The possible FD flag names and values are:
overflow
Determines the behavior on integer overflow conditions. Possible values:
error
Raises a representation error (the default).
fail
Silently fails.
debug
Controls the visibility of constraint propagation. Possible values are
on
and off
(the default). For internal use by
library(fdbg)
.
precision since release 4.10.0
The value should be a float not smaller than 0.0 (the default).
Defines a lower bound for the size of nonground real domains. In some
applications, if the size of the domain of a real variable becomes
smaller than a given bound, the variable should be considered fixed.
The precision
flag provides that functionality, fixing the
variable to a value in its domain as soon as the size drops below the
threshold.