lib(ic_symbolic)


    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 &= YX is the same as Y
    X &\= YX is different from Y
    X &X is strictly before Y in the domain order
    X &> YX is strictly after Y in the domain order
    X &=X is the same as Y, or before Y in the domain order
    X &>= YX 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 &
    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)
    
    
    

