The following subsections describe declarations, clauses, options and built-in predicates of the CHR language.
Declarations name the constraint handler, its constraints, specify their syntax and use in built-in labeling.
handler declaration documents the name of the constraint
handler. Currently it can be omitted, but will be useful in future releases for
constraints declaration lists the constraints
defined in the handler. A “SpecList” is a list of Name
pairs for the constraints.
The declaration of a constraint must appear before
the constraint handling rules and ECLiPSe clauses which define it,
otherwise a syntax error is raised.
There can be several constraints declarations.
operator declaration declares an operator, with
the same arguments as op/3 in ECLiPSe. However, while the usual
operator declarations are ignored during compilation from chr to
pl files, the CHR operator declarations are taken into account
(see also the subsection on clauses).
label_with declaration specifies when the
ECLiPSe clauses of a constraint can be used for built-in labeling
(see subsection on labeling).
Example, contd.: The first lines of the minmax handler are declarations:
handler minmax. constraints leq/2, neq/2, minimum/3, maximum/3. operator(700, xfx, leq). operator(700, xfx, neq).
A constraint handler program may also include arbitrary ECLiPSe code (written
with the four operators
:- /[1,2] and
Note that :-/1 and ?-/1 behave different from each other in CHR programs. Clauses starting with :- are copied into the pl file by the CHR compiler, clauses with ?- are executed by the compiler. As the op declaration needs both copying and execution, we have introduced the special operator declaration (see previous subsection on declarations). A "Head" can be a "Constraint", such clauses are used for built-in labeling only (see section on labeling).
The option command allows the user to set options in the CHR compiler.
Options can be switched on or off. Default is on. Advanced users may switch an option off to improve the efficiency of the handler at the cost of safety. Options are:
check_guard_bindings: When executing a guard, it is checked that no global variables (variables of the rule heads) are touched (see subsection on how CHRs work). If the option is on, guards involving cut, if-then-else or negation may not work correctly if a global variable has been touched before. If switched off, guard checking may be significantly faster, but only safe if the user makes sure that global variables are not touched. To ensure that the variables are sufficiently bound, tests like nonvar/1 or delays can be added to the predicates used in the guards.
already_in_store: Before adding a user-defined constraint to the constraint store, it is checked if there is an identical one already in the store. If there is, the new constraint needs not to be added. The handling of the duplicate constraint is avoided. This option can be set to
off, because the checking may be too expensive if duplicate constraints rarely occur. Specific duplicate constraints can still be removed by a simpagation rule of the form
Constraint \ Constraint <=> true.
already_in_heads: In two-headed simplification rules, the intention is often to simplify the two head constraints into a stronger version of one of the constraints. However, a straightforward encoding of the rule may include the case where the new constraint is identical to the corresponding head constraint. Removing the head constraint and adding it again in the body is inefficient and may cause termination problems. If the
already_in_headsoption is on, in such a case the head constraint is kept and the body constraint ignored. Note however, that this optimization currently only works if the body constraint is the only goal of the body or the first goal in the conjunction comprising the body of the rule (see the example handler for domains). The option may be too expensive if identical head-body constraints rarely occur.
debug_compile(set and unset with
nodbgcomp) is also taken into account by the CHR compiler. The default is on. If switched off, the resulting code is more efficient, but cannot be debugged anymore (see section 9.8).
There are some built-in predicates to compile chr files, for debugging, built-in labeling and to inspect the constraint store and remove its constraints:
chr_traceactivates the standard debugger and shows constraint handling.
chr_notracestops either debugger.