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.
Declaration | ::= | handler Name. |
::= | constraints SpecList. | |
::= | operator( Precedence, Associativity, Name). | |
::= | label_with Constraint if Guard. |
The optional handler
declaration documents the name of the constraint
handler. Currently it can be omitted, but will be useful in future releases for
combining handlers.
The mandatory constraints
declaration lists the constraints
defined in the handler. A “SpecList” is a list of Name/
Arity
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.
The optional 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).
The optional 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 ?- /[1,2]
).
Clause | ::= | Head :- Body. |
::= | Head ?- Body. | |
::= | :- Body. | |
::= | ?- Body. |
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.
Option | ::= | option( Option, On_or_off). |
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_heads
option 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 dbgcomp
and 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_trace
activates the standard debugger and
shows constraint handling.
chr_notrace
stops either debugger.