next up previous index
Next: RANGE: A Basis For Up: IC: A Hybrid Finite Previous: General Guidelines for the   Index

Subsections

User defined constraints

The library ic_kernel exports a variety of predicate which give access to the internal domain representation and suspension lists used to implement constraints in IC.

This section will introduce these predicates and demonstrate how they may be used to create new constraints for IC variables.

The IC attribute

The IC attribute is a meta-term which is attached to all variables which take part in IC constraints. ic_kernel defines the IC attribute as a structure of the following form:
ic with [variable:V,
         type:T,
         lo:Lo,
         hi:Hi,
         bitmap:Bmp,
         wake_lo:SuspLo,
         wake_hi:SuspHi,
         wake_hole:SuspHole,
         wake_type:SuspType
        ]

This structure holds

variable
A reference to the variable to which this attribute is attached. This can be useful when constraints wish to deal mainly with the attributes, but occasionally with the variables.

type
The type of the variable. This defaults to 'real' but may become 'integer' after an explicit call to integers/1, by being included in an integer constraint (eg.#=) or by inferences made during constraint propagation.

lo
The lower bound of the variable's domain, as a float.
hi
The lower bound of the variable's domain, as a float.
bitmap
Where relevant a bitmap represent the integer domain, where not relevant it holds the atom undefined.

wake_lo
Suspension list of suspended goals to be woken on lower bound changes.
wake_hi
Suspension list of suspended goals to be woken on upper bound changes.

wake_hole
Suspension list of suspended goals to be woken when a value is removed from the middle of a domain. Such removals only happen for integer variables whose domain is finite.

wake_type
Suspension list of suspended goals to be woken when a variables type becomes constrained, ie. when it is known that a variable is now integral.

The suspension list names can be used in suspend/3 and related predicates to denote an appropriate waking condition.

The attribute of a domain variable can be accessed with the predicate get_ic_attr/2.

IC attribute access

As mentioned above, one method to access information about the current domain of an IC variable is by explicitly acquiring the attribute and then extracting the information from the structure.

However for convenience, a number of access predicates are provided.

is_ic_var/1
Tests whether a variable has an ic attribute or not.

get_var_type/2
Returns either 'integer' or 'real' depending on the type of the variable.

get_ic_bounds/3
Returns the upper and lower bounds of a variable.

With the exception of is_ic_var/1 all the above access predicates will succeed meaningfully for numeric constants, and will add ic attributes to non ic variables automatically. This makes them safe to use without the need for extra type checks.

Modifying variable domains

When using IC variables in normal code, one would typically use the =\= < > family of constraints to (resp) remove a value, reduce the upper bound or increase the lower bound of a variable.

However, these general purpose constraints perform many type checks and safety checks before actually imposing any bounds. Also these constraints may leave delayed goals and furthermore may result in further propagation occurring right away. Though fine for normal CSP solving, when writing new constraints such behaviour (especially the immediate execution of delayed goals) may prove counter productive.

To give the constraint writer more control over such matters, special predicates exist in the ic_kernel module which allow direct modification of the domain without the waking of goals (they are scheduled for execution but not actually executed).

Typically two versions of each predicate exists, the first which works with IC variables, non-IC variables and numbers and the second which only works with IC attributes. The reason for this distinction is, again, a matter of efficiency and control. It is entirely possible (and indeed it is the case with the implementation of many IC constraints) that a constraint demon would not store the variables upon which it operates, but rather it would store the attributes only. Doing so removes the need to keep looking the attributes up and avoid (if the programmer is careful) the unnecessary type checks of a more general access predicate.

Full details on these predicates can be found in the reference manual, they are listed here for completeness. Note that the predicates prefixed with ic_ operate only on IC attributes and none of the goals call wake/0, so the programmer is free to do so at a convenient time.

lwb ic_lwb
Set the lowerbound.
upb ic_upb
Set the upperbound.
set_ic_bounds
Sets both upper and lower bounds, works on variables.
new_ic_bounds
Sets both upper and lower bounds, works on attributes.
excl ic_excl
Excludes an integer from an integral variable.
excl_range ic_excl_range
Excludes a range of integers from an integral variable.
set_var_integer
Sets the type to 'integer'.


next up previous index
Next: RANGE: A Basis For Up: IC: A Hybrid Finite Previous: General Guidelines for the   Index
Warwick Harvey
2002-05-15