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
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
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
), 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.