Very often the programmer knows quite a bit about when parts of a program can be executed, due to the state of instantiation of data. Some CLP (and Prolog) systems include concurrency-related primitives which allow delaying the execution of user predicates until certain conditions (usually related to the instantiation state of the variables) hold: block and wait declarations are particular cases of a more general
:- delay Goal until Condition.
declaration. The allowed Conditions differ between systems. With such a declaration, a predicate like plus/3 in Section 4.4 could be put anywhere, provided that a condition stating that at least two of its three arguments must be numbers. This allows a simulation of constraint solving. In the same way, constraint languages can be augmented with concurrency for predicates involving operations which are not part of the constraint system, and which need a given call mode.
In any case, having the possibility of some kind of concurrency is interesting, because concurrent predicates can act as daemons waiting for a condition on the variables to be triggered; their use can range from I/O communication to error raising.
Enumeration also impacts the performance of constraint programs. The order in which variables are enumerated, and which values in the variable are selected first, impact greatly the amount of work (and, therefore, the time and memory spent) used to figure out a solution. Constraint languages usually allow the user to specify heuristics for these two possibilities.
On one hand, it is important to cut search paths as fast as possible (this is a general rule in writing search procedures, and is termed the first-fail principle). This is affected by the selection of the variable to enumerate, as setting value(s) for a variable simplifies the constraint system and removes values from the other variable's domains. Selecting the most constrained variables first for enumeration is a simple, sensible heuristic: these variables are more likely to affect the domains of other variables. Also, when selecting values for a variable, there are two general possibilities: enumerating values (for example, minimum to maximum, or the other way around), or setting a constraint (associated to a choicepoint) which splits the domain of the variable in two halves.
The selection of the heuristics depends greatly on the problem and the relationships among the variables.