10.35.9.8 Goal Expanded Constraints

The arithmetic, membership, and propositional constraints described earlier are transformed at compile time to conjunctions of goals of library constraints.

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.

The following two constructions are semantically equivalent:

     Head +: LinExpr RelOp LinExpr.
     
     Head :- LinExpr RelOp LinExpr.

where Head only contains unique variables mentioned in the linear arithmetic expressions LinExpr (see Syntax of Indexicals). The alternative version of sum/8 in Send More Money illustrates this technique.

Similarly, the following two constructions are semantically equivalent:

     Pred(X,Y) +: element(X, CList, Y).
     
     Pred(X,Y) :- element(X, CList, Y).

where CList is a ground list of integers. This technique is used in some demo programs in library('clpfd/examples'). Please note: the generated indexical will assume that the domains of X and Y do not contain values incompatible with CList.

Similarly, the following two constructions are semantically equivalent:

     Pred(X1,...,Xn) +: table(CTable).
     
     Pred(X1,...,Xn) :- table([[X1,...Xn]], CTable).

where CTable is an n-ary relation given by extension, as for the constraint table/[2,3]. Please note: the generated indexical will assume that the domains of X1,...Xn do not contain values incompatible with CTable.

In the body of an FD predicate, element/3 and table/1 expressions expand to indexicals recursively built up from switch/2 and unionof/3 expressions. For example, the following constraint:

     p(X, Y) +: table([[1,1],[2,1..2],[3,1..3]]).

expands to:

     q(X, Y) +:
             X in unionof(B,dom(Y),switch(B,[1-{1,2,3},2-{2,3},3-{3}])),
             Y in unionof(B,dom(X),switch(B,[1-{1},2-{1,2},3-{1,2,3}])).

Send feedback on this subject.