:- module(ic_symbolic).
:- export element_ / 4.
:- export element / 3.
:- export atmost_ / 4.
:- export atmost / 3.
:- export occurrences_ / 4.
:- export occurrences / 3.
:- export alldifferent_ / 3.
:- export alldifferent / 2.
:- export alldifferent_ / 2.
:- export alldifferent / 1.
:- export rotate_ / 5.
:- export rotate / 4.
:- export rotate_ / 4.
:- export rotate / 3.
:- export shift_ / 5.
:- export shift / 4.
:- export shift_ / 4.
:- export shift / 3.
:- export ge / 4.
:- export &>= / 3.
:- export ge / 3.
:- export &>= / 2.
:- export gt / 4.
:- export &> / 3.
:- export gt / 3.
:- export &> / 2.
:- export le / 4.
:- export &=< / 3.
:- export le / 3.
:- export &=< / 2.
:- export lt / 4.
:- export &< / 3.
:- export lt / 3.
:- export &< / 2.
:- export differ_ / 4.
:- export &\= / 3.
:- export differ_ / 3.
:- export &\= / 2.
:- export same_ / 4.
:- export &= / 3.
:- export same_ / 3.
:- export &= / 2.
:- export msg_ / 4.
:- export msg / 3.
:- export is_exact_solver_var / 1.
:- export is_solver_var / 1.
:- export symbols_domain_indices_ / 4.
:- export symbols_domain_indices / 3.
:- export symbol_domain_index / 3.
:- export indomain / 1.
:- export symbol_domain_index_ / 4.
:- export have_domain / 3.
:- export &:: / 2.
:- export compare_instances_ic_symbolic / 3.
:- export copy_term_ic_symbolic / 2.
:- export test_unify_ic_symbolic / 2.
:- export unify_ic_symbolic / 3.
:- export get_domain_as_list / 2.
:- 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, &>=).
:- tool(element / 3,element_ / 4).
:- tool(atmost / 3,atmost_ / 4).
:- tool(occurrences / 3,occurrences_ / 4).
:- tool(alldifferent / 2,alldifferent_ / 3).
:- tool(alldifferent / 1,alldifferent_ / 2).
:- tool(rotate / 4,rotate_ / 5).
:- tool(rotate / 3,rotate_ / 4).
:- tool(shift / 4,shift_ / 5).
:- tool(shift / 3,shift_ / 4).
:- tool(&>= / 3,ge / 4).
:- tool(&>= / 2,ge / 3).
:- tool(&> / 3,gt / 4).
:- tool(&> / 2,gt / 3).
:- tool(&=< / 3,le / 4).
:- tool(&=< / 2,le / 3).
:- tool(&< / 3,lt / 4).
:- tool(&< / 2,lt / 3).
:- tool(&\= / 3,differ_ / 4).
:- tool(&\= / 2,differ_ / 3).
:- tool(&= / 3,same_ / 4).
:- tool(&= / 2,same_ / 3).
:- tool(msg / 3,msg_ / 4).
:- tool(symbols_domain_indices / 3,symbols_domain_indices_ / 4).
:- tool(symbol_domain_index / 3,symbol_domain_index_ / 4).
:- tool(&:: / 2,have_domain / 3).
:- comment(element_ / 4, hidden).
:- comment(atmost_ / 4, hidden).
:- comment(occurrences_ / 4, hidden).
:- comment(alldifferent_ / 3, hidden).
:- comment(alldifferent_ / 2, hidden).
:- comment(rotate_ / 5, hidden).
:- comment(rotate_ / 4, hidden).
:- comment(shift_ / 5, hidden).
:- comment(shift_ / 4, hidden).
:- comment(ge / 4, hidden).
:- comment(ge / 3, hidden).
:- comment(gt / 4, hidden).
:- comment(gt / 3, hidden).
:- comment(le / 4, hidden).
:- comment(le / 3, hidden).
:- comment(lt / 4, hidden).
:- comment(lt / 3, hidden).
:- comment(differ_ / 4, hidden).
:- comment(differ_ / 3, hidden).
:- comment(same_ / 4, hidden).
:- comment(same_ / 3, hidden).
:- comment(msg_ / 4, hidden).
:- comment(symbols_domain_indices_ / 4, hidden).
:- comment(symbol_domain_index_ / 4, hidden).
:- comment(have_domain / 3, hidden).
:- comment(summary, "Solver for constraints over ordered symbolic domains").
:- comment(author, "Joachim Schimpf").
:- comment(date, "$Date: 2008/06/05 15:30:42 $").
:- comment(copyright, "Cisco Systems, Inc.").
:- comment(desc, html("\n    <H4>Overview</H4>\n    <P>\n    This library is an add-on to library(ic) and implements variables\n    over ordered symbolic domains, and constraints over such variables.\n    This is in contrast to the basic library(ic), which implements only\n    variables over numeric domains.\n    <H4>Domains</H4>\n    The library uses the domain feature provided by the ECLiPSe kernel.\n    I.e. domains need to be declared. The declaration specifies the domain\n    values and their order. For example:\n    <PRE>\n    \t?- local domain(weekday(mo,tu,we,th,fr,sa,su)).\n    </PRE>\n    declares a domain with name 'weekday' and values 'mo', 'tu' etc.\n    The domain values are implicitly ordered, with 'mo' corresponding to 1,\n    until 'su' corresponding to 7.\n    Domain values must be unique within one ECLiPSe module, i.e. a symbolic\n    value can belong to at most one domain.\n    <H4>Variables</H4>\n    A variable of a declared domain can then be created using\n    <PRE>\n\t?- X &:: weekday.\n\tX = X{[mo, tu, we, th, fr, sa, su]}\n\tYes (0.00s cpu)\n    </PRE>\n    or multiple variables using &:: /2.\n    <H4>Basic Constraints</H4>\n    The following constraints implement the basic relationships between\n    two domain values. The constraints require their arguments to come from\n    identical domains, otherwise an error is raised.\n    <DL>\n    <DT>X &= Y</DT><DD>X is the same as Y</DD>\n    <DT>X &\\= Y</DT><DD>X is different from Y</DD>\n    <DT>X &< Y</DT><DD>X is strictly before Y in the domain order</DD>\n    <DT>X &> Y</DT><DD>X is strictly after Y in the domain order</DD>\n    <DT>X &=< Y</DT><DD>X is the same as Y, or before Y in the domain order</DD>\n    <DT>X &>= Y</DT><DD>X is the same as Y, or after Y in the domain order</DD>\n    <DT>shift(X,C,Y)</DT><DD>Y is C places after X in the domain order</DD>\n    <DT>rotate(X,C,Y)</DT><DD>like shift/3 but wraps at domain boundary</DD>\n    <DT>element(Index,List,Value)</DT><DD>Value occurs List at position Index</DD>\n    </DL>\n    For example\n    <PRE>\n\t?- [X, Y] &:: weekday, X &< Y.\n\tX = X{[mo, tu, we, th, fr, sa]}\n\tY = Y{[tu, we, th, fr, sa, su]}\n\tYes (0.00s cpu)\n\n\t?- X &:: weekday, X &=< we.\n\tX = X{[mo, tu, we]}\n\tYes (0.00s cpu)\n    </PRE>\n    <H4>Global Constraints</H4>\n    A number of global constraints are available which directly correspond\n    (and are in fact implemented via) their counterparts in lib(ic_global):\n    <DL>\n    <DT>alldifferent(List)</DT><DD>All list elements are different</DD>\n    <DT>occurrences(Value,List,N)</DT><DD>Value occurs N times in List</DD>\n    <DT>atmost(N,List,Value)</DT><DD>Value occurs at most N times in List</DD>\n    </DL>\n    </P>\n    <H4>Internals</H4>\n    <P>\n    Internally, symbolic domains are mapped to integer ranges from 1 up to\n    the number of domain elements. The first value in the domain declaration\n    corresponds to 1, the second to 2 and so on. Similarly, symbolic domain\n    variables can be mapped to a corresponding IC integer variable.\n    This mapping is accessible through the predicate symbol_domain_index/3:\n    <PRE>\n    ?- symbol_domain_index(fr, D, I).\n    D = weekday\n    I = 5\n    Yes (0.00s cpu)\n\n    ?- X &:: weekday, symbol_domain_index(X, D, I).\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    D = weekday\n    I = I{1 .. 7}\n    Yes (0.00s cpu)\n\n    ?- X &:: weekday, X &\\= we, symbol_domain_index(X, D, I).\n    X = X{[mo, tu, th, fr, sa, su]}\n    D = weekday\n    I = I{[1, 2, 4 .. 7]}\n    Yes (0.00s cpu)\n    </PRE>\n    The integer variable I mirrors the domain of the symbolic variable\n    X and vice versa.\n    </P>\n    <H4>Extending and Interfacing this Library</H4>\n    <P>\n    Because of the mapping of symbols to integers, new constraints over\n    symbolic variables can be implemented simply by placing numeric (IC)\n    constraints on the corresponding integer variables.\n    </P><P>\n    Similarly, the facilities of the ic_search library can be exploited\n    when working with symbolic variables. Instead of labeling the symbolic\n    variables, one can use the various facilities of ic_search to label\n    the corresponding integer variables instead.\n    </P>\n    <H4>Known Problems</H4>\n    <P>\n    For efficiency reasons, the 'constrained' suspension list of the symbolic\n    variable does not automatically get woken every time the domain changes\n    (although it does get woken when the domain is initially attached, and\n    when the variable gets instantiated). There are two solutions: (1) instead\n    of suspending goals on the constrained-list of the symbolic variable,\n    suspend them on the constrained-list of the corresponding integer variable.\n    (2) Use a forwarding demon that suspends on the constrained-list of the\n    integer variable and wakes the constrained-list of the symbolic variable:\n    <PRE>\n\tsymbol_domain_index(X, Domain, X_ic),\n    \tsuspend(notify_constrained(X), 2, X_ic->constrained)\n    </PRE>\n    </P>\n    ")).
:- comment(&:: / 2, [summary : "All elements of Vars have a value in the domain Domain", args : ["Vars" : "variable or atomic value, list of them, or submatrix of them", "Domain" : "domain name (atom) or list of domain elements"], template : "?Vars &:: +Domain", see_also : [domain / 1, current_domain / 3, domain_index / 3], eg : "\n    ?- X &:: weekday.\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- [X,Y,we] &:: weekday.\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- dim(M,[3]), M[1..3] &:: weekday.\n    M = [](_306{[mo, tu, we, th, fr, sa, su]}, ...)\n    Yes (0.00s cpu)\n\n    ?- [X,Y] &:: [we,fr,su].\n    X = X{[we, fr, su]}\n    Y = Y{[we, fr, su]}\n\n    ?- X &:: [].\n    No (0.00s cpu)\n    ", desc : html("<P>\n\tConstrains a variable, or a list or submatrix of variables, to be in\n\tthe domain Domain.\n\tDomain must be the name of a previously declared domain (see domain/1),\n\tor a sub-domain, expressed as a list of values from a single domain.\n\tA domain variable can only be instantiated to values within its domain.\n\t</P><P>\n\tNote that, on the left hand side of &::/2, the atom [] is not\n\tinterpreted as the empty list but as a potential domain element.\n\t</P>\n")]).
:- comment(&< / 2, [summary : "X is before Y in the domain order", args : ["X" : "variable or domain value", "Y" : "variable or domain value"], template : "?X &< ?Y", see_also : [&< / 3, &> / 2, &=< / 2, &>= / 2, &= / 2, &\= / 2, shift / 3, rotate / 3, domain / 1], eg : "\n    ?- [X,Y] &:: weekday, X &< Y.\n    X = X{[mo, tu, we, th, fr, sa]}\n    Y = Y{[tu, we, th, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- mo &< th.\n    Yes (0.00s cpu)\n\n    ?- X &< th.\n    X = X{[mo, tu, we]}\n    Yes (0.00s cpu)\n\n    ?- fr &< th.\n    No (0.00s cpu)\n\n    ?- X &< Y.\n    Arguments have no domains in X &< Y in module eclipse\n    Abort\n\n    ?- X &:: weekday, X &< red.\n    Arguments have different domains (weekday,colour) in X &< red ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y such that X is before Y in the domain order.\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n")]).
:- comment(&< / 3, [summary : "Reified version of X &< Y", see_also : [&< / 2], args : ["X" : "variable or domain value", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(&= / 2, [summary : "X is the same domain value as Y", args : ["X" : "variable or domain value", "Y" : "variable or domain value"], template : "?X &= ?Y", see_also : [&= / 3, &< / 2, &> / 2, &=< / 2, &>= / 2, &\= / 2, shift / 3, rotate / 3], eg : "\n    ?- [X, Y] &:: weekday, X &= Y.\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = X{[mo, tu, we, th, fr, sa, su]}\n    Yes (0.01s cpu)\n\n    ?- th &= th.\n    Yes (0.00s cpu)\n\n    ?- X &= th.\n    X = th\n    Yes (0.00s cpu)\n\n    ?- fr &= th.\n    No (0.00s cpu)\n\n    ?- X &= Y.\n    Arguments have no domains in X &= Y in module eclipse\n    Abort\n\n    ?- X &:: weekday, X &= red.\n    Arguments have different domains (weekday,colour) in X &= red ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y to be the same.  This is almost the same as\n\tunifying X and Y, except that &=/2 raises errors when X and\n\tY are domain-less (where unification succeeds) or when the\n\tdomains of X and Y are incompatible (where unification fails).\n")]).
:- comment(&= / 3, [summary : "Reified version of X &= Y", see_also : [&= / 2], args : ["X" : "variable or domain value", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(&=< / 2, [summary : "X is before or equal to Y in the domain order", args : ["X" : "variable or domain value", "Y" : "variable or domain value"], template : "?X &=< ?Y", see_also : [&=< / 3, &< / 2, &> / 2, &>= / 2, &= / 2, &\= / 2, shift / 3, rotate / 3, domain / 1], eg : "\n    ?- [X,Y] &:: weekday, X &=< Y.\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- mo &=< th.\n    Yes (0.00s cpu)\n\n    ?- X &=< th.\n    X = X{[mo, tu, we, th]}\n    Yes (0.00s cpu)\n\n    ?- fr &=< th.\n    No (0.00s cpu)\n\n    ?- X &=< Y.\n    Arguments have no domains in X &=< Y in module eclipse\n    Abort\n\n    ?- X &:: weekday, X &=< red.\n    Arguments have different domains (weekday,colour) in X &=< red ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y such that X is before Y or the same as Y in the\n\tdomain order.\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n")]).
:- comment(&=< / 3, [summary : "Reified version of X &=< Y", see_also : [&=< / 2], args : ["X" : "variable or domain value", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(&> / 2, [summary : "X is after Y in the domain order", args : ["X" : "variable or domain value", "Y" : "variable or domain value"], template : "?X &> ?Y", see_also : [&> / 3, &< / 2, &=< / 2, &>= / 2, &= / 2, &\= / 2, shift / 3, rotate / 3, domain / 1], eg : "\n    ?- [X,Y] &:: weekday, X &> Y.\n    X = X{[tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- th &> mo.\n    Yes (0.00s cpu)\n\n    ?- X &> th.\n    X = X{[fr, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- th &> fr.\n    No (0.00s cpu)\n\n    ?- X &> Y.\n    Arguments have no domains in X &> Y in module eclipse\n    Abort\n\n    ?- X &:: weekday, X &> red.\n    Arguments have different domains (weekday,colour) in X &> red ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y such that X is after Y in the domain order.\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n")]).
:- comment(&> / 3, [summary : "Reified version of X &> Y", see_also : [&> / 2], args : ["X" : "variable or domain value", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(&>= / 2, [summary : "X is after or equal to Y in the domain order", args : ["X" : "variable or domain value", "Y" : "variable or domain value"], template : "?X &>= ?Y", see_also : [&>= / 3, &< / 2, &> / 2, &=< / 2, &= / 2, &\= / 2, shift / 3, rotate / 3, domain / 1], eg : "\n    ?- [X,Y] &:: weekday, X &>= Y.\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- th &>= mo.\n    Yes (0.00s cpu)\n\n    ?- X &>= th.\n    X = X{[th, fr, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- th &>= fr.\n    No (0.00s cpu)\n\n    ?- X &>= Y.\n    Arguments have no domains in X &>= Y in module eclipse\n    Abort\n\n    ?- X &:: weekday, X &>= red.\n    Arguments have different domains (weekday,colour) in X &>= red ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y such that X is after Y or the same as Y in the\n\tdomain order.\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n")]).
:- comment(&>= / 3, [summary : "Reified version of X &>= Y", see_also : [&>= / 2], args : ["X" : "variable or domain value", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(&\= / 2, [summary : "X is different from Y in the domain", args : ["X" : "variable or domain value", "Y" : "variable or domain value"], template : "?X &\\= ?Y", see_also : [&\= / 3, &< / 2, &> / 2, &=< / 2, &>= / 2, &= / 2, shift / 3, rotate / 3], eg : "\n    ?- [X,Y] &:: weekday, X &\\= Y.\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- mo &\\= th.\n    Yes (0.00s cpu)\n\n    ?- X &\\= th.\n    X = X{[mo, tu, we, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- th &\\= th.\n    No (0.00s cpu)\n\n    ?- X &\\= Y.\n    Arguments have no domains in X &\\= Y in module eclipse\n    Abort\n\n    ?- X &:: weekday, X &\\= red.\n    Arguments have different domains (weekday,colour) in X &\\= red ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y to be different.\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n")]).
:- comment(&\= / 3, [summary : "Reified version of X &\\= Y", see_also : [&\= / 2], args : ["X" : "variable or domain value", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(alldifferent / 1, [summary : "All elements of List are different", args : ["List" : "list of variables or domain values"], see_also : [ic_global : alldifferent / 1], desc : html("\n\tConstrains all list elements to be different values of the same domain.\n\tThis is implemented by mapping onto ic_global:alldifferent/1.\n\tAll list elements must be variables or values of the same domain.\n\tIf one or more of them are domain-less, they will be given the same\n\tdomain as the others.\n")]).
:- comment(alldifferent / 2, [summary : "No domain value occurs more than Cap times in List", args : ["List" : "list of variables or domain values", "Cap" : "integer or integer variable"], see_also : [ic_global : alldifferent / 2], desc : html("\n\tConstrains the list so that no more than Cap elements can have the\n\tsame value.\n\tThis is implemented by mapping onto ic_global:alldifferent/2.\n\tAll list elements must be variables or values of the same domain.\n\tIf one or more of them are domain-less, they will be given the same\n\tdomain as the others.\n")]).
:- comment(atmost / 3, [summary : "Value occurs N times in List", amode : atmost(++, +, ++), args : ["N" : "integer", "List" : "list of variables or domain values", "Value" : "domain value"], see_also : [ic_global : atmost / 3], desc : html("\n\tConstrains its arguments such that Value occurs at most N times\n\tin List.\n\tThis is implemented by mapping onto ic_global:atmost/3.\n\tAll list elements and Value must be variables or values of the\n\tsame domain.  If one or more of them are domain-less, they will\n\tbe given the same domain as the others.\n")]).
:- comment(element / 3, [summary : "Value is the Index'th element of List", amode : element(?, ++, ?), args : ["Index" : "integer variable or integer", "List" : "list of domain values", "Value" : "domain variable or value"], see_also : [ic : element / 3], desc : html("\n\tConstrains its arguments such that Value is the Index'th member\n\tof List.  This is implemented by mapping onto ic:element/3.\n\tAll list elements and Value must be variables or values of the\n\tsame domain.  If one or more of them are domain-less, they will\n\tbe given the same domain as the others.\n")]).
:- comment(indomain / 1, [summary : "Nondeterministically instantiate to domain values", args : ["X" : "domain variable or value"], see_also : [&:: / 2, domain / 1], eg : "\n    ?- local domain(weekday(mo, tu, we, th, fr, sa, su)).\n    Yes (0.00s cpu)\n\n    ?- X &:: weekday.\n    X = X{[mo, tu, th, fr, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- X &:: weekday, indomain(X).\n    X = mo\n    More (0.00s cpu)\n    X = tu\n    More (0.01s cpu)\n    X = we\n    More (0.02s cpu)\n    X = th\n    More (0.03s cpu)\n    X = fr\n    More (0.05s cpu)\n    X = sa\n    More (0.06s cpu)\n    X = su\n    Yes (0.06s cpu)\n\n    ?- indomain(we).\n    Yes (0.00s cpu)\n    ", desc : html("<P>\n\tInstantiates a domain variable to its domain values. The order of\n\tenumeration is in increasing domain order.\n    </P>")]).
:- comment(msg / 3, [summary : "MSG is the most specific generalisation of X and Y representable with ic-symbolic domain variables", args : ["X" : "Any term or variable", "Y" : "Any term or variable", "MSG" : "A domain variable or constant (output)"], amode : msg(?, ?, -), fail_if : "None", see_also : [_37479 : msg / 3, library(propia), &:: / 2, domain / 1], eg : "\n    ?- local domain(weekday(mo, tu, we, th, fr, sa, su)).\n    Yes (0.00s cpu)\n\n    ?- msg(we, fr, Z).\n    Z = Z{[we, fr]}\n    Yes (0.00s cpu)\n\n    ?- X &:: [sa, su], msg(X, we, Z).\n    X = X{[sa, su]}\n    Z = Z{[we, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- X &:: [sa, su], Y &:: [mo, tu, we], msg(X, Y, Z).\n    X = X{[sa, su]}\n    Y = Y{[mo, tu, we]}\n    Z = Z{[mo, tu, we, sa, su]}\n    Yes (0.00s cpu)\n\n    ?- X &:: [sa, su], msg(X, _, Z).\n    X = X{[sa, su]}\n    Z = Z\n    Yes (0.01s cpu)\n\n    % in the following, the result is not precisely representable\n    ?- X &:: [sa, su], msg(X, foo, Z).\n    X = X{[sa, su]}\n    Z = Z\n    Yes (0.01s cpu)\n    ", desc : html("<P>\n\tThis predicate computes the most specific generalisation of X and Y\n\twhich can be represented using ic-symbolic's domains and domain\n\tvariables.\n\t</P><P>\n\tIf X and Y are domain variables (or constants) from the same domain,\n\tthen MSG will be unified with a new domain variable whose domain\n\tconsists of the union of the domain elements of X and Y.\n\t</P><P>\n\tIf X and Y are domain variables or constants with incompatible\n\tdomains, then the result will be a free (unconstrained) variable.\n\t</P><P>\n\tIf X or Y are free (unconstrained) variables, then the result will\n\talso be a free (unconstrained) variable.\n    </P>")]).
:- comment(occurrences / 3, [summary : "Value occurs N times in List", amode : occurrences(+, +, ?), args : ["Value" : "domain value", "List" : "list of variables or domain values", "N" : "integer variable or integer"], see_also : [ic_global : occurrences / 3], desc : html("\n\tConstrains its arguments such that Value occurs exactly N times\n\tin List.\n\tThis is implemented by mapping onto ic_global:occurrences/3.\n\tAll list elements and Value must be variables or values of the\n\tsame domain.  If one or more of them are domain-less, they will\n\tbe given the same domain as the others.\n")]).
:- comment(rotate / 3, [summary : "Y is C places after X in the (cyclic) domain order", args : ["X" : "variable or domain value", "C" : "variable or integer", "Y" : "variable or domain value"], amode : rotate(?, ?, ?), see_also : [rotate / 4, &< / 2, &> / 2, &=< / 2, &>= / 2, &= / 2, &\= / 2, shift / 3, domain / 1], eg : "\n    ?- [X,Y] &:: weekday, rotate(X,1,Y).\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    ?- rotate(th,1,fr).\n    Yes (0.00s cpu)\n\n    ?- rotate(su,2,tu).\n    Yes (0.00s cpu)\n\n    ?- rotate(su,9,tu).\n    Yes (0.00s cpu)\n\n    ?- rotate(X,1,fr).\n    X = th\n    Yes (0.00s cpu)\n\n    ?- rotate(su,50,X).\n    X = mo\n    Yes (0.00s cpu)\n\n    ?- rotate(su,-1,X).\n    X = sa\n    Yes (0.00s cpu)\n\n    ?- rotate(tu,1,th).\n    No (0.00s cpu)\n\n    ?- ic:(X::0..7), rotate(tu,X,fr).\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- ic:(X::2..4), rotate(tu,X,Y).\n    X = X{2 .. 4}\n    Y = Y{[th, fr, sa]}\n    Delayed goals: ...\n\n    ?- rotate(X,1,Y).\n    Arguments have no domains in rotate(X, 1, Y) in module eclipse\n    Abort\n\n    ?- X &:: weekday, rotate(X, 1, red).\n    Arguments have different domains (weekday,colour) in rotate(X, 1, red) ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y such that Y is C positions after X in the domain\n\torder, where the order is considered cyclic, i.e. the first domain\n\telement follows the last one. Because of the cyclic order, for each\n\tpair of X and Y there are infinitely many solutions for C (which\n\tare identical modulo the domain size).\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n\t<P>\n\tThe implementation currently achieves only bounds-consistency.\n")]).
:- comment(rotate / 4, [summary : "Reified version of rotate(X,C,Y)", see_also : [rotate / 3], args : ["X" : "variable or domain value", "C" : "variable or integer", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(shift / 3, [summary : "Y is C places after X in the domain order", args : ["X" : "variable or domain value", "C" : "variable or integer", "Y" : "variable or domain value"], amode : shift(?, ?, ?), see_also : [shift / 4, &< / 2, &> / 2, &=< / 2, &>= / 2, &= / 2, &\= / 2, rotate / 3, domain / 1], eg : "\n    ?- [X,Y] &:: weekday, shift(X, 1, Y).\n    X = X{[mo, tu, we, th, fr, sa]}\n    Y = Y{[tu, we, th, fr, sa, su]}\n    There is 1 delayed goal.\n    Yes (0.00s cpu)\n\n    [eclipse 4]: [X,Y]&::weekday, shift(X,C,Y). \n    X = X{[mo, tu, we, th, fr, sa, su]}\n    C = C{-6 .. 6}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    There are 3 delayed goals.\n    Yes (0.00s cpu)\n\n    ?- shift(we, 1, th).\n    Yes (0.00s cpu)\n\n    ?- shift(we, 2, fr).\n    Yes (0.00s cpu)\n\n    ?- shift(X, -1, th).\n    X = fr\n    Yes (0.00s cpu)\n\n    ?- shift(tu, X, fr).\n    X = 3\n    Yes (0.00s cpu)\n\n    ?- shift(tu,X,Y).\n    X = X{-1 .. 5}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    Delayed goals: ...\n\n    ?- shift(tu, 1, th).\n    No (0.00s cpu)\n\n    ?- shift(X, 1, Y).\n    Arguments have no domains in shift(X, 1, Y) in module eclipse\n    Abort\n\n    ?- X &:: weekday, shift(X, 1, red).\n    Arguments have different domains (weekday,colour) in shift(X, 1, red) ...\n    Abort\n    ", desc : html("\n\tConstrains X and Y such that Y is C positions after X in the domain\n\torder. C must be an integer or integer variable, and its range is\n\t-(S-1)..S-1 where S is the size of the symbolic domain.\n\tX and Y must be variables or values of the same domain. If one of\n\tthem is domain-less, it will be given the same domain as the other.\n\t<P>\n\tThe implementation achieves domain consistency iff C is instantiated\n\tat call time, otherwise only bounds consistency.\n")]).
:- comment(shift / 4, [summary : "Reified version of shift(X,C,Y)", see_also : [shift / 3], args : ["X" : "variable or domain value", "C" : "variable or integer", "Y" : "variable or domain value", "Bool" : "0, 1, or boolean variable"]]).
:- comment(symbol_domain_index / 3, [summary : "Map a symbolic domain variable/value to integer variable/value", amode : symbol_domain_index(?, -, -), fail_if : "X is neither a symbolic domain variable nor a domain constant", args : ["X" : "domain variable or value", "Domain" : "Variable, will be bound to a pair Module:DomainName", "Index" : "Variable, will be bound to integer or integer variable"], see_also : [symbols_domain_indices / 3, &:: / 2, domain / 1, domain_index / 3], eg : "\n    ?- symbol_domain_index(we, D, I).\n    D = eclipse:weekday\n    I = 3\n    Yes (0.00s cpu)\n\n    ?- X &:: weekday, X &\\= we, symbol_domain_index(X, D, I).\n    X = X{[mo, tu, th, fr, sa, su]}\n    D = eclipse:weekday\n    I = I{[1, 2, 4 .. 7]}\n    Yes (0.00s cpu)\n    ", desc : html("\n\tLow-level primitive:\n\tFor a domain variable or domain value, return the corresponding\n\tdomain name and an integer or integer variable reflecting the\n\tcorresponding integer index within the domain order.\n")]).
:- comment(symbols_domain_indices / 3, [summary : "Map symbolic domain variables/values to integer variables/values", amode : symbols_domain_indices(+, ?, -), fail_if : "X is neither a symbolic domain variable nor a domain constant", args : ["Xs" : "list of domain variables or values", "Domain" : "Variable or domain name", "Is" : "Variable, will be bound to list of integers or integer variables"], see_also : [symbol_domain_index / 3, &:: / 2, domain / 1], eg : "\n    ?- symbols_domain_indices([we], D, Is).\n    D = eclipse:weekday\n    Is = [3]\n    Yes (0.00s cpu)\n    \n    ?- X &:: weekday, symbols_domain_indices([X], D, Is).\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    D = weekday\n    Is = [X_ic{1 .. 7}]\n    Yes (0.00s cpu)\n\n    ?- X &:: weekday, symbols_domain_indices([X, Y, we], D, Is).\n    X = X{[mo, tu, we, th, fr, sa, su]}\n    Y = Y{[mo, tu, we, th, fr, sa, su]}\n    D = eclipse:weekday\n    Is = [X_ic{1 .. 7}, X_ic{1 .. 7}, 3]\n    Yes (0.00s cpu)\n    ", desc : html("<P>\n\tLow-level primitive:\n\tFor a list of domain variables or domain values, return the\n\tdomain name and a list of integers or integer variables reflecting\n\tthe corresponding integer index within the domain order.\n\tIf the domain name is instantiated at call time, the list elements\n\twill be checked to be all from this domain.\n\t</P><P>\n\tAn error will be reported if not all list elements come from the same\n\tdomain. If the list contained domain-less variables, then, as a side\n\teffect, these will be given a domain to be compatible with the other\n\tlist elements.\n\t</P>\n")]).
