[ Reference Manual | Alphabetic Index ]

# library(ic_symbolic)

Solver for constraints over ordered symbolic domains   [more]

## Predicates

?Vars &:: +Domain
All elements of Vars have a value in the domain Domain
?X &< ?Y
X is before Y in the domain order
&<(?X, ?Y, ?Bool)
Reified version of X &< Y
?X &= ?Y
X is the same domain value as Y
&=(?X, ?Y, ?Bool)
Reified version of X &= Y
?X &=< ?Y
X is before or equal to Y in the domain order
&=<(?X, ?Y, ?Bool)
Reified version of X &=< Y
?X &> ?Y
X is after Y in the domain order
&>(?X, ?Y, ?Bool)
Reified version of X &> Y
?X &>= ?Y
X is after or equal to Y in the domain order
&>=(?X, ?Y, ?Bool)
Reified version of X &>= Y
?X &\= ?Y
X is different from Y in the domain
&\=(?X, ?Y, ?Bool)
Reified version of X &\= Y
alldifferent(?List)
All elements of List are different
alldifferent(?List, ?Cap)
No domain value occurs more than Cap times in List
atmost(++N, +List, ++Value)
Value occurs N times in List
element(?Index, ++List, ?Value)
Value is the Index'th element of List
get_domain_as_list(?, ?)
No description available
indomain(?X)
Nondeterministically instantiate to domain values
is_exact_solver_var(?)
No description available
is_solver_var(?)
No description available
msg(?X, ?Y, -MSG)
MSG is the most specific generalisation of X and Y representable with ic-symbolic domain variables
occurrences(+Value, +List, ?N)
Value occurs N times in List
rotate(?X, ?C, ?Y)
Y is C places after X in the (cyclic) domain order
rotate(?X, ?C, ?Y, ?Bool)
Reified version of rotate(X,C,Y)
shift(?X, ?C, ?Y)
Y is C places after X in the domain order
shift(?X, ?C, ?Y, ?Bool)
Reified version of shift(X,C,Y)
symbol_domain_index(?X, -Domain, -Index)
Map a symbolic domain variable/value to integer variable/value
symbols_domain_indices(+Xs, ?Domain, -Is)
Map symbolic domain variables/values to integer variables/values

## Other Exports

export op(700, xfx, &::)
export op(700, xfx, &=)
export op(700, xfx, &\=)
export op(700, xfx, &<)
export op(700, xfx, &=<)
export op(700, xfx, &>)
export op(700, xfx, &>=)

## Description

#### Overview

This library is an add-on to library(ic) and implements variables over ordered symbolic domains, and constraints over such variables. This is in contrast to the basic library(ic), which implements only variables over numeric domains.

#### Domains

The library uses the domain feature provided by the ECLiPSe kernel. I.e. domains need to be declared. The declaration specifies the domain values and their order. For example:
```    	?- local domain(weekday(mo,tu,we,th,fr,sa,su)).
```
declares a domain with name 'weekday' and values 'mo', 'tu' etc. The domain values are implicitly ordered, with 'mo' corresponding to 1, until 'su' corresponding to 7. Domain values must be unique within one ECLiPSe module, i.e. a symbolic value can belong to at most one domain.

#### Variables

A variable of a declared domain can then be created using
```	?- X &:: weekday.
X = X{[mo, tu, we, th, fr, sa, su]}
Yes (0.00s cpu)
```
or multiple variables using &:: /2.

#### Basic Constraints

The following constraints implement the basic relationships between two domain values. The constraints require their arguments to come from identical domains, otherwise an error is raised.
X &= Y
X is the same as Y
X &\= Y
X is different from Y
X &< Y
X is strictly before Y in the domain order
X &> Y
X is strictly after Y in the domain order
X &=< Y
X is the same as Y, or before Y in the domain order
X &>= Y
X is the same as Y, or after Y in the domain order
shift(X,C,Y)
Y is C places after X in the domain order
rotate(X,C,Y)
like shift/3 but wraps at domain boundary
element(Index,List,Value)
Value occurs List at position Index
For example
```	?- [X, Y] &:: weekday, X &< Y.
X = X{[mo, tu, we, th, fr, sa]}
Y = Y{[tu, we, th, fr, sa, su]}
Yes (0.00s cpu)

?- X &:: weekday, X &=< we.
X = X{[mo, tu, we]}
Yes (0.00s cpu)
```

#### Global Constraints

A number of global constraints are available which directly correspond (and are in fact implemented via) their counterparts in lib(ic_global):
alldifferent(List)
All list elements are different
occurrences(Value,List,N)
Value occurs N times in List
atmost(N,List,Value)
Value occurs at most N times in List

#### Internals

Internally, symbolic domains are mapped to integer ranges from 1 up to the number of domain elements. The first value in the domain declaration corresponds to 1, the second to 2 and so on. Similarly, symbolic domain variables can be mapped to a corresponding IC integer variable. This mapping is accessible through the predicate symbol_domain_index/3:

```    ?- symbol_domain_index(fr, D, I).
D = weekday
I = 5
Yes (0.00s cpu)

?- X &:: weekday, symbol_domain_index(X, D, I).
X = X{[mo, tu, we, th, fr, sa, su]}
D = weekday
I = I{1 .. 7}
Yes (0.00s cpu)

?- X &:: weekday, X &\= we, symbol_domain_index(X, D, I).
X = X{[mo, tu, th, fr, sa, su]}
D = weekday
I = I{[1, 2, 4 .. 7]}
Yes (0.00s cpu)
```
The integer variable I mirrors the domain of the symbolic variable X and vice versa.

#### Extending and Interfacing this Library

Because of the mapping of symbols to integers, new constraints over symbolic variables can be implemented simply by placing numeric (IC) constraints on the corresponding integer variables.

Similarly, the facilities of the ic_search library can be exploited when working with symbolic variables. Instead of labeling the symbolic variables, one can use the various facilities of ic_search to label the corresponding integer variables instead.

#### Known Problems

For efficiency reasons, the 'constrained' suspension list of the symbolic variable does not automatically get woken every time the domain changes (although it does get woken when the domain is initially attached, and when the variable gets instantiated). There are two solutions: (1) instead of suspending goals on the constrained-list of the symbolic variable, suspend them on the constrained-list of the corresponding integer variable. (2) Use a forwarding demon that suspends on the constrained-list of the integer variable and wakes the constrained-list of the symbolic variable:

```	symbol_domain_index(X, Domain, X_ic),
suspend(notify_constrained(X), 2, X_ic->constrained)
```