Node:Goal Expanded Constraints, Previous:Execution of Checking Indexicals, Up:Defining Primitive Constraints
The arithmetic, membership, and propositional constraints described earlier are transformed at compile time to conjunctions of goals of library constraints.
Sometimes it is necessary to postpone the expansion of a constraint
until runtime, e.g. if the arguments are not instantiated enough.
This can be achieved by wrapping call/1
around the constraint.
Although space economic (linear in the size of the source code), the
expansion of a constraint to library goals can have an overhead compared
to expressing the constraint in terms of indexicals. Temporary
variables holding intermediate values may have to be introduced, and the
grain size of the constraint solver invocations can be rather small.
The translation of constraints to library goals has been greatly
improved in the current version, so these problems have virtually
disappeared. However, for backward compatibility, an implementation by
compilation to indexicals of the same constraints is also provided. An
FD predicate may be defined by a single clause:
Head +: Constraint.
where Constraint is an arithmetic constraint or an element/3
or
a relation/3
constraint. This translation is only available for
+:
clauses; thus, Head cannot be reified.
In the case of arithmetic constraints, the constraint must be over
linear terms (see Syntax of Indexicals). The memory consumption of
the FD predicate will be quadratic in the size of the source code. The
alternative version of sum/8
in Send More Money illustrates
this technique.
In the case of element(X,L,Y)
or relation(X,L,Y)
, the
memory consumption of the FD predicate will be linear in the size of the
source code. The execution time of the initial evaluation of the FD
predicate will be linear in the size of the initial domains for X
and Y; if these domains are infinite, no propagation will
take place.