:- module(ic).
:- export (=\=) / 3.
:- export (<) / 3.
:- export (>) / 3.
:- export (=<) / 3.
:- export (>=) / 3.
:- export (=:=) / 3.
:- export (=\=) / 2.
:- export (<) / 2.
:- export (>) / 2.
:- export (=<) / 2.
:- export (>=) / 2.
:- export (=:=) / 2.
:- reexport reals / 1, integers / 1, is_solver_var / 1, is_exact_solver_var / 1, is_solver_type / 1, get_solver_type / 2, get_bounds / 3, get_min / 2, get_max / 2, get_float_bounds / 3, get_integer_bounds / 3, get_finite_integer_bounds / 3, get_domain_size / 2, get_domain / 2, get_domain_as_list / 2, get_median / 2, get_delta / 2, msg / 3, print_solver_var / 2, set_threshold / 1, set_threshold / 2, get_threshold / 1, is_in_domain / 2, is_in_domain / 3, delayed_goals_number / 2 from ic_kernel.
:- reexport struct(ic(_54744, _54745, _54746, _54747, _54748, _54749, _54750, _54751)) from ic_kernel.
:- reexport ic_constraints.
:- reexport ic_search.
:- tool((=\=) / 3).
:- tool((<) / 3).
:- tool((>) / 3).
:- tool((=<) / 3).
:- tool((>=) / 3).
:- tool((=:=) / 3).
:- tool((=\=) / 2).
:- tool((<) / 2).
:- tool((>) / 2).
:- tool((=<) / 2).
:- tool((>=) / 2).
:- tool((=:=) / 2).
:- comment(summary, "Hybrid integer/real interval arithmetic constraint solver").
:- comment(author, "Warwick Harvey, Andrew Sadler, Andrew Cheadle").
:- comment(desc, html("<P>\n   The IC (Interval Constraint) library is a hybrid integer/real interval\n   arithmetic constraint solver.  Its aim is to make it convenient for\n   programmers to write hybrid solutions to problems, mixing together\n   integer and real constraints and variables.</P><P>\n\n   The integer constraints and variables are similar to those available in\n   the old finite domain library `fd'.  The real constraints are similar to\n   those that were available in the old real interval arithmetic library\n   `ria'.  Constraints which are not specifically integer constraints can be\n   applied to either real or integer variables (or a mix) seamlessly, and\n   any real variable can be converted to an integer variable at any time by\n   imposing an integrality constraint on it.</P><P>\n\n   The IC library replaces the `fd', `ria' and `range' libraries (with a new\n   symbolic solver library providing the non-numeric functionality of `fd').\n   <P>\n   For more information, see the IC section of the constraint library manual\n   or the documentation for the individual IC predicates.</P><P>\n\n   The IC library solves constraint problems over the reals.  It is not\n   limited to linear constraints, so it can be used to solve general\n   problems like:\n   <PRE>\n   [eclipse 2]: ln(X) $>= sin(X).\n\n   X = X{0.36787944117144228 .. 1.0Inf}\n   yes.\n   </PRE>\n   <P>\n   The IC library handles linear and non-linear, reified constraints and\n   user defined functions. \n   <P>\n   User-defined functions/constraints are treated in a similar manner to\n   user defined functions found in expressions handled by is/2.  Note,\n   however, that user defined constraints/functions, when used in IC, should\n   be (semi-)deterministic.  User defined constraints/functions which leave\n   choice points may not behave as expected.\n   <P>\n   Linear constraints are handled by a single propagator, whereas non-linear\n   constraints are broken down into simpler ternary/binary/unary\n   propagators.  The value of any constraint found in an expression is its\n   reified truth value (0..1).\n   <P>\n   Variables appearing in arithmetic IC constraints at compile-time are\n   assumed to be IC variables unless they are wrapped in an <STRONG>eval/1</STRONG>\n   term.  The <STRONG>eval/1</STRONG> wrapper inside arithmetic constraints is used to\n   indicate that a variable will be bound to an expression at run-time.\n   This feature will only be used by programs which generate their\n   constraints dynamically at run-time, for example.\n   <PRE>\n   broken_sum(Xs,Sum):-\n       (\n\t   foreach(X,Xs),\n\t   fromto(Expr,S1,S2,0)\n       do\n\t   S1 = X + S2\n       ),\n       Sum $= Expr.\n   </PRE>\n   <P>\n   The above implementation of a summation constraint will not work as\n   intended because the variable <TT>Expr</TT> will be treated like an IC\n   variable when it is in fact the term <TT>+(X1,+(X2,+(...)))</TT> which is\n   constructed in the for-loop.  In order to get the desired functionality,\n   one must wrap the variable <TT>Expr</TT> in an <STRONG>eval/1</STRONG>.\n   <P>\n   <PRE>\n   working_sum(Xs,Sum):-\n       (\n\t   foreach(X,Xs),\n\t   fromto(Expr,S1,S2,0)\n       do\n\t   S1 = X + S2\n       ),\n       Sum $= eval(Expr).\n   </PRE>\n   <P>\n   The following arithmetic expression can be used inside the constraints:\n   <DL>\n   <DT><STRONG>X</STRONG><DD>\n\t    Variables.  If X is not yet an interval variable, it is turned \n\t    into one.\n\n   <DT><STRONG>123</STRONG><DD>\n\t    Integer constants.\n\n   <DT><STRONG>0.1</STRONG><DD>\n\t    Floating point constants.  These are assumed to be exact and\n\t    are converted to zero-width bounded reals.\n\n   <DT><STRONG>0.1__0.2</STRONG><DD>\n\t    Bounded real constants.\n\n   <DT><STRONG>pi, e</STRONG><DD>\n\t    Intervals enclosing the constants pi and e respectively.\n\n   <DT><STRONG>inf</STRONG><DD>\n\t    Floating point infinity.\n\n   <DT><STRONG>+Expr</STRONG><DD>\n\t    Identity.\n\n   <DT><STRONG>-Expr</STRONG><DD>\n\t    Sign change.\n\n   <DT><STRONG>+-Expr</STRONG><DD>\n\t    Expr or -Expr.  The result is an interval enclosing both.\n\n   <DT><STRONG>abs(Expr)</STRONG><DD>\n\t    The absolute value of Expr.\n\n   <DT><STRONG>E1+E2</STRONG><DD>\n\t    Addition.\n\n   <DT><STRONG>E1-E2</STRONG><DD>\n\t    Subtraction.\n\n   <DT><STRONG>E1*E2</STRONG><DD>\n\t    Multiplication.\n\n   <DT><STRONG>E1/E2</STRONG><DD>\n\t    Division.\n\n   <DT><STRONG>E1^E2</STRONG><DD>\n\t    Exponentiation.\n\n   <DT><STRONG>min(E1,E2)</STRONG><DD>\n\t    Minimum.\n\n   <DT><STRONG>max(E1,E2)</STRONG><DD>\n\t    Maximum.\n\n   <DT><STRONG>sqr(Expr)</STRONG><DD>\n\t    Square.  Logically equivalent to Expr*Expr, but with better \n\t    operational behaviour.\n\n   <DT><STRONG>sqrt(Expr)</STRONG><DD>\n\t    Square root (always positive).\n\n   <DT><STRONG>exp(Expr)</STRONG><DD>\n\t    Same as e^Expr.\n\n   <DT><STRONG>ln(Expr)</STRONG><DD>\n\t    Natural logarithm, the reverse of the exp function.\n\n   <DT><STRONG>sin(Expr)</STRONG><DD>\n\t    Sine.\n\n   <DT><STRONG>cos(Expr)</STRONG><DD>\n\t    Cosine.\n\n   <DT><STRONG>atan(Expr)</STRONG><DD>\n\t    Arcus tangens.  (Returns value between -pi/2 and pi/2.)\n\n   <DT><STRONG>rsqr(Expr)</STRONG><DD>\n\t    Reverse of the sqr function.  The same as +-sqrt(Expr).\n\n   <DT><STRONG>rpow(E1,E2)</STRONG><DD>\n\t    Reverse of exponentiation. i.e. finds X in E1 = X^E2.\n\n   <DT><STRONG>sub(Expr)</STRONG><DD>\n\t    A subinterval of Expr.\n\n   <DT><STRONG>sum(ExprList)</STRONG><DD>\n\t    Sum of a list of expressions.\n\n   <DT><STRONG>min(ExprList)</STRONG><DD>\n\t    Minimum of a list of expressions.\n\n   <DT><STRONG>max(ExprList)</STRONG><DD>\n\t    Maximum of a list of expressions.\n\n   <DT><STRONG>and</STRONG><DD>\n\t    Reified constraint conjunction.  e.g. X&gt;3 and Y&lt;8\n\n   <DT><STRONG>or</STRONG><DD>\n\t    Reified constraint disjunction.  e.g. X&gt;3 or Y&lt;8\n\n   <DT><STRONG>=&gt;</STRONG><DD>\n\t    Reified constraint implication.  e.g. X&gt;3 =&gt; Y&lt;8\n\n   <DT><STRONG>neg</STRONG><DD>\n\t    Reified constraint negation.  e.g. neg X&gt;3\n\n   <DT><STRONG>$=, $\\=, $&gt;, $&gt;=, $&lt;, $=&lt;, #=, #\\=, #&gt;, #&gt;=, #&lt;, #=&lt;,\n   =:=, =\\=, &gt;, &gt;=, &lt;, =&lt;, and, or, =&gt;, neg</STRONG><DD>\n\t    Constraints whose value is taken as their reified truth value\n\t    (0..1).\n\n   <DT><STRONG>foo(Arg1, Arg2 ... ArgN), module:foo(Arg1, Arg2 ...  ArgN)</STRONG></DT>\n\t    Call user-defined constraint/function foo.\n\n   <DT><STRONG>eval(Var)</STRONG><DD>\n\t    Var will be an expression at run-time.\n   </DL>\n")).
:- comment(#:: / 2, [amode : #::(?, ++), template : "?Vars #:: ++Domain", args : ["Vars" : "Variable or collection (a la collection_to_list/2) of variables", "Domain" : "Domain specification"], summary : "Constrain Vars to be integral and have the domain Domain.", see_also : [(::) / 2, $:: / 2], desc : html("<P>\n   Like ::/2, but constrains Vars to take only integer values from the given\n   domain.\n")]).
:- comment(#:: / 3, [amode : #::(?, ++, ?), template : "#::(?Var, ++Domain, ?Bool)", args : ["Var" : "Variable", "Domain" : "Domain specification", "Bool" : "Reified truth value"], summary : "Reflect into Bool the truth of Var having the domain Domain.", see_also : [integers / 1, reals / 1, _27329 : #:: / 2, #:: / 2, (::) / 3], desc : html("<P>\n   Provides a reified form of the #::/2 domain assignment predicate.  This\n   reified #::/3 is defined only to work for one variable and only integer\n   variables (unlike #::/2), hence only the Domain formats suitable for\n   integers may be supplied to this reified #::/3.\n   <P>\n   For a single variable, V, the Bool will be instantiated to 0 if the\n   current domain of V does not intersect with Domain.  It will be\n   instantiated to 1 iff the domain of V is wholly contained within Domain.\n   Finally the Boolean will remain an integer variable in the range 0..1, if\n   neither of the above two conditions hold.\n   <P>\n   Instantiating Bool to 1, will cause the constraint to behave exactly like\n   #::/2.  Instatiating Bool to 0 will cause Domain to be excluded from the\n   domain of the variable where such an exclusion is representable.  If such\n   an integer domain is unrepresentable (eg. -1.0Inf .. -5, 5..1.0Inf), then\n   a delayed goal will be setup to exclude values when the bounds become\n   sufficiently narrow.\n   <P>\n   Calling #::/3 with a range with real bounds eg. #::(X,1.0..10.0,B) will\n   result in a type error.\n   <P>\n   Note that calling the reified form of #:: will result in the Variable\n   becoming constrained to be integral, even if Bool is uninstantiated.\n   <P>\n   Further note that, like other reified predicates, #:: can be used infix in\n   an IC expression, e.g. B #= (X #:: [1..10]) is equivalent to\n   #::(X, [1..10], B).\n"), eg : "[eclipse 2]: #::(X, [1..10, 12..30],1).\n\nX = X{[1 .. 10, 12 .. 30]}\nYes (0.00s cpu)\n\n[eclipse 3]: #::(X, [1..10, 12..30],0).\nX = X{-1.0Inf .. 1.0Inf}\nDelayed goals:\n        exclude_range(X{-1.0Inf .. 1.0Inf}, 1, 10)\n        exclude_range(X{-1.0Inf .. 1.0Inf}, 12, 30)\nYes (0.00s cpu)\n\n[eclipse 4]: #::(X, [1..10, 12..30],B).\nX = X{-1.0Inf .. 1.0Inf}\nB = B{[0, 1]}\nDelayed goals:\n        ic : #::(X{-1.0Inf .. 1.0Inf}, [1 .. 10, 12 .. 30], B{[0, 1]})\nYes (0.00s cpu)\n\n[eclipse 5]: ic:( B =:= (X #:: [1..10,12..30])).\nB = B{[0, 1]}\nX = X{-1.0Inf .. 1.0Inf}\nDelayed goals:\n        ic : #::(X{-1.0Inf .. 1.0Inf}, [1 .. 10, 12 .. 30], B{[0, 1]})\nYes (0.00s cpu)\n\n"]).
:- comment((#<) / 2, [amode : (? #< ?), template : "?ExprX #< ?ExprY", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression"], summary : "ExprX is less than ExprY (with integrality constraints).", see_also : [(#=<) / 2, (#=) / 2, (#>=) / 2, (#>) / 2, (#\=) / 2, (<) / 2, (#<) / 3, _40696 : (#<) / 2], desc : html("<P>\n   Constrains ExprX to be less than ExprY.  Also constrains all variables\n   appearing in ExprX and ExprY to be integral and checks that all constants\n   are integers.</P>\n")]).
:- comment((#<) / 3, [amode : #<(?, ?, ?), template : "#<(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is less than ExprY (with integrality constraints).", see_also : [(#=<) / 3, (#=) / 3, (#>=) / 3, (#>) / 3, (#\=) / 3, (<) / 3, (#<) / 2, _41203 : (#<) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((#=) / 2, [amode : (? #= ?), template : "?ExprX #= ?ExprY", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression"], summary : "ExprX is equal to ExprY (with integrality constraints).", see_also : [(#<) / 2, (#=<) / 2, (#>=) / 2, (#>) / 2, (#\=) / 2, (=:=) / 2, (#=) / 3, _36278 : (#=) / 2], desc : html("<P>\n   Constrains ExprX and ExprY to be equal.  Also constrains all variables\n   appearing in ExprX and ExprY to be integral and checks that all constants\n   are integers.</P><P>\n\n   Note that if all variables and constants appearing in this constraint\n   are already integral, then the constraint is equivalent to\n   ic:(ExprX =:= ExprY).</P>\n")]).
:- comment((#=) / 3, [amode : #=(?, ?, ?), template : "#=(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is equal to ExprY (with integrality constraints).", see_also : [(#<) / 3, (#=<) / 3, (#>=) / 3, (#>) / 3, (#\=) / 3, (=:=) / 3, (#=) / 2, _36805 : (#=) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((#=<) / 2, [amode : (? #=< ?), template : "?ExprX #=< ?ExprY", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression"], summary : "ExprX is less than or equal to ExprY (with integrality constraints).", see_also : [(#<) / 2, (#=) / 2, (#>=) / 2, (#>) / 2, (#\=) / 2, (=<) / 2, (#=<) / 3, _38497 : (#=<) / 2], desc : html("<P>\n   Constrains ExprX to be less than or equal to ExprY.  Also constrains all\n   variables appearing in ExprX and ExprY to be integral and checks that all\n   constants are integers.</P><P>\n\n   Note that if all variables and constants appearing in this constraint\n   are already integral, then the constraint is equivalent to\n   ic:(ExprX =< ExprY).</P>\n")]).
:- comment((#=<) / 3, [amode : #=<(?, ?, ?), template : "#=<(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is less than or equal to ExprY (with integrality constraints).", see_also : [(#<) / 3, (#=) / 3, (#>=) / 3, (#>) / 3, (#\=) / 3, (=<) / 3, (#=<) / 2, _39027 : (#=<) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((#>) / 2, [amode : (? #> ?), template : "?ExprX #> ?ExprY", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression"], summary : "ExprX is strictly greater than ExprY (with integrality constraints).", see_also : [(#<) / 2, (#=<) / 2, (#=) / 2, (#>=) / 2, (#\=) / 2, (>) / 2, (#>) / 3, _39608 : (#>) / 2], desc : html("<P>\n   Constrains ExprX to be greater than ExprY.  Also constrains all variables\n   appearing in ExprX and ExprY to be integral and checks that all constants\n   are integers.</P>\n")]).
:- comment((#>) / 3, [amode : #>(?, ?, ?), template : "#>(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is strictly greater than ExprY (with integrality constraints).", see_also : [(#<) / 3, (#=<) / 3, (#=) / 3, (#>=) / 3, (#\=) / 3, (>) / 3, (#>) / 2, _40116 : (#>) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((#>=) / 2, [amode : (? #>= ?), template : "?ExprX #>= ?ExprY", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression"], summary : "ExprX is greater than or equal to ExprY (with integrality constraints).", see_also : [(#<) / 2, (#=<) / 2, (#=) / 2, (#>) / 2, (#\=) / 2, (>=) / 2, (#>=) / 3, _37386 : (#>=) / 2], desc : html("<P>\n   Constrains ExprX to be greater than or equal to ExprY.  Also constrains\n   all variables appearing in ExprX and ExprY to be integral and checks that\n   all constants are integers.</P><P>\n\n   Note that if all variables and constants appearing in this constraint\n   are already integral, then the constraint is equivalent to\n   ic:(ExprX >= ExprY).</P>\n")]).
:- comment((#>=) / 3, [amode : #>=(?, ?, ?), template : "#>=(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is greater than or equal to ExprY (with integrality constraints).", see_also : [(#<) / 3, (#=<) / 3, (#=) / 3, (#>) / 3, (#\=) / 3, (>=) / 3, (#>=) / 2, _37916 : (#>=) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((#\=) / 2, [amode : (? #\= ?), template : "?ExprX #\\= ?ExprY", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression"], summary : "ExprX is not equal to ExprY (with integrality constraints).", see_also : [(#<) / 2, (#=<) / 2, (#=) / 2, (#>=) / 2, (#>) / 2, (=\=) / 2, (#\=) / 3, _41783 : (#\=) / 2], desc : html("<P>\n   Constrains ExprX to be not equal to ExprY.  Also constrains all variables\n   appearing in ExprX and ExprY to be integral and checks that all constants\n   are integers.</P><P>\n\n   Note that if all variables and constants appearing in this constraint\n   are already integral, then the constraint is equivalent to\n   ic:(ExprX =\\= ExprY).</P>\n")]).
:- comment((#\=) / 3, [amode : #\=(?, ?, ?), template : "#\\=(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Integer arithmetic expression", "ExprY" : "Integer arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is not equal to ExprY (with integrality constraints).", see_also : [(#<) / 3, (#=<) / 3, (#=) / 3, (#>=) / 3, (#>) / 3, (=\=) / 3, (#\=) / 2, _42311 : (#\=) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment($:: / 2, [amode : $::(?, ++), template : "?Vars $:: ++Domain", args : ["Vars" : "Variable or collection (a la collection_to_list/2) of variables", "Domain" : "Domain specification"], summary : "Constrain Vars to have the domain Domain.", see_also : [(::) / 2, #:: / 2], desc : html("<P>\n   Like ::/2, but does not perform any type analysis on the domain and does\n   not enforce integrality on the variables even if the domain specified has\n   integer bounds.  Domain must be a contiguous interval.\n")]).
:- comment($:: / 3, [amode : $::(?, ++, ?), template : "$::(?Var, ++Domain, ?Bool)", args : ["Var" : "Variable", "Domain" : "Domain specification", "Bool" : "Reified truth value"], summary : "Reflect into Bool the truth of Var having the domain Domain. Does not impose integrality.", see_also : [integers / 1, reals / 1, _26688 : $:: / 2, $:: / 2, (::) / 3], desc : html("<P>\n   Provides a reified form of the $::/2 domain assignment predicate.  This\n   reified $::/3 is defined only to work for one variable and real \n   variables (unlike ::/3), hence only the Domain formats suitable for\n   reals may be supplied to this reified $::/3.\n   <P>\n   For a single variable, V, the Bool will be instantiated to 0 if the\n   current domain of V does not intersect with Domain.  It will be\n   instantiated to 1 iff the domain of V is wholly contained within Domain.\n   Finally the Boolean will remain an integer variable in the range 0..1, if\n   neither of the above two conditions hold.\n   <P>\n   Instantiating Bool to 1, will cause the constraint to behave exactly like\n   $::/2.  Instatiating Bool to 0 will cause a set of delayed goals to\n   excluded the range from the domain of the variable where such an\n   exclusion is representable.\n   <P>\n   Note that calling the reified form of $:: will NOT result in the Variable\n   becoming constrained to be integral, even if domain contains only integers.\n   <P>\n   Further note that, like other reified predicates, $:: can be used infix in\n   an IC expression, e.g. B #= (X $:: [1..10]) is equivalent to\n   $::(X, [1..10], B).\n"), eg : "[eclipse 2]: $::(X, 1..30,1).\n\nX = X{1.0 .. 30.0}\nYes (0.00s cpu)\n\n[eclipse 3]: $::(X, [1..10, 12..30],0).\n\nAbort\ntype error in $::(X, [1 .. 10, 12 .. 30], 0)\n\n[eclipse 4]: $::(X, 1.0..30.0,B).\n\nX = X{-1.0Inf .. 1.0Inf}\nB = B{[0, 1]}\nThere are 3 delayed goals.\nYes (0.00s cpu)\n"]).
:- comment($< / 2, [amode : $<(?, ?), template : "?ExprX $< ?ExprY", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is strictly less than ExprY.", see_also : [(<) / 2], desc : html("<P>\n   Constrains ExprX to be strictly less than ExprY.  Alternate form of\n   ic:(ExprX < ExprY).\n")]).
:- comment($= / 2, [amode : $=(?, ?), template : "?ExprX $= ?ExprY", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is equal to ExprY.", see_also : [(=:=) / 2], desc : html("<P>\n   Constrains ExprX and ExprY to be equal.  Alternate form of\n   ic:(ExprX =:= ExprY).\n")]).
:- comment($=< / 2, [amode : $=<(?, ?), template : "?ExprX $=< ?ExprY", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is less than or equal to ExprY.", see_also : [(=<) / 2], desc : html("<P>\n   Constrains ExprX to be less than or equal to ExprY.  Alternate form of\n   ic:(ExprX =< ExprY).\n")]).
:- comment($> / 2, [amode : $>(?, ?), template : "?ExprX $> ?ExprY", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is strictly greater than ExprY.", see_also : [(>) / 2], desc : html("<P>\n   Constrains ExprX to be strictly greater than ExprY.  Alternate form of\n   ic:(ExprX > ExprY).\n")]).
:- comment($>= / 2, [amode : $>=(?, ?), template : "?ExprX $>= ?ExprY", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is greater than or equal to ExprY.", see_also : [(>=) / 2], desc : html("<P>\n   Constrains ExprX to be greater than or equal to ExprY.  Alternate form of\n   ic:(ExprX >= ExprY).\n")]).
:- comment($\= / 2, [amode : $\=(?, ?), template : "?ExprX $\\= ?ExprY", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is not equal to ExprY.", see_also : [(=\=) / 2], desc : html("<P>\n   Constrains ExprX and ExprY to not be equal.  Alternate form of\n   ic:(ExprX =\\= ExprY).\n")]).
:- comment((::) / 2, [amode : (? :: ++), template : "?Vars :: ++Domain", args : ["Vars" : "Variable or collection (a la collection_to_list/2) of variables", "Domain" : "Domain specification"], summary : "Constrain Vars to have the domain Domain.", see_also : [integers / 1, reals / 1, _25283 : (::) / 2, (::) / 3, #:: / 2, $:: / 2], desc : html("<P>\n   Constrains Vars to take only integer or real values from the domain\n   specified by Domain.  Vars may be a variable or a collection of variables\n   (as accepted by collection_to_list/2).  Domain can be specified as a\n   simple range Lo .. Hi, or as a list of subranges and/or individual\n   elements.  Multiple subranges and/or individual elements are allowed in\n   integer domains only.  If all subrange bounds and individual elements are\n   integers the domain is considered an integer domain and the variables\n   Vars are constrained to be integral; otherwise it is considered a real\n   domain and the type of the variables is not constrained.  Note that\n   infinities are considered to be untyped for this purpose.\n<P>\n   For instance:\n<PRE>\n     X :: 0..1                  % boolean\n     X :: -1..5                 % integer between -1 and 5\n     X :: 1..inf                % strictly positive integer\n     X :: 0.0..10.0             % real between 0.0 and 10.0\n     X :: 1.5..3.7              % real between 1.5 and 3.7\n     X :: 0.0..5                % real between 0.0 and 5.0\n     X :: 1.4__1.6..3.6__3.8    % real where the bounds aren't known exactly\n     X :: breal(0)..inf         % nonnegative real\n     X :: [0..3, 5, 8..10]      % any integer from 0 to 10 except 4 and 6\n     [X, Y, Z] :: 1..8          % apply domain to X, Y and Z\n     M[2..4, 5] :: 1..8         % apply to rows 2..4, column 5 of matrix M\n     X :: [0.0..5.0, 7.0..9.0]  % Type error\n     X :: [a, b, c]             % Type error\n</PRE>\n"), eg : "[eclipse 2]: X :: 0..1.\nX = X{[0, 1]}\nYes (0.00s cpu)\n\n[eclipse 3]: X :: -1..5.\nX = X{-1 .. 5}\nYes (0.00s cpu)\n\n[eclipse 4]: X :: 1..inf.\nX = X{1 .. 1.0Inf}\nYes (0.00s cpu)\n\n[eclipse 5]: X :: 0.0..10.0.\nX = X{0.0 .. 10.0}\nYes (0.00s cpu)\n\n[eclipse 6]: X :: 1.5..3.7.\nX = X{1.5 .. 3.7}\nYes (0.00s cpu)\n\n[eclipse 7]: X :: 1.4__1.6..3.6__3.8.\nX = X{1.4 .. 3.8}\nDelayed goals:\n        ic : (-(X{1.4 .. 3.8}) =< -1.6__-1.4)\n        ic : (X{1.4 .. 3.8} =< 3.6__3.8)\nYes (0.00s cpu)\n\n[eclipse 8]: X :: [0..3, 5, 8..10].\nX = X{[0 .. 3, 5, 8 .. 10]}\nYes (0.00s cpu)\n"]).
:- comment((::) / 3, [amode : ::(?, ++, ?), template : "::(?Var, ++Domain, ?Bool)", args : ["Var" : "Variable", "Domain" : "Domain specification", "Bool" : "Reified truth value"], summary : "Reflect into Bool the truth of Var having the domain Domain.", see_also : [integers / 1, reals / 1, _26001 : (::) / 2, (::) / 2], desc : html("<P>\n   Provides a reified form of the ::/2 domain assignment predicate.  This\n   reified ::/3 is defined only to work for one variable and only integer\n   variables (unlike ::/2), hence only the Domain formats suitable for\n   integers may be supplied to this reified ::/3.\n<P>\n   For a single variable, V, the Bool will be instantiated to 0 if the\n   current domain of V does not intersect with Domain.  It will be\n   instantiated to 1 iff the domain of V is wholly contained within Domain.\n   Finally the Boolean will remain an integer variable in the range 0..1, if\n   neither of the above two conditions hold.\n<P>\n   Instantiating Bool to 1, will cause the constraint to behave exactly like\n   ::/2.  Instatiating Bool to 0 will cause Domain to be excluded from the\n   domain of the variable where such an exclusion is representable.  If such\n   an integer domain is unrepresentable (eg. -1.0Inf .. -5, 5..1.0Inf), then\n   a delayed goal will be setup to exclude values when the bounds become\n   sufficiently narrow.\n<P>\n   Note that calling the reified form of :: will result in the Variable\n   becoming constrained to be integral, even if Bool is uninstantiated.\n<P>\n   Further note that, like other reified predicates, :: can be used infix in\n   an IC expression, e.g. B #= (X :: [1..10]) is equivalent to\n   ::(X, [1..10], B).\n"), eg : "[eclipse 2]: ::(X, [1..10, 12..30],1).\n\nX = X{[1 .. 10, 12 .. 30]}\nYes (0.00s cpu)\n\n[eclipse 3]: ::(X, [1..10, 12..30],0).\nX = X{-1.0Inf .. 1.0Inf}\nDelayed goals:\n        exclude_range(X{-1.0Inf .. 1.0Inf}, 1, 10)\n        exclude_range(X{-1.0Inf .. 1.0Inf}, 12, 30)\nYes (0.00s cpu)\n\n[eclipse 4]: ::(X, [1..10, 12..30],B).\nX = X{-1.0Inf .. 1.0Inf}\nB = B{[0, 1]}\nDelayed goals:\n        ic : ::(X{-1.0Inf .. 1.0Inf}, [1 .. 10, 12 .. 30], B{[0, 1]})\nYes (0.00s cpu)\n\n[eclipse 5]: ic:( B =:= (X :: [1..10,12..30])).\nB = B{[0, 1]}\nX = X{-1.0Inf .. 1.0Inf}\nDelayed goals:\n        ic : ::(X{-1.0Inf .. 1.0Inf}, [1 .. 10, 12 .. 30], B{[0, 1]})\nYes (0.00s cpu)\n\n"]).
:- comment((<) / 2, [amode : (? < ?), template : "ic:(?ExprX < ?ExprY)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is strictly less than ExprY.", see_also : [(=<) / 2, (=:=) / 2, (>=) / 2, (>) / 2, (=\=) / 2, (#<) / 2, (<) / 3, _34153 : (<) / 2], desc : html("<P>\n   Constrains ExprX to be strictly less than ExprY.</P>\n")]).
:- comment((<) / 3, [amode : <(?, ?, ?), template : "<(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is strictly less than ExprY.", see_also : [(=<) / 3, (=:=) / 3, (>=) / 3, (>) / 3, (=\=) / 3, (#<) / 3, (<) / 2, _34640 : (<) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((=:=) / 2, [amode : (? =:= ?), template : "ic:(?ExprX =:= ?ExprY)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is equal to ExprY.", see_also : [(<) / 2, (=<) / 2, (>=) / 2, (>) / 2, (=\=) / 2, (#=) / 2, (=:=) / 3, _29905 : (=:=) / 2], desc : html("<P>\n   Constrains ExprX and ExprY to be equal.\n")]).
:- comment((=:=) / 3, [amode : =:=(?, ?, ?), template : "=:=(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is equal to ExprY.", see_also : [(<) / 3, (=<) / 3, (>=) / 3, (>) / 3, (=\=) / 3, (#=) / 3, (=:=) / 2, _30389 : (=:=) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((=<) / 2, [amode : (? =< ?), template : "ic:(?ExprX =< ?ExprY)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is less than or equal to ExprY.", see_also : [(<) / 2, (=:=) / 2, (>=) / 2, (>) / 2, (=\=) / 2, (#=<) / 2, (=<) / 3, _33091 : (=<) / 2], desc : html("<P>\n   Constrains ExprX to be less than or equal to ExprY.</P>\n")]).
:- comment((=<) / 3, [amode : =<(?, ?, ?), template : "=<(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is less than or equal to ExprY.", see_also : [(<) / 3, (=:=) / 3, (>=) / 3, (>) / 3, (=\=) / 3, (#=<) / 3, (=<) / 2, _33578 : (=<) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment(=> / 2, [amode : =>(+, +), template : "+ConX => +ConY", args : ["ConX" : "Constraint", "ConY" : "Constraint"], summary : "Constraint ConX being true implies ConY must both be true.", see_also : [=> / 3, neg / 1, neg / 2, or / 2, or / 3, and / 2, and / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to BX $= (ConX), BY $= (ConY), BX #=< BY</P>\n   <P>\n   The two constraints are reified in such a way that ConX being true\n   implies that ConY must also be true.  ConX and ConY must be constraints\n   that have a corresponding reified form.\n")]).
:- comment(=> / 3, [amode : =>(+, +, ?), template : "=>(+ConX,+ConY,Bool)", args : ["ConX" : "Constraint", "ConY" : "Constraint", "Bool" : "Reified truth value of the constraint"], summary : "Bool is the reified truth of constraint ConX implying the truth of ConY.", see_also : [=> / 2, neg / 1, neg / 2, or / 2, or / 3, and / 2, and / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to BX $= (ConX), BY $= (ConY), Bool #= (BX #=< BY)</P>\n   <P>\n   The two constraints are reified in such a way that Bool is true if ConX\n   being true implies that ConY must also be true.  ConX and ConY must be\n   constraints that have a corresponding reified form.\n")]).
:- comment((=\=) / 2, [amode : (? =\= ?), template : "ic:(?ExprX =\\= ?ExprY)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is not equal to ExprY.", see_also : [(<) / 2, (=<) / 2, (>=) / 2, (>) / 2, (=:=) / 2, (#\=) / 2, (=\=) / 3, _35214 : (=\=) / 2], desc : html("<P>\n   Constrains ExprX and ExprY to be different.\n")]).
:- comment((=\=) / 3, [amode : =\=(?, ?, ?), template : "=\\=(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is not equal to ExprY.", see_also : [(<) / 3, (=<) / 3, (>=) / 3, (>) / 3, (=:=) / 3, (#\=) / 3, (=\=) / 2, _35699 : (=\=) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((>) / 2, [amode : (? > ?), template : "ic:(?ExprX > ?ExprY)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is strictly greater than ExprY.", see_also : [(<) / 2, (=<) / 2, (=:=) / 2, (>=) / 2, (=\=) / 2, (#>) / 2, (>) / 3, _32029 : (>) / 2], desc : html("<P>\n   Constrains ExprX to be strictly greater than ExprY.</P>\n")]).
:- comment((>) / 3, [amode : >(?, ?, ?), template : ">(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is strictly greater than ExprY.", see_also : [(<) / 3, (=<) / 3, (=:=) / 3, (>=) / 3, (=\=) / 3, (#>) / 3, (>) / 2, _32516 : (>) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment((>=) / 2, [amode : (? >= ?), template : "ic:(?ExprX >= ?ExprY)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression"], summary : "ExprX is greater than or equal to ExprY.", see_also : [(<) / 2, (=<) / 2, (=:=) / 2, (>) / 2, (=\=) / 2, (#>=) / 2, (>=) / 3, _30965 : (>=) / 2], desc : html("<P>\n   Constrains ExprX to be greater than or equal to ExprY.</P>\n")]).
:- comment((>=) / 3, [amode : >=(?, ?, ?), template : ">=(?ExprX, ?ExprY, ?Bool)", args : ["ExprX" : "Arithmetic expression", "ExprY" : "Arithmetic expression", "Bool" : "Reified truth value of the constraint"], summary : "Reified ExprX is greater than or equal to ExprY.", see_also : [(<) / 3, (=<) / 3, (=:=) / 3, (>) / 3, (=\=) / 3, (#>=) / 3, (>=) / 2, _31454 : (>=) / 3], desc : html("<P>\n   This predicate is a reified constraint: it succeeds if and only if the\n   truth value of its associated constraint (the constraint with arity one\n   less and the same arguments except for B) is equal to B, where the value\n   0 means false and 1 true.  This constraint can be used both to test the\n   validity of the associated constraint (entailment test) and to impose\n   this constraint or its negation.  For the former, B will be instantiated\n   as soon as either the associated constraint or its negation is subsumed\n   by the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the associated\n   constraint or its negation will be imposed on its arguments.</P>\n")]).
:- comment(ac_eq / 3, [amode : ac_eq(?, ?, ++), args : ["X" : "Variable or integer", "Y" : "Variable or integer", "C" : "Integer constant"], summary : "Arc-consistent implementation of X #= Y + C.", see_also : [(#=) / 2], desc : html("<P>\n   This constraint implements an arc-consistent version of X #= Y + C (i.e.\n   any \"holes\" in the domain of X are propagated to Y and vice-versa).<P>\n\n   A range error is thrown if X and Y do not have \"reasonable\" bounds\n   (roughly +/- 2^30 on a 32-bit machine, roughly +/- 2^52 on a 64-bit\n   machine: note that even much smaller bounds than this can lead to\n   available memory being exhausted very rapidly, if not immediately).\n")]).
:- comment(alldifferent / 1, [amode : alldifferent(+), args : ["Vars" : "A collection (a la collection_to_list/2) of variables or integers"], summary : "Constrains all elements of a list to be pairwise different.", see_also : [(#\=) / 2, _43594 : alldifferent / 1, collection_to_list / 2], desc : html("<P>\n   Constrains all elements of a collection to be pairwise different (and\n   integral).  Effectively imposes #\\= constraints on every pair of\n   elements from Vars.</P>\n")]).
:- comment(and / 2, [amode : and(+, +), template : "+ConX and +ConY", args : ["ConX" : "Constraint", "ConY" : "Constraint"], summary : "Constraints ConX and ConY must both be true.", see_also : [and / 3, neg / 1, neg / 2, or / 2, or / 3, => / 2, => / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to BX $= (ConX), BY $= (ConY), BX + BY #= 2</P>\n   <P>\n   The two constraints are reified in such a way that both must be true.\n   ConX and ConY must be a constraints that have a corresponding reified\n   form.\n")]).
:- comment(and / 3, [amode : and(+, +, ?), template : "and(+ConX,+ConY,Bool)", args : ["ConX" : "Constraint", "ConY" : "Constraint", "Bool" : "Reified truth value of the constraint"], summary : "Bool is the reified truth of both constraints ConX and ConY being true.", see_also : [and / 2, neg / 1, neg / 2, or / 2, or / 3, => / 2, => / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to BX $= (ConX), BY $= (ConY), Bool #= (BX + BY #= 2)</P>\n   <P>\n   The two constraints are reified in such a way that Bool reflects the\n   truth of both being true.  ConX and ConY must be constraints that have a\n   corresponding reified form.\n")]).
:- comment(delayed_goals_number / 2, [amode : delayed_goals_number(?, -), args : ["Var" : "Variable or term", "Number" : "Number of goals delayed on the ic attribute of Var."], summary : "Returns the number of goals delayed on the ic attribute of Var.", desc : html("   N is the number of constraints and suspended goals currently attached to\n   the IC attribute of the variable Var.  Note that this number may not\n   correspond to the exact number of different constraints attached to Var,\n   as goals in different suspension lists are counted separately, and a\n   constraint may decompose into more than one suspension.  This predicate\n   is often used when looking for the most or least constrained variable\n   from a set of domain variables.  If Var is not a variable, N is bound to\n   1.0Inf; otherwise if Var is not an IC variable, N is zero.\n</P><P>\n   Note that this predicate only counts goals attached to the IC attribute;\n   if you want to count all goals attached to a variable, use the generic\n   delayed_goals_number/2.\n"), see_also : [_24300 : delayed_goals_number / 2]]).
:- comment(delete / 5, [summary : "Choose a domain variable from a list according to selection criteria.", amode : delete(-, +, -, ++, ++), args : ["X" : " a free variable", "List" : " a list of variables or terms ", "R" : " a free variable ", "Arg" : " an integer", "Select" : " the name of the selection criteria"], desc : html("\nThis predicate chooses one entry in a list of variables or terms based\non some selection criteria.  The criteria are explained in detail in\nthe <b>search/6</b> predicate.<p>\n"), fail_if : "fails if the list is empty", resat : no, eg : "\n", see_also : [search / 6]]).
:- comment(element / 3, [summary : "Value is the Index'th element of the integer list List.", template : "element(?Index, ++List, ?Value)", args : ["?Index" : "A variable or an integer.", "++List" : "A non-empty list or array of integers.", "?Value" : "A variable or an integer."], resat : "No.", fail_if : "Fails if Value is not the Index'th element of List.", desc : html("This constraint can be used in a variety of programs to state a\n   relation between two domain variables.  List is a list of integers and\n   the constraint states that its Index'th element is equal to Value, i.e.\n<P>\n<PRE>\n\t\t\t     List_Index = Value\n</PRE>\n   Every time Index or Value is updated, this constraint is activated and\n   the domain of the other variable is updated accordingly.\n<P>\n"), eg : "\n   [eclipse 13]: element(I, [1,3,6,3], V).\n   I = I{1 .. 4}\n   V = V{[1, 3, 6]}\n   Delayed goals:\n   element(I{1 .. 4}, [1, 3, 6, 3], V{[1, 3, 6]})\n   yes.\n   [eclipse 14]: element(I, [1,3,6,3], V), V #\\= 3.\n   I = I{[1, 3]}\n   V = V{[1, 6]}\n   Delayed goals:\n   element(I{[1, 3]}, [1, 3, 6, 3], V{[1, 6]})\n   yes.\n", see_also : [(::) / 2]]).
:- comment(get_bounds / 3, [amode : get_bounds(-, -, -), amode : get_bounds(?, -, -), amode : get_bounds(++, -, -), args : ["Var" : "A variable or a number", "Lo" : "Lower bound", "Hi" : "Upper bound"], summary : "Retrieve the current bounds of Var.", see_also : [get_min / 2, get_max / 2, get_float_bounds / 3, get_integer_bounds / 3, get_finite_integer_bounds / 3, get_delta / 2, get_median / 2], desc : html("<P>\n   Primitive for retrieving the upper and lower bounds of Var.  Lo and Hi\n   return the minimum and maximum (respectively) of the variable's interval.\n   If the variable is integer and a bound is finite, then that bound will be\n   returned as an integer; in all other cases it will be returned as a\n   float.  If Var has not been declared before, it will be turned into an\n   unrestricted real variable.  If Var is a ground number, Lo and Hi will\n   give appropriate bounds based on the type and value of Var: exact bounds\n   for floats, bounded reals and integers, and best safe approximations for\n   rationals.</P>\n")]).
:- comment(get_delta / 2, [amode : get_delta(-, -), amode : get_delta(?, -), amode : get_delta(++, -), args : ["Var" : "A variable or a number", "Width" : "Width of the interval"], summary : "Returns the width of the interval of Var.", see_also : [get_median / 2, get_bounds / 3], desc : html("<P>\n   Returns the width (Hi - Lo) of the interval of Var.  If Var has not been\n   declared before, it will be turned into an unrestricted real variable.\n   If Var is a ground number, the width will be calculated appropriately\n   based on its type.</P>\n")]).
:- comment(get_domain / 2, [amode : get_domain(?, -), amode : get_domain(?, ++), args : ["Var" : "An IC variable or a number.", "Domain" : "A ground representation of the domain of Var."], summary : "Returns a ground representation of the current IC domain of a variable.", see_also : [get_domain_as_list / 2, get_bounds / 3], desc : html("<P>\n   If Var is a number, Domain will be unified with that number.</P><P>\n\n   If Var is a real IC variable, Domain will be unified with the term\n   Lo..Hi where Lo and Hi are floats corresponding to the current lower\n   and upper bounds of Var, respectively.</P><P>\n\n   If Var is an integer IC variable with no holes in its domain, Domain will\n   be unified with the term Lo..Hi where Lo and Hi are integers\n   corresponding to the current lower and upper bounds of Var, respectively.</P><P>\n\n   If Var is an integer IC variable with holes in its domain, Domain will\n   be unified with an ordered list of integers and/or terms Lo..Hi where Lo\n   and Hi are integers; in this case the elements of the domain of Var are\n   exactly those integers appearing directly in the list or falling within\n   any of the intervals Lo..Hi.</P>\n"), exceptions : [5 : "Var is neither an IC variable or number.", 6 : "Var is a IC variable of type real."], fail_if : "The initial value of DomainList fails to unify with the returned value."]).
:- comment(get_domain_as_list / 2, [amode : get_domain_as_list(?, -), amode : get_domain_as_list(?, ++), args : ["Var" : "An IC variable or a number", "DomainList" : "The domain of Var as a list of elements."], summary : "List of all the elements in the IC domain of Var", see_also : [get_domain / 2, get_bounds / 3], desc : html("<P>\n   If Var is an integer IC variable, DomainList will be set to an ordered\n   list containing each element in the domain of Var.  If Var is a number,\n   then DomainList will be set to a singleton list containing the number.</P><P>\n\n   Currently, an out of range exception would be raised if Var is an IC \n   variable of type real.  This may change in the future.</P>\n"), exceptions : [5 : "Var is neither an IC variable or number.", 6 : "Var is a IC variable of type real."], fail_if : "The initial value of DomainList fails to unify with the returned value."]).
:- comment(get_domain_size / 2, [amode : get_domain_size(?, -), amode : get_domain_size(?, ++), amode : get_domain_size(++, -), amode : get_domain_size(++, ++), args : ["Var" : "An IC variable or a number", "Size" : "A variable (or integer)"], summary : "Size is the number of integer elements in the IC domain for Var", see_also : [get_delta / 2], desc : html("<P>\n   If Var is an integer IC variable, Size will be set to the number of \n   integer values in the domain of Var.  If Var is a number, then Size \n   will be set to 1.</P><P>\n\n   Currently, an out of range exception would be raised if Var is an IC \n   variable of type real.  This may change in the future.</P>\n"), exceptions : [5 : "Var is neither an IC variable or number.", 6 : "Var is a IC variable of type real."], fail_if : "The initial value of Size fails to unify with the returned value."]).
:- comment(get_finite_integer_bounds / 3, [amode : get_finite_integer_bounds(-, -, -), amode : get_finite_integer_bounds(?, -, -), amode : get_finite_integer_bounds(++, -, -), args : ["Var" : "A variable or a number", "Lo" : "Lower bound", "Hi" : "Upper bound"], summary : "Retrieve the current (finite, integral) bounds of Var.", see_also : [get_bounds / 3, get_integer_bounds / 3, get_float_bounds / 3], desc : html("<P>\n   Primitive for retrieving the (finite, integral) upper and lower bounds of\n   Var.  Lo and Hi return the minimum and maximum (respectively) of the\n   variable's interval.  If Var has not been declared before, it will be\n   turned into an integer variable.  If Var is a real IC variable, it will\n   be constrained to be integral.  If any bound is infinite, it has a\n   default bound imposed to make it finite (-10000000 for lower bounds,\n   10000000 for upper bounds).  (These changes may cause propagation.)\n   Bounds are always returned as integers.  If Var is a ground integer, Lo\n   and Hi will unified with that integer.  All other cases result in a type\n   error.</P>\n")]).
:- comment(get_float_bounds / 3, [amode : get_float_bounds(-, -, -), amode : get_float_bounds(?, -, -), amode : get_float_bounds(++, -, -), args : ["Var" : "A variable or a number", "Lo" : "Lower bound", "Hi" : "Upper bound"], summary : "Retrieve the current bounds of Var as floats.", see_also : [get_bounds / 3, get_integer_bounds / 3, get_finite_integer_bounds / 3, get_delta / 2, get_median / 2], desc : html("<P>\n   Primitive for retrieving the upper and lower bounds of Var.  Lo and Hi\n   return the minimum and maximum (respectively) of the variable's interval\n   in floating point format (regardless of the variable's type).  If Var has\n   not been declared before, it will be turned into an unrestricted real\n   variable.  If Var is a ground number, Lo and Hi will give appropriate\n   bounds based on the type and value of Var: exact bounds for floats,\n   bounded reals and exactly representable integers, and best safe\n   approximations for large integers and rationals.</P>\n")]).
:- comment(get_integer_bounds / 3, [amode : get_integer_bounds(-, -, -), amode : get_integer_bounds(?, -, -), amode : get_integer_bounds(++, -, -), args : ["Var" : "A variable or a number", "Lo" : "Lower bound", "Hi" : "Upper bound"], summary : "Retrieve the current bounds of (integral) Var.", see_also : [get_bounds / 3, get_finite_integer_bounds / 3, get_float_bounds / 3], desc : html("<P>\n   Primitive for retrieving the upper and lower bounds of (integral) Var.\n   Lo and Hi return the minimum and maximum (respectively) of the variable's\n   interval.  If Var has not been declared before, it will be turned into an\n   unrestricted integer variable.  If Var is a real IC variable, it will be\n   constrained to be integral.  (These changes may cause propagation.)\n   Infinite bounds are returned as floating point numbers; all others are\n   returned as integers.  If Var is a ground integer, Lo and Hi will unified\n   with that integer.  All other cases result in a type error.</P>\n")]).
:- comment(get_max / 2, [amode : get_max(-, -), amode : get_max(?, -), amode : get_max(++, -), args : ["Var" : "A variable or a number", "Hi" : "Upper bound"], summary : "Retrieve the current upper bound of Var.", see_also : [get_bounds / 3, get_float_bounds / 3, get_integer_bounds / 3, get_finite_integer_bounds / 3], desc : html("<P>\n   Primitive for retrieving the upper bound of Var.  Hi returns the maximum\n   of the variable's interval.  If the variable is integer and the bound is\n   finite, then the bound will be returned as an integer; in all other cases\n   it will be returned as a float.  If Var has not been declared before, it\n   will be turned into an unrestricted real variable.  If Var is a ground\n   number, Hi will give an appropriate bound based on the type and value of\n   Var: an exact bound for floats, bounded reals and integers, and a best\n   safe approximation for rationals.</P>\n")]).
:- comment(get_median / 2, [amode : get_median(-, -), amode : get_median(?, -), amode : get_median(++, -), args : ["Var" : "A variable or a number", "Median" : "The median of the interval (float)"], summary : "Returns the median of the interval of the IC variable Var.", see_also : [get_delta / 2, get_bounds / 3, get_float_bounds / 3], desc : html("<P>\n   Returns the median of the interval of Var (usually so that the interval\n   can be split) as a float value.  If Var has not been declared before,\n   it will be turned into an unrestricted real variable as a side effect.\n   If Var is a ground number, the median is a float equal or near that\n   number.\n\n   Generally, the median splits the interval logarithmically so that the\n   two subintervals have roughly the same number of representable floats.\n   Only in the vicinity of zero, splitting is linear to prevent the sub-\n   intervals from getting too small.</P>\n"), eg : "[eclipse 2]: X :: 10..1000, get_median(X, M).\nX = X{10 .. 1000}\nM = 100.0\nYes (0.00s cpu)\n\n[eclipse 3]: X :: -1..1000, get_median(X, M).\nX = X{-1 .. 1000}\nM = 11.633369384516794\nYes (0.00s cpu)\n\n[eclipse 4]: get_median(3, M).\nM = 3.0\nYes (0.00s cpu)\n"]).
:- comment(get_min / 2, [amode : get_min(-, -), amode : get_min(?, -), amode : get_min(++, -), args : ["Var" : "A variable or a number", "Lo" : "Lower bound"], summary : "Retrieve the current lower bound of Var.", see_also : [get_bounds / 3, get_float_bounds / 3, get_integer_bounds / 3, get_finite_integer_bounds / 3], desc : html("<P>\n   Primitive for retrieving the lower bound of Var.  Lo returns the minimum\n   of the variable's interval.  If the variable is integer and the bound is\n   finite, then the bound will be returned as an integer; in all other cases\n   it will be returned as a float.  If Var has not been declared before, it\n   will be turned into an unrestricted real variable.  If Var is a ground\n   number, Lo will give an appropriate bound based on the type and value of\n   Var: an exact bound for floats, bounded reals and integers, and a best\n   safe approximation for rationals.</P>\n")]).
:- comment(get_solver_type / 2, [amode : get_solver_type(-, -), amode : get_solver_type(?, -), amode : get_solver_type(++, -), args : ["Var" : "A variable or a number", "Type" : "Type of Var (real or integer)"], summary : "Retrieve the type of a variable.", fail_if : "Var is not a variable or a number.", desc : html("<P>\n   Retrieve the type (the atom 'real' or the atom 'integer') of a variable\n   (or number).  If Var has not been declared before, it will be turned into\n   an unrestricted real variable.  If Var is a ground number, the type\n   returned will be appropriate for its type (i.e. if it's not an integer,\n   the type returned will be real).</P>\n")]).
:- comment(get_threshold / 1, [amode : get_threshold(-), args : ["Threshold" : "Current threshold"], summary : "Returns the current propagation threshold.", see_also : [set_threshold / 1, set_threshold / 2], desc : html("<P>\n   Returns the current threshold.  For non-integer variables, bounds are\n   only changed if the absolute and relative changes of the bound exceed the\n   threshold.  This means that constraints over real variables are only\n   guaranteed to be consistent up to the current threshold (over and above\n   any normal widening which occurs).</P><P>\n\n   Limiting the amount of propagation is important for efficiency.  A higher\n   threshold speeds up computations, but reduces precision and may in the\n   extreme case prevent the system from being able to locate individual\n   solutions.</P>\n")]).
:- comment(indomain / 1, [amode : indomain(?), args : ["Var" : "An integer IC variable or an integer"], resat : "Yes.", summary : "Instantiates an integer IC variable to an element of its domain.", see_also : [labeling / 1, (::) / 2, _42851 : indomain / 1], desc : html("<P>\n   Simple predicate for instantiating an integer IC variable to an element\n   of its domain.  It starts with the smallest element, and upon\n   backtracking tries successive elements until the entire domain has been\n   explored, at which point the predicate fails.</P><P>\n\n   If Var is already a ground integer, then this predicate simply succeeds\n   exactly once without leaving a choicepoint.</P>\n")]).
:- comment(indomain / 2, [summary : "a flexible way to assign values to finite domain variables", amode : indomain(?, ++), args : ["Var" : "a domain variable or an integer", "Method" : "one of the atoms min, max, middle, median, split, interval, random or an integer"], desc : html("This predicate provides a flexible way to assign values to finite \ndomain variables.<p>\nThe available methods are:\n<ul>\n<li><b>min</b> Start the enumeration from the smallest value upwards. \n    This behaves like the built-in <b>indomain/1</b>, except that it\n    removes previously tested values on backtracking.</li>\n\n<li><b>max</b> Start the enumeration from the largest value\n    downwards.</li>\n\n<li><b>middle</b> Try the enumeration starting from the middle of the\n    domain.  On backtracking, this chooses alternatively values above and\n    below the middle value, until all alternatives have been tested.</li>\n\n<li><b>median</b> Try the enumeration starting from the median value\n    of the domain.  On backtracking, this chooses alternatively values\n    above and below the median value, until all alternatives have been\n    tested.</li>\n\n<li><b>split</b> Try the enumeration by splitting the domain\n    successively into halves until a ground value is reached.  This\n    sometimes can detect failure earlier than the normal enumeration\n    methods, but enumerates the values in the same order as min.</li>\n\n<li><b>interval</b> If the domain consists of several intervals, then\n    we branch first on the choice of the interval.  For one interval, we\n    use domain splitting.</li>\n\n<li><b>random</b> Try the enumeration in a random order.  On\n    backtracking, the previously tested value is removed.  This method\n    uses <b>random/1</b> to create random numbers, use <b>seed/1</b>\n    before to make results reproducible.</li>\n\n<li><b>Value:integer</b> Like middle, but start with the given integer\n    <b>Value</b></li>\n\n<li><b>sbds_min</b> Like min, but use <b>sbds_try/2</b> to make choices (for\n    use in conjunction with the SBDS symmetry breaking library).</li>\n\n<li><b>sbds_max</b> Like max, but use <b>sbds_try/2</b> to make choices (for\n    use in conjunction with the SBDS symmetry breaking library).</li>\n\n<li><b>sbds_middle</b> Like middle, but use <b>sbds_try/2</b> to make choices\n    (for use in conjunction with the SBDS symmetry breaking library).</li>\n\n<li><b>sbds_median</b> Like median, but use <b>sbds_try/2</b> to make choices\n    (for use in conjunction with the SBDS symmetry breaking library).</li>\n\n<li><b>sbds_random</b> Like random, but use <b>sbds_try/2</b> to make choices\n    (for use in conjunction with the SBDS symmetry breaking library).</li>\n\n<li><b>sbds(Value:integer)</b> Like Value:integer, but use <b>sbds_try/2</b>\n    to make choices (for use in conjunction with the SBDS symmetry breaking\n    library).</li>\n\n<li><b>gap_sbds_min</b> Like min, but use <b>sbds_try/2</b> to make choices (for\n    use in conjunction with the GAP-based SBDS symmetry breaking library,\n    lib(ic_gap_sbds)).</li>\n\n<li><b>gap_sbds_max</b> Like max, but use <b>sbds_try/2</b> to make choices (for\n    use in conjunction with the GAP-based SBDS symmetry breaking library,\n    lib(ic_gap_sbds)).</li>\n\n<li><b>gap_sbds_middle</b> Like middle, but use <b>sbds_try/2</b> to make choices\n    (for use in conjunction with the GAP-based SBDS symmetry breaking\n    library, lib(ic_gap_sbds)).</li>\n\n<li><b>gap_sbds_median</b> Like median, but use <b>sbds_try/2</b> to make choices\n    (for use in conjunction with the GAP-based SBDS symmetry breaking\n    library, lib(ic_gap_sbds)).</li>\n\n<li><b>gap_sbds_random</b> Like random, but use <b>sbds_try/2</b> to make choices\n    (for use in conjunction with the GAP-based SBDS symmetry breaking\n    library, lib(ic_gap_sbds)).</li>\n\n<li><b>gap_sbds(Value:integer)</b> Like Value:integer, but use <b>sbds_try/2</b>\n    to make choices (for use in conjunction with the GAP-based SBDS symmetry\n    breaking library, lib(ic_gap_sbds)).</li>\n\n<li><b>gap_sbdd_min</b> Like min, but use <b>sbdd_try/2</b> to make choices (for\n    use in conjunction with the GAP-based SBDD symmetry breaking library,\n    lib(ic_gap_sbdd)).</li>\n\n<li><b>gap_sbdd_max</b> Like max, but use <b>sbdd_try/2</b> to make choices (for\n    use in conjunction with the GAP-based SBDD symmetry breaking library,\n    lib(ic_gap_sbdd)).</li>\n\n<li><b>gap_sbdd_middle</b> Like middle, but use <b>sbdd_try/2</b> to make choices\n    (for use in conjunction with the GAP-based SBDD symmetry breaking\n    library, lib(ic_gap_sbdd)).</li>\n\n<li><b>gap_sbdd_median</b> Like median, but use <b>sbdd_try/2</b> to make choices\n    (for use in conjunction with the GAP-based SBDD symmetry breaking\n    library, lib(ic_gap_sbdd)).</li>\n\n<li><b>gap_sbdd_random</b> Like random, but use <b>sbdd_try/2</b> to make choices\n    (for use in conjunction with the GAP-based SBDD symmetry breaking\n    library, lib(ic_gap_sbdd)).</li>\n\n<li><b>gap_sbdd(Value:integer)</b> Like Value:integer, but use <b>sbdd_try/2</b>\n    to make choices (for use in conjunction with the GAP-based SBDD symmetry\n    breaking library, lib(ic_gap_sbdd)).</li>\n</ul>\nOn backtracking, all methods first remove the previously tested value\nbefore choosing a new one.  This sometimes can have a huge impact on\nthe constraint propagation, and normally does not cause much overhead,\neven if no additional propagation occurs.\n"), fail_if : "No", resat : yes, eg : "\ntop:-\n\tX :: 1..10,\n\tindomain(X,min),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes 1 2 3 4 5 6 7 8 9 10\n\ntop:-\n\tX :: 1..10,\n\tindomain(X,max),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes 10 9 8 7 6 5 4 3 2 1\n\ntop:-\n\tX :: 1..10,\n\tindomain(X,middle),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes 5 6 4 7 3 8 2 9 1 10\n\ntop:-\n\tX :: 1..10,\n\tindomain(X,median),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes 5 6 4 7 3 8 2 9 1 10\n\ntop:-\n\tX :: 1..10,\n\tindomain(X,3),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes 3 4 2 5 1 6 7 8 9 10\n\ntop:-\n\tX :: 1..10,\n\tindomain(X,split),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes 1 2 3 4 5 6 7 8 9 10\n\ntop:-\n\tX :: 1..10,\n\tindomain(X,random),\n\twrite(X),put(32),\n\tfail.\ntop.\n\n% writes for example 5 3 7 6 8 1 2 10 9 4\n\n", see_also : [search / 6, indomain / 1, random / 1, seed / 1, sbds_try / 2, sbdd_try / 2]]).
:- comment(integers / 1, [amode : integers(-), amode : integers(?), amode : integers(+), args : ["Vars" : "Variable or integer, or a list or submatrix of variables/integers"], summary : "Vars' domain is the integer numbers.", see_also : [reals / 1, _14830 : integers / 1], desc : html("<P>\n   Constrain the variables to integer values.  Note that this declaration is\n   implicit when specifiying an integer interval, e.g. in <TT>Y :: 0..99</TT>.</P>\n")]).
:- comment(is_exact_solver_var / 1, [amode : is_exact_solver_var(?), args : ["Term" : "A Term"], summary : "Succeeds iff Term is an IC integer variable.", fail_if : "Var is not an IC integer variable.", desc : html("<P>\n   Test if the term Term is an IC integer variable.\n   </P>\n")]).
:- comment(is_in_domain / 2, [amode : is_in_domain(++, ?), args : ["Val" : "A number", "Var" : "An IC variable or a number"], summary : "Succeeds iff Val is in the domain of Var", exceptions : [4 : "Val is not ground", 5 : "either Val or Var is not a numeric type", 'undecidable comparison of bounded reals' : "Val was a bounded real which overlapped a bound of Var"], see_also : [is_in_domain / 3], desc : html("<P>\n   Low level predicate which succeeds when Val is in the domain of Var.  If\n   Var is a number, this predicate will succeed iff Var $= Val would succeed\n   WITHOUT leaving a delayed goal.\n")]).
:- comment(is_in_domain / 3, [amode : is_in_domain(++, ?, ?), args : ["Val" : "A number", "Var" : "An IC variable or a number", "Result" : "An atom"], summary : "Binds Result to indicate presence of Val in domain of Var", exceptions : [4 : "Val is not ground", 5 : "either Val or Var is not a numeric type"], see_also : [is_in_domain / 2], desc : html("<P>\n   Low level predicate which succeeds when Val is in the domain of Var with\n   Result bound to the atom 'yes'.  When Val is not in the domain of Var,\n   the predicate succeeds binding Result to the atom 'no'.  Should the\n   result be undecidable (as can be the case with bounded reals), the\n   predicate will succeed binding Result to the atom 'maybe'.  If Var is a\n   number, this predicate will succeed with Result bound to 'yes' iff\n   Var $= Val would succeed WITHOUT leaving a delayed goal.  If Var $= Val\n   would have left a delayed goal then Result gets bound to 'maybe'.\n")]).
:- comment(is_solver_type / 1, [amode : is_solver_type(?), args : ["Term" : "A Term"], summary : "Succeeds iff Term is an IC variable or a number.", fail_if : "Var is not an IC variable or a number.", desc : html("<P>\n   Test if the term Term is an IC variable or a numeric type supported by\n   the solver (any ground number).  Succeed if it is, fail otherwise.</P>\n")]).
:- comment(is_solver_var / 1, [amode : is_solver_var(?), args : ["Term" : "A Term"], summary : "Succeeds iff Term is an IC variable.", fail_if : "Var is not an IC variable.", desc : html("<P>\n   Test if the term Term is an IC variable.  Succeed if it is, fail\n   otherwise.</P>\n")]).
:- comment(labeling / 1, [amode : labeling(+), args : ["Vars" : "A collection (a la collection_to_list/2) of integer IC variables or integers"], resat : "Yes.", summary : "Instantiates all variables in a collection to elements of their domains.", see_also : [indomain / 1, _43223 : labeling / 1, collection_to_list / 2], desc : html("<P>\n   Simple predicate for instantiating a collection of integer IC variables\n   to elements of their domains.  (Integers are also allowed in the\n   collection; they are effectively ignored.)  The variables are\n   instantiated in the order in which they appear in the collection; the\n   implementation is essentially:\n<PRE>\n\tlabeling(Vars) :-\n\t\tcollection_to_list(Vars, List),\n\t\t( foreach(Var,List) do\n\t\t    indomain(Var)\n\t\t).\n</PRE></P>\n")]).
:- comment(locate / 2, [amode : locate(+, ++), args : ["Vars" : "Collection (a la collection_to_list/2) of variables", "Precision" : "Minimum required precision (float)"], summary : "Locate solution intervals for Vars by splitting and search.", see_also : [locate / 3, locate / 4, squash / 3, collection_to_list / 2], desc : html("<P>\n   Locate solution intervals for the given variables with the required\n   precision.  This works well if the problem has a finite number of\n   solutions.  locate/2,3 work by nondeterministically splitting the\n   intervals of the variables until they are narrower than Precision (in\n   either absolute or relative terms).</P><P>\n\n   locate/2 is defined in terms of locate/3 as follows:\n    <PRE>\n    locate(Vars, Precision) :- locate(Vars, Precision, log).\n    </PRE></P>\n")]).
:- comment(locate / 3, [amode : locate(+, ++, ++), args : ["Vars" : "Collection (a la collection_to_list/2) of variables", "Precision" : "Minimum required precision (float)", "LinLog" : "Domain splitting method (lin or log)"], summary : "Locate solution intervals for Vars by splitting and search.", see_also : [locate / 2, locate / 4, squash / 3, collection_to_list / 2], desc : html("<P>\n   Locate solution intervals for the given variables with the required\n   precision.  This works well if the problem has a finite number of\n   solutions.  locate/2,3 work by nondeterministically splitting the\n   intervals of the variables until they are narrower than Precision (in\n   either absolute or relative terms).</P><P>\n\n   The LinLog parameter guides the way domains are split.  If it is set to\n   <TT>lin</TT> then the split is linear (i.e. the arithmetic mean of the bounds is\n   used).  If it is set to <TT>log</TT>, the split is logarithmic (i.e. the geometric\n   mean of the bounds is used).  Note that if <TT>log</TT> is used, there will be\n   roughly the same number of representable floating point numbers on either\n   side of the split, due to the logarithmic distribution of these numbers.</P><P>\n\n   locate/3 is defined in terms of locate/4 as follows:\n    <PRE>\n    locate(Vars, Precision, LinLog) :- locate(Vars, [], Precision, LinLog).\n    </PRE></P>\n")]).
:- comment(locate / 4, [amode : locate(+, +, ++, ++), args : ["LocateVars" : "Collection (a la collection_to_list/2) of variables", "SquashVars" : "Collection of variables", "Precision" : "Minimum required precision (float)", "LinLog" : "Domain splitting method (lin or log)"], summary : "Locate solution intervals for LocateVars, interleaving search with squashing.", see_also : [locate / 2, locate / 3, squash / 3, collection_to_list / 2], desc : html("<P>\n   A variant of locate/2,3 with interleaved squashing.  The squash algorithm\n   is applied once to the SquashVars initially, and then again after each\n   splitting step (i.e. each time one of the LocateVars has been split\n   nondeterministically during the search).  A variable may occur in both\n   LocateVars and SquashVars.</P><P>\n\n   The LinLog parameter guides the way domains are split.  If it is set to\n   <TT>lin</TT> then the split is linear (i.e. the arithmetic mean of the bounds is\n   used).  If it is set to <TT>log</TT>, the split is logarithmic (i.e. the geometric\n   mean of the bounds is used).  Note that if <TT>log</TT> is used, there will be\n   roughly the same number of representable floating point numbers on either\n   side of the split, due to the logarithmic distribution of these numbers.</P>\n")]).
:- comment(max / 2, [amode : max(+, ?), args : ["Vars" : "Collection (a la collection_to_list/2) of variables or numbers (NOT arbitrary expressions)", "Max" : "Maximum element of Vars"], summary : "Constrains Max to be the largest element in Vars.", see_also : [min / 2, collection_to_list / 2], desc : html("<P>\n   Constrains Max to be the largest element in the collection of variables\n   or numbers Vars.</P><P>\n\n   You may find it more convenient to embed <TT>max(Vars)</TT> in a\n   constraint.\n")]).
:- comment(maxlist / 2, [amode : maxlist(+, ?), args : ["Vars" : "Collection (a la collection_to_list/2) of variables or numbers (NOT arbitrary expressions)", "Max" : "Maximum element of Vars"], summary : "Constrains Max to be the largest element in Vars.", see_also : [max / 2, min / 2, collection_to_list / 2], desc : html("<P>\n   This predicate is obsolete.  Use <TT>max/2</TT> instead.\n")]).
:- comment(min / 2, [amode : min(+, ?), args : ["Vars" : "Collection (a la collection_to_list/2) of variables or numbers (NOT arbitrary expressions)", "Min" : "Minimum element of Vars"], summary : "Constrains Min to be the smallest element in Vars.", see_also : [max / 2, collection_to_list / 2], desc : html("<P>\n   Constrains Max to be the smallest element in the collection of variables\n   or numbers Vars.</P><P>\n\n   You may find it more convenient to embed <TT>min(Vars)</TT> in a\n   constraint.\n")]).
:- comment(minlist / 2, [amode : minlist(+, ?), args : ["Vars" : "Collection (a la collection_to_list/2) of variables or numbers (NOT arbitrary expressions)", "Min" : "Minimum element of Vars"], summary : "Constrains Min to be the smallest element in Vars.", see_also : [min / 2, max / 2, collection_to_list / 2], desc : html("<P>\n   This predicate is obsolete.  Use <TT>min/2</TT> instead.\n")]).
:- comment(neg / 1, [amode : neg(+), template : "neg(+Con)", args : ["Con" : "Constraint"], summary : "Constraints Con is negated.", see_also : [and / 2, and / 3, neg / 2, or / 2, or / 3, => / 2, => / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to 0 $= (Con)</P>\n   <P>\n   The reified constraint Con is negated.  Con must be a constraint that has\n   a corresponding reified form.\n")]).
:- comment(neg / 2, [amode : neg(+, ?), template : "neg(+Con,Bool)", args : ["Con" : "Constraint", "Bool" : "Reified truth value of the constraint"], summary : "Bool is the logical negation of the reified truth constraints Con.", see_also : [and / 2, and / 3, neg / 1, or / 2, or / 3, => / 2, => / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to B $= (Con), Bool #= 1-B</P>\n   <P>\n   Bool is the logical negation of the reified truth constraint Con.  Con\n   must be a constraint that has a corresponding reified form.\n")]).
:- comment(nth_value / 3, [summary : "return the nth value in a domain", amode : nth_value(+, ++, -), args : ["Domain" : "The domain list to select a value from", "N" : "The position of the value to select", "Value" : "The selected value"], desc : html("Find the nth value in a domain given by an interval or a list of\nintegers and intervals, as it is returned for example by ic's\n<b>get_domain/2</b> or fd's <b>::/2</b>.\n"), fail_if : "N < 1 or there are less than N values in the domain.", resat : no, eg : "\n% a typical use\n\n\t....\n\tget_domain(X, L),\n\tnth_value(L, 2, Value),\n\t....\n", see_also : [fd : (::) / 2, ic : get_domain / 2]]).
:- comment(or / 2, [amode : or(+, +), template : "+ConX or +ConY", args : ["ConX" : "Constraint", "ConY" : "Constraint"], summary : "At least one of the constraints ConX or ConY must be true.", see_also : [or / 3, neg / 1, neg / 2, and / 2, and / 3, => / 2, => / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to BX $= (ConX), BY $= (ConY), BX + BY #>= 1</P>\n   <P>\n   The two constraints are reified in such a way that at least one must be\n   true.  ConX and ConY must be constraints that have a corresponding\n   reified form.\n")]).
:- comment(or / 3, [amode : or(+, +, ?), template : "or(+ConX,+ConY,Bool)", args : ["ConX" : "Constraint", "ConY" : "Constraint", "Bool" : "Reified truth value of the constraint"], summary : "Bool is the reified truth of at least one of the constraints ConX or ConY being true.", see_also : [or / 2, neg / 1, neg / 2, and / 2, and / 3, => / 2, => / 3, (=:=) / 3, (=<) / 3, (=\=) / 3, (>=) / 3, (>) / 3, (<) / 3], desc : html("<P>\n   Equivalent to BX $= (ConX), BY $= (ConY), Bool #= (BX + BY #>= 1)</P>\n   <P>\n   The two constraints are reified in such a way that Bool reflects the\n   truth of at least one being true.  ConX and ConY must be constraints that\n   have a corresponding reified form.\n")]).
:- comment(piecewise_linear / 3, [amode : piecewise_linear(?, ++, ?), args : ["X" : "Parameter/domain of the piecewise function", "Points" : "Collection (a la collection_to_list/2) of points defining the piecewise function", "Y" : "Result/interval of piecewise the function"], summary : "Relates X and Y according to a piecewise linear function.", see_also : [piecewise_linear_hull / 3, collection_to_list / 2], desc : html("<P>\n   This predicate imposes the constraint Y = f(X), where f is a piecewise\n   linear function defined by Points.  Points must be (after processing by\n   collection_to_list/2) a list of elements of the form (X, Y), sorted by\n   increasing X values.  The function is constructed by performing linear\n   interpolation between consecutive points, and extrapolating the first and\n   last linear segments to infinity.\n</P><P>\n   Discontinuities are allowed, by specifying more than one point with the\n   same X coordinate.  However, since the constraint is a function, one must\n   specify which of the given Y values is the true value of the function at\n   that point.  This is done by annotating which of the adjacent line\n   segments is ``open'' at that end (i.e. does not include the end point).\n   There are three allowed forms of discontinuity:\n</P><P>\n\t(X1, Y1), (X2, Y2a), (>(X2), Y2b), (X3, Y3) </P><P>\n\t(X1, Y1), (&lt;(X2), Y2a), (X2, Y2b), (X3, Y3) </P><P>\n\t(X1, Y1), (&lt;(X2), Y2a), (X2, Y2b), (>(X2), Y2c), (X3, Y3)\n</P><P>\n   In the first form, the segment specified by the first two points is\n   defined over the interval [X1 .. X2] while that specified by the last two\n   is defined over the interval (X2 .. X3].  That is, the first interval is\n   closed at X2, the second is open at X2 (i.e. only includes points\n   strictly greater than X2), and thus the value of the function at X2 is\n   Y2a.\n</P><P>\n   In the second form, the reverse is true.  The first segment is over the\n   interval [X1 .. X2) (points less than X2), the second is over the\n   interval [X2 .. X3], and the value of the function at X2 is Y2b.\n</P><P>\n   The final form is a double discontinuity.  Both adjacent segments are\n   open - [X1 .. X2), (X2 .. X3] - and at X2 the value of the function is\n   Y2b, taken from neither segment.\n</P><P>\n   Note that a segment can be open at both ends, if it has discontinuities\n   at both ends.  For example, if the list of points is\n</P><P>\n\t[(0, 0), (10, 0), (>(10), 1), (&lt;(20), 1), (20, 2), (30, 2)]\n</P><P>\n   then the function has value 0 for all values of X up to and including 10,\n   it has value 2 for all values of X from 20 onwards, and has value 1 in\n   between.\n\n</P><P>\n   Other notes:\n</P><P>\n   A piecewise linear constraint is expected to have at least two points\n   (though if it only has two, then a standard linear constraint would do,\n   and likely be more efficient).  If there is only one point, then there is\n   no way to determine the gradient to use to extend the function to other\n   values of X.  As a result, the value of the function is not defined for\n   all other values of X.  Similarly, if the first or last points in the\n   specification of the piecewise constraint are involved in\n   discontinuities, then the corresponding extensions to infinity are\n   undefined; it is recommended that the user either provide a valid\n   extension by supplying an extra point, or exclude those values of X by\n   imposing an appropriate bound.  (In any event, the first and last points\n   must be closed; an open discontinuity is not permitted at either end.)\n</P><P>\n   Whilst the piecewise constraint accepts bounded reals in its arguments,\n   the current implementation does not fully support bounded reals of\n   non-zero width (i.e. those which do not correspond to a single floating\n   point value).  As a result, use of such bounded reals is not recommended\n   at this time.</P>\n")]).
:- comment(print_solver_var / 2, [amode : print_solver_var(?, -), args : ["Var" : "An IC variable (or IC attribute)", "Printed" : "A printable representation of Var"], summary : "Returns a representation of the IC variable Var suitable for printing.", fail_if : "Var is not an IC variable or attribute", desc : html("<P>\n   The print handler for the IC attribute.  Returns a representation of the\n   IC variable (or attribute) Var suitable for printing, encoding the type\n   of the variable, the bounds, and any holes in the domain.\n</P>")]).
:- comment(reals / 1, [amode : reals(-), amode : reals(?), amode : reals(+), args : ["Vars" : "Variable or number, or a list or submatrix of variables/numbers"], summary : "Vars' domain is the real numbers.", see_also : [integers / 1, _14430 : reals / 1], desc : html("<P>\n   Constrain the domain of the variables to be the real numbers.  This is\n   the default, so the declaration is optional.</P><P>\n\n   Note that the notion of real numbers is used here in the pure\n   mathematical sense, where real numbers subsume the integers.  A variable\n   of type real can therefore be instantated to either a floating point or\n   an integer number (or a bounded real).  If the variables are already\n   instantiated, this call checks that the variable is instantiated to a\n   number.</P>\n")]).
:- comment(search / 6, [summary : "A generic search routine for finite domains or IC which implements \ndifferent partial search methods (complete, credit, lds, bbs, dbs, sbds,\ngap_sbds, gap_sbdd)", amode : search(+, ++, ++, +, ++, +), args : ["L" : "is a collection (a la collection_to_list/2) of domain\n\t    variables (Arg = 0) or a collection of terms (Arg > 0)", "Arg" : "is an integer, which is 0 if the list is a list of\n\t    dvarints or greater 0 if the list consists of terms of\n\t    arity greater than Arg, the value Arg indicates the\n\t    selected argument of the term", "Select" : "is a predefined selection method or the name of a\n\t    predicate of arity 2.  Predefined methods are input_order,\n\t    first_fail, smallest, largest, occurrence,\n\t    most_constrained, max_regret, anti_first_fail", "Choice" : "is the name of a predicate of arity 1 or a term\n\t    with two arguments with the same functor as a predicate of\n\t    arity 3.  Some names are already predefined as special\n\t    cases and are handled without a meta-call:  indomain,\n\t    indomain_min, indomain_max, indomain_middle,\n\t    indomain_median, indomain_split, indomain_random,\n\t    indomain_interval", "Method" : "is one of the following:  complete,\n\t    bbs(Steps:integer), lds(Disc:integer),\n\t    credit(Credit:integer, Extra:integer or bbs(Steps:integer)\n\t    or lds(Disc:integer)), dbs(Level:integer, Extra:integer or\n\t    bbs(Steps:integer) or lds(Disc:integer)), sbds, gap_sbds,\n\t    gap_sbdd", "Option" : "is a list of option terms.  Currently recognized\n\t   are backtrack(-N), node(++Call), nodes(++N)"], desc : html("<b>Search/6</b> provides a generic interface to a set of different search\nmethods.  It can currently be used with either the finite domains (if\nloaded via lib(fd_search)), or integer IC domains (if loaded via\nlib(ic_search)).  By changing the <b>Method</b> argument, different partial\nsearch algorithms (and their parameters) can be selected and\ncontrolled. The search predicate also provides a number of pre-defined\nvariable selection methods (to choose which variable will be assigned next)\nand some pre-defined value assignment methods (to try out the possible\nvalues for the selected variable in some heuristic order), but user-defined\nmethods can be used in their place as well.  In order to allow more\nstructure in the application program, it is possible to pass a collection\nof terms rather than only a collection of domain variables. In this way all\ninformation about some entity can be easily grouped together. It also\nallows more complex labeling methods which combine the assignment of\nmultiple variables (like a preference value and a decision variable).\n\n<p>\nAll search methods use a <i>stable</i> selection method. If several entries\nhave the same heuristic value, then the first one is selected.  The rest of\nthe collection (treated as a list) is equal to the original list with the\nselected entry removed, the order of the non-selected entries does not\nchange.\n<p>\nInteger values are not treated differently from the domain variables,\nthey are selected only if their heuristic value is better than those of the \nother entries.\n<p>\nThe pre-defined <b>selection methods</b> use the following criteria:\n<ul>\n<li><b>input_order</b> the first entry in the list is selected</li>\n<li><b>first_fail</b> the entry with the smallest domain size is selected</li>\n<li><b>anti_first_fail</b> the entry with the largest domain size is selected</li>\n<li><b>smallest</b> the entry with the smallest value in the domain is selected</li>\n<li><b>largest</b> the entry with the largest value in the domain is selected</li>\n<li><b>occurrence</b> the entry with the largest number of attached constraints is selected</li>\n<li><b>most_constrained</b> the entry with the smallest domain size is selected. If several entries have the same domain size, the entry with the largest number of attached constraints is selected.</li>\n<li><b>max_regret</b> the entry with the largest difference between the smallest and second smallest value in the domain is selected. This method is typically used if the variable represents a cost, and we are interested in the choice which could increase overall cost the most if the best possibility is not taken. Unfortunately, the implementation sometimes does not always work. If two decision variables incur the same minimal cost, the regret is not calculated as zero, but as the difference from this minimal value to the next greater value.</li>\n</ul><p>\nAny other name is taken as the name of a user-defined predicate of arity 2\nwhich is expected to compute a selection criterion (typically a number), e.g.\n<pre>\nmy_select(X,Criterion) :-\n\t...\t% compute Criterion from variable X\n</pre>\nThe variable-selection will then select the variable with the lowest\nvalue of Criterion.  If several variables have the same value, the first\none is selected.\n<p>\nThe pre-defined <b>choice methods</b> have the following meaning:\n<ul>\n<li><b>indomain</b>\nuses the built-in indomain/1.  Values are tried in increasing order. \nOn failure, the previously tested value is not removed.</li>\n\n<li><b>indomain_min</b>\nValues are tried in increasing order.  On failure, the previously\ntested value is removed.  The values are tested in the same order as\nfor <b>indomain</b>, but backtracking may occur earlier.</li>\n\n<li><b>indomain_max</b>\nValues are tried in decreasing order.  On failure, the previously\ntested value is removed.</li>\n\n<li><b>indomain_middle</b>\nValues are tried beginning from the middle of the domain.  On failure,\nthe previously tested value is removed.</li>\n\n<li><b>indomain_median</b>\nValues are tried beginning from the median value of the domain.  On\nfailure, the previously tested value is removed.</li>\n\n<li><b>indomain_split</b>\nValues are tried by succesive domain splitting.  On failure, the\npreviously tried interval is removed.  This enumerates values in the\nsame order as indomain or indomain_min, but may fail earlier.</li>\n\n<li><b>indomain_random</b>\nValues are tried in a random order.  On backtracking, the previously\ntried value is removed.  Using this rutine may lead to unreproducable\nresults, as another call wil create random numbers in a different\nsequence.  This method uses the built-in <b>random/1</b> to create\nrandom numbers, <b>seed/1</b> can be used to force the same number\ngeneration sequence in another run.</li>\n\n<li><b>indomain_interval</b>\nIf the domain consists of several intervals, we first branch on the\nchoice of the interval.  For one interval, we use domain\nsplitting.</li>\n\n</ul><p>\nAny other name is taken as the name of a user-defined predicate of\narity 1, e.g.\n<pre>\nmy_choice(X) :-\n\t...\t% make a choice on variable X\n</pre>\nAlternatively, a term with 2 arguments can be given as the choice-method,\ne.g. my_choice(FirstIn,LastOut). this will lead to the invocation of a\nchoice predicate with arity 3, e.g.\n<pre>\nmy_choice(X,In,Out) :-\n\t...\t% make a choice on variable X, using In-Out\n</pre>\nThis allows user-defined state to be transferred between the subsequent\ninvocations of the choice-predicate (the Out argument of a call to\nmy_choice/3 for one variable is unified with the In argument of the call to\nmy_choice/3 for the next variable, and so on).\n<p>\nThe different <b>search methods</b> are\n<ul>\n<li><b>complete</b>\na complete search routine which explores all alternative choices.</li>\n\n<li><b>bbs(Steps)</b>\nThe <i>bounded backtracking search</i> allows <b>Steps</b>\nbacktracking steps.</li>\n\n<li><b>lds(Disc)</b>\nA form of the <i> limited discrepancy search </i>.  This method\niteratively tries 0, 1, 2 ..  <b>Disc</b> changes against the\nheuristic (first) value.  Typical values are between 1 and 3 (which\nalready may create too many alternatives for large problems).  The\noriginal LDS paper stated that the discrepancy to be tested first\nshould be at the top of the tree.  Our implementation tries the first\ndiscrepancy at the bottom of the tree.  This means that solutions may\nbe found in a different order compared to the original algorithm. \nThis change is imposed by the evaluation strategy used and can not be\neasily modified.</li>\n\n<li><b>credit(Credit, bbs(Steps))</b>\nThe credit based search explores the top of the search tree\ncompletely.  Initially, a given number of credits (<b>Credit</b>) are\ngiven.  At each choice point, the first alternative gets half of the\navailable credit, the second alternative half of the remaining credit,\nand so on.  When the credit run out, the system switches to another\nsearch routine, here bbs.  In each of these bounded backtracking\nsearches <b>Steps</b> backtracking steps are allowed before returning\nto the top most part of the tree and choosing the next remaining\ncandidate.  A good value for <b>Steps</b> is 5, a value of 0 forces a\ndeterministic search using the heuristic.  Typical values for\n<b>Credit</b> are either N or N*N, where N is the number of entries in\nthe collection.</li>\n\n<li><b>credit(Credit, lds(Disc))</b>\nlike the one above, but using <i>lds</i> when the credit runs out. \nTypically, only one (perhaps 2) discrepancies should be allowed.</li>\n\n<li><b>dbs(Level, bbs(Steps))</b>\nThe <i>depth bounded search</i> explores the first <b>Level</b>\nchoices in the search tree completely, i.e.  it tries all values for\nthe first <b>Level</b> selected variables.  After that, it switches to\nanother search method, here bbs.  In each of these searches,\n<b>Steps</b> backtracking steps are allowed.  </li>\n\n<li><b>dbs(Level, lds(Disc))</b>\nlike the method above, but switches to lds after the first\n<b>Level</b> variables.</li>\n\n<li><b>sbds</b>\nA complete search routine which uses the SBDS symmetry breaking library\n(lib(ic_sbds) or lib(fd_sbds)) to exclude symmetric parts of the search tree\nfrom consideration.  The symmetry breaking must be initialised through a\ncall to sbds_initialise/4,5 before calling search/6.  Currently the only\npre-defined choice methods supported by this search method are\n<b>indomain_min</b>, <b>indomain_max</b>, <b>indomain_middle</b>,\n<b>indomain_median</b> and <b>indomain_random</b>.  Any user-defined choice\nmethod used in conjunction with this search method must use sbds_try/2 to\nassign/exclude values or the symmetry breaking will not work correctly.</li>\n\n<li><b>gap_sbds</b> (Not available for FD.)\nA complete search routine which uses the GAP-based SBDS symmetry breaking\nlibrary lib(ic_gap_sbds) to exclude symmetric parts of the search tree from\nconsideration.  The symmetry breaking must be initialised through a call to\nsbds_initialise/5 before calling search/6.  Currently the only pre-defined\nchoice methods supported by this search method are <b>indomain_min</b>,\n<b>indomain_max</b>, <b>indomain_middle</b>, <b>indomain_median</b> and\n<b>indomain_random</b>.  Any user-defined choice method used in conjunction\nwith this search method must use sbds_try/2 to assign/exclude values or the\nsymmetry breaking will not work correctly.</li>\n\n<li><b>gap_sbdd</b> (Not available for FD.)\nA complete search routine which uses the GAP-based SBDD symmetry breaking\nlibrary lib(ic_gap_sbdd) to exclude symmetric parts of the search tree from\nconsideration.  The symmetry breaking must be initialised through a call to\nsbdd_initialise/5 before calling search/6.  Currently the only pre-defined\nchoice methods supported by this search method are <b>indomain_min</b>,\n<b>indomain_max</b>, <b>indomain_middle</b>, <b>indomain_median</b> and\n<b>indomain_random</b>.  Any user-defined choice method used in conjunction\nwith this search method must use sbdd_try/2 to assign/exclude values or the\nsymmetry breaking will not work correctly.</li>\n</ul>\nThe option list is used to pass additional parameters to and from the\nprocedure.  The currently recognized options are:\n<ul>\n<li><b>backtrack(-N)</b>\nreturns the number of backtracking steps used in the search\nroutine</li>\n\n<li><b>nodes(++N)</b>\nsets an upper limit on the number of nodes explored in the search.  If\nthe given limit is exceeded, the search routine stops the exploration\nof the search tree.</li>\n\n<li><b>node(daVinci)</b>\ncreate a drawing of the search tree using the daVinci graph drawing\ntool.  Each node of the search tree is shown as a node in the tree. \nThe label of the node is the selected term of the collection.</li>\n\n<li><b>node(daVinci(++Call))</b>\nas the previous option, it creates a drawing of the search tree using\nthe daVinci graph drawing tool.  But instead of using the complete\nselected term as the label, it call the predicate <b>Call/2</b> to\nchoose which part of the selected term to display.</li>\n</ul>\n"), fail_if : "Fails if the search tree generated does not contain any solution. \nFor partial search methods, this does not mean that the problem does not \nhave a solution, but only that the part of the tree generated did not \ncontain one.", resat : yes, eg : "\ntop:-\n\tlength(L,8),\n\tL :: 1..8,\n\tsearch(L,0,input_order,indomain,complete,[]).\n\ntop:-\n\tlength(L,8),\n\tL :: 1..8,\n\tsearch(L,0,input_order,indomain,bbs(15),[]).\n\ntop:-\n\tlength(L,8),\n\tL :: 1..8,\n\tsearch(L,0,input_order,indomain,lds(2),[]).\n\ntop:-\n\tlength(L,8),\n\tL :: 1..8,\n\tsearch(L,0,input_order,indomain,credit(64,bbs(5)),[]).\n\ntop:-\n\tlength(L,8),\n\tL :: 1..8,\n\tsearch(L,0,input_order,indomain,dbs(2,lds(1)),[]).\n\n% a more complex example with different methods and heuristics\n% the list to be assigned is a list of terms queen/2\n\n:- local struct(queen(place,var)).\n\ntop:-\n\tmember(Method,[complete,lds(2),credit(64,5),bbs(1000),dbs(5,10)]),\n\tmember(Select,[first_fail,most_constrained,input_order]),\n\tmember(Choice,[indomain,\n\t               indomain_min,\n\t\t       indomain_max,\n\t\t       indomain_middle,\n\t\t       indomain_median,\n\t\t       indomain_split,\n\t\t       indomain_random]),\n\twriteln(queen(Method,Select,Choice)),\n\tonce(queen_credit(64,Select,Choice,Method,L,Back)),\n\twriteln(L),\n\twriteln(backtrack(Back)),\n\tfail.\ntop:-\n\tnl.\n\nqueen_credit(N,Select,Choice,Method,L,Back):-\n\tcreate_queens(1,N,Queens,L),\n\tsetup(L),\n\trearrange(Queens,Queens,[],[],Queens1),\n\tsearch(Queens1, var of queen, Select, Choice, Method, [backtrack(Back)]).\n\nrearrange([],Last,Last,Res,Res).\nrearrange([_],[Mid|Last],Last,Res,[Mid|Res]).\nrearrange([_,_|S],[H|T],A1,In,Res):-\n\trearrange(S,T,[A|A1],[H,A|In],Res).\n\ncreate_queens(N,M,[],[]):-\n\tN > M,\n\t!.\ncreate_queens(N,M,[queen{place:N,var:X}|T],[X|L]):-\n\tX :: 1..M,\n\tN1 is N+1,\n\tcreate_queens(N1,M,T,L).\n\nsetup([]).\nsetup([H|T]):-\n\tsetup1(H,T,1),\n\tsetup(T).\n\nsetup1(_,[],_).\nsetup1(X,[Y|R],N):-\n\tX #\\= Y,\n\tX #\\= Y + N,\n\tY #\\= X + N,\n\tN1 is N+1,\n\tsetup1(X,R,N1).\n\n\n% this example shows how to pass information from one assignment step \n% to the next\n% this uses a term of two arguments as the choice argument\n% The example also shows the use of the option argument:\n% the search tree generated is drawn with the daVinci graph drawing tool\n% and the search is limited to 1000 nodes.\n% The number of backtracking steps is returned in the variables Back.\n:-local struct(country(name,color)).\n\ntop:-\n\tcountries(C),\n\tcreate_countries(C,Countries,Vars),\n\tfindall(n(A,B),n(A,B),L),\n\tsetup(L,Countries),\n\tsearch(Countries,\n\t       color of country, % select based on this variable\n\t       most_constrained,\n\t       assign([1,2,3,4],Out), % this calls assign/3\n\t       complete,\n\t       [backtrack(Back),node(daVinci),nodes(1000)]),\n\twriteln(Vars),\n\twriteln(Back),\n\twriteln(Out).\n\ncreate_countries([],[],[]).\ncreate_countries([C|C1],[country{name:C, color:V}|R1],[V|V1]):-\n\tV :: 1..4,\n\tcreate_countries(C1,R1,V1).\n\nsetup([],_L).\nsetup([n(A,B)|N1],L):-\n\tmember(country{name:A, color:Av},L),\n\tmember(country{name:B, color:Bv},L),\n\tAv #\\= Bv,\n\tsetup(N1,L).\n\n% this is the choice predicate\n% the first argument is the complete selected term\n% the second is the input argument\n% the third is the output argument\n% here we pass a list of values and rotate this list from one step to the next\nassign(country{color:X},L,L1):-\n\trotate(L,L1),\n\tmember(X,L).\n\nrotate([A,B,C,D],[B,C,D,A]).\n\n% another example of argument passing \n% here each entry gets the same information\n% it is passed unchanged from one level to the next\n\ntop:-\n\t...\n\tlength(L,N),\n\tL :: 1..10,\n\t...\n        search(L,\n\t       0,\n\t       most_constrained,\n\t       % pass two lists as the In argument of assign\n\t       % try the odd numbers before the even numbers\n\t       assign([1,3,5,7,9]-[2,4,6,8,10],_), \n\t       complete,[]),\n\t...\n\n% this is the assignment routine\n% the first argument is a \n% Pass the In argument as the Out argument\n% try values from list L1 before values from list L2\nassign(X,L1-L2,L1-L2):-\n\tmember(X,L1);member(X,L2).\n\n% and another example from square placement\n% alternatively try minimal and maximal values first\n\n:-local struct(square(x,y,size)).\n\ntop:-\n\tdata(L),\n\tcreate_squares(L,Squares),\n\t...\n        search(Squares,\n\t       0, % this value does not matter if input_order is chosen\n\t       input_order,\n\t       assign(min,_),\n\t       complete,\n\t       []),\n\t...\n\n% the assignment routine\n% alternate between min and max for consecutive levels in the search\nassign(square{x:X,y:Y},Type,Type1):-\n\tswap(Type,Type1),\n\tindomain(X,Type),\n\tindomain(Y,Type).\n\nswap(max,min).\nswap(min,max).\n\n% this example shows that the choice routine may consist of several clauses\n% the idea comes from a graph coloring heuristic\n\ntop:-\n\tlength(L,N),\n\tL :: 1..100,\n\t...\n        search(L,\n\t       0,\n\t       most_constrained,\n\t       assign(0,K), The In argument is the highest color used so far\n\t       complete,[]),\n\t...\n\n\n% assign variable X either to one of the colors 1..K \n% which have already been used, or to the new color K+1\n% we do not need to try other values K+2 etc, as this is a symmetry that\n% we can avoid\nassign(X,K,K):-\n\tX #=< K,\n\tindomain(X).\nassign(K1,K,K1):-\n\tK1 is K+1.\n\n\n% example showing use of the SBDS library with a user-defined choice method\n% which calls sbds_try/2.\n\ntop:-\n\tdim(M, [8]),\n\tM[1..8] :: 1..8,\n\t...\n\tsbds_initialise(M,SymPreds,#=,[]),\n\tM =.. [_|L],\t% get list of variables for search routine\n\tsearch(L,0,first_fail,sbds_indomain_max,sbds,[]).\n\nsbds_indomain_max(X):-\n\tnonvar(X).\nsbds_indomain_max(X):-\n\tvar(X),\n\tget_max(X,Max),\n\tsbds_try(X,Max),\n\tsbds_indomain_max(X).\n\n\n% Example showing use of the GAP-based SBDS library with a user-defined\n% choice method which calls sbds_try/2.  (For the GAP-based SBDD library,\n% just substitute \"sbdd\" for each occurrence of \"sbds\" below.)\n\ntop:-\n\tdim(M, [8]),\n\tM[1..8] :: 1..8,\n\tsbds_initialise(M,[vars],values:1..8,[symmetry(s_n,[vars])],[]),\n\tM =.. [_|L],\t% get list of variables for search routine\n\tsearch(L,0,first_fail,gap_sbds_indomain_max,gap_sbds,[]).\n\ngap_sbds_indomain_max(X):-\n\tnonvar(X).\ngap_sbds_indomain_max(X):-\n\tvar(X),\n\tget_max(X,Max),\n\tsbds_try(X,Max),\n\tgap_sbds_indomain_max(X).\n", see_also : [indomain / 1, indomain / 2, labeling / 1, deleteff / 3, deleteffc / 3, sbds_initialise / 4, sbds_initialise / 5, sbds_try / 2, sbdd_initialise / 5, sbdd_try / 2, library(ic_sbds), library(fd_sbds), library(ic_gap_sbds), library(ic_gap_sbdd)]]).
:- comment(set_threshold / 1, [amode : set_threshold(++), args : ["Threshold" : "New threshold (float)"], summary : "Sets the propagation threshold.", see_also : [get_threshold / 1, set_threshold / 2], desc : html("<P>\n   Set the threshold to Threshold, which is a small floating-point number.\n   Subsequent to this, bounds updates to non-integer variables are only\n   performed if the change in the bounds exceeds this threshold (in both\n   absolute and relative terms).</P><P>\n\n   The default threshold is 1e-8.</P><P>\n\n   Limiting the amount of propagation is important for efficiency.  A higher\n   threshold speeds up computations, but reduces precision and may in the\n   extreme case prevent the system from being able to locate individual\n   solutions.</P><P>\n\n   Note that if the threshold is reduced using this predicate (requiring a\n   higher level of precision), the current state of the system may not be\n   consistent with respect to the new threshold.  If it is important that\n   the new level of precision be realised for all or part of the system\n   before computation proceeds, use set_threshold/2 instead.</P>\n")]).
:- comment(set_threshold / 2, [amode : set_threshold(++, +), args : ["Threshold" : "New threshold (float)", "WakeVars" : "Collection (a la collection_to_list/2) of IC variables to \"wake\""], summary : "Sets the propagation threshold with recomputation.", see_also : [get_threshold / 1, set_threshold / 1, collection_to_list / 2], desc : html("<P>\n   Set the threshold to Threshold, which is a small floating-point number,\n   and then if the threshold has been reduced, wake all constraints\n   suspended on the bounds of the variables in the collection WakeVars.\n   Subsequent to the setting of the new threshold, bounds updates to\n   non-integer variables are only performed if the change in the bounds\n   exceeds this threshold (in both absolute and relative terms).  The waking\n   of the constraints when the threshold is reduced allows part or all of\n   the system to be re-propagated in order to ensure the higher level of\n   precision is achieved before the rest of the computation proceeds.</P><P>\n\n   The default threshold is 1e-8.</P><P>\n\n   Limiting the amount of propagation is important for efficiency.  A higher\n   threshold speeds up computations, but reduces precision and may in the\n   extreme case prevent the system from being able to locate individual\n   solutions.</P>\n")]).
:- comment(squash / 3, [amode : squash(+, ++, ++), args : ["Vars" : "Collection (a la collection_to_list/2) of variables", "Precision" : "Minimum required precision (float)", "LinLog" : "Domain splitting method (lin or log)"], summary : "Refine the intervals of Vars by the squashing algorithm.", see_also : [locate / 2, locate / 3, locate / 4, set_threshold / 1, get_threshold / 1, collection_to_list / 2], desc : html("<P>\n   Use the squash algorithm on Vars.  This is a deterministic reduction of\n   the intervals of variables, done by searching for domain restrictions\n   which cause failure, and then reducing the domain to the complement of\n   that which caused the failure.  This algorithm is appropriate when the\n   problem has continuous solution intervals (where locate would return many\n   adjacent solutions).</P><P>\n\n   Precision is the minimum required precision, i.e. the maximum size of the\n   resulting intervals (in either absolute or relative terms).  Note that\n   the arc-propagation threshold (set by set_threshold/1,2), needs to be one\n   or several orders of magnitude smaller than Precision, otherwise the\n   solver may not be able to achieve the required precision.</P><P>\n\n   The LinLog parameter guides the way domains are split.  If it is set to\n   <TT>lin</TT> then the split is linear (i.e. the arithmetic mean of the bounds is\n   used).  If it is set to <TT>log</TT>, the split is logarithmic (i.e. the geometric\n   mean of the bounds is used).  Note that if <TT>log</TT> is used, there will be\n   roughly the same number of representable floating point numbers on either\n   side of the split, due to the logarithmic distribution of these numbers.</P><P>\n\n   If the intervals of variables at the start of the squashing algorithm are\n   known not to span several orders of magnitude, the somewhat cheaper\n   linear splitting may be used.  In general, log splitting is recommended.</P>\n")]).
