# 7 Special Variables and Coroutining

This chapter deals with extensions primarily designed to support constraint logic programming (CLP). The low-level attributed variable interface defined in section 7.1 is not intended for the typical Prolog programmer. Instead, the typical Prolog programmer should use the coroutining predicates and the various constraint solvers built on top of attributed variables. CHR (chapter 8) provides a general purpose constraint handling language.

As a rule of thumb, constraint programming reduces the search space by reordering goals and joining goals based on domain knowledge. A typical example is constraint reasoning over integer domains. Plain Prolog has no efficient means to deal with (integer) X > 0 and X < 3. At best it could translate X > 0 with uninstantiated X to `between(1, infinite, X)` and a similar primitive for X < 3. If the two are combined it has no choice but to generate and test over this infinite two-dimensional space. Instead, a constraint system will delay an uninstantiated goal to X > 0. If, later, it finds a value for X it will execute the test. If it finds X < 3 it will combine this knowledge to infer that X is in 1..2 (see below). If it never finds a concrete value for X it can be asked to label X and produce 1 and 2 on backtracking. See section A.8.

    1 ?- [library(clpfd)].
    ...
    true.

    2 ?- X #> 0, X #< 3.
    X in 1..2.

Using constraints generally makes your program more declarative. There are some caveats though:

- Constraints and cuts do not merge well. A cut after a goal that is delayed prunes the search space before the condition is true.
- Term-copying operations (assert/1, retract/2, findall/3, copy_term/2, etc.) generally also copy constraints. The effect varies from ok, silent copying of huge constraint networks to violations of the internal consistency of constraint networks. As a rule of thumb, copying terms holding attributes must be deprecated.

## Section Index