Goal Expanded 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.