:- module(fd).
:- export is_exact_solver_var / 1.
:- export is_solver_var / 1.
:- export msg / 3.
:- export min_max_body / 9.
:- export min_max_body / 7.
:- export min_max_body / 6.
:- export min_max_body / 5.
:- export min_max_body / 3.
:- export minimize_body / 9.
:- export minimize_body / 7.
:- export minimize_body / 6.
:- export minimize_body / 5.
:- export minimize_body / 3.
:- export min_max / 8.
:- export min_max / 6.
:- export min_max / 5.
:- export min_max / 4.
:- export min_max / 2.
:- export minimize_bound_check / 0.
:- export minimize / 8.
:- export minimize / 6.
:- export minimize / 5.
:- export minimize / 4.
:- export minimize / 2.
:- export integers / 1.
:- export element / 3.
:- export atmost / 3.
:- export alldifferent / 1.
:- export tr_fd_out / 2.
:- reexport fd_arith except fd_eq / 1, fd_eq / 2, fd_ge / 1, fd_ge / 2, fd_gec / 5, fd_gec_ent / 6, fd_ineq / 1, fd_ineq / 2, fd_qeq / 3, fd_re / 2, fd_dom_simple / 2, fd_dom_simple / 3.
:- reexport fd_chip.
:- reexport fd_elipsys.
:- reexport fd_util.
:- export macro(element / 5, fd : tr_fd_out / 2, [write, goal]).
:- tool(min_max / 8,min_max_body / 9).
:- tool(min_max / 6,min_max_body / 7).
:- tool(min_max / 5,min_max_body / 6).
:- tool(min_max / 4,min_max_body / 5).
:- tool(min_max / 2,min_max_body / 3).
:- tool(minimize / 8,minimize_body / 9).
:- tool(minimize / 6,minimize_body / 7).
:- tool(minimize / 5,minimize_body / 6).
:- tool(minimize / 4,minimize_body / 5).
:- tool(minimize / 2,minimize_body / 3).
:- comment(min_max_body / 9, hidden).
:- comment(min_max_body / 7, hidden).
:- comment(min_max_body / 6, hidden).
:- comment(min_max_body / 5, hidden).
:- comment(min_max_body / 3, hidden).
:- comment(minimize_body / 9, hidden).
:- comment(minimize_body / 7, hidden).
:- comment(minimize_body / 6, hidden).
:- comment(minimize_body / 5, hidden).
:- comment(minimize_body / 3, hidden).
:- comment(summary, "Finite domain library").
:- comment(author, "Micha Meier, ECRC Munich").
:- comment(copyright, "Cisco Systems, Inc").
:- comment(date, "$Date").
:- comment(# / 3, [summary : "The cardinality operator", args : ["Min" : "Integer or domain variable", "Cstrs" : "A list of constraint expressions", "Max" : "Integer or domain variable"], desc : html("\n\tThis is a meta constraint known in the literature as the\n\tcardinality operator.  CstList is a list of constraint\n\texpressions and this operator states that at least Min and at\n\tmost Max out of them are valid. \n    "), see_also : [#/\ / 3, isd / 2]]).
:- comment(## / 2, [summary : "X is different from Y.\n\n", template : "?X ## ?Y", desc : html("   This constraints states that the two linear terms are not equal.  It is\n   suspended until at most one variable appears in it and then its domain\n   is updated so that the constraint is satisfied.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   The constraint does not hold if X=Y.\n\n", see_also : [(::) / 2, #:: / 2, (#=) / 2]]).
:- comment(## / 3, [summary : "The constraint X ## Y has the truth value B.\n\n", template : "##(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment(#/\ / 2, [summary : "The constraint expression C1 and the constraint expression C2 is true.\n\n", template : "?C1 #/\\ ?C2", desc : html("   This constraint states that both constraint expressions C1 and C2 must\n   be true.  It is identical to normal conjunstion (C1, C2).\n\n<P>\n"), args : ["?C1" : "An arithmetic constraint expression.", "?C2" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails if one of C1 or C2 is false.\n\n", see_also : [#\/ / 2, #=> / 2, #<=> / 2, #\+ / 1]]).
:- comment(#/\ / 3, [summary : "The constraint X #/\\ Y has the truth value B.\n\n", template : "#/\\(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A constraint expression.", "?Y" : "A constraint expression.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [#\+ / 2, #\/ / 3, #=> / 3, #<=> / 3, isd / 2]]).
:- comment(#:: / 2, [summary : "Terms in Vars have the domain Domain. The predicate is an alias for ::/2.\n\n", template : "?Vars #::  ?Domain", args : ["?Vars" : "A variable or a list of variables.", "+Domain" : "Variable, integer, integer interval or a list of integers                and integer intervals."], resat : "   No.", fail_if : "   Fails if Vars cannot have the domain Domain.\n\n", see_also : [(::) / 2, dom_to_list / 2, is_domain / 1]]).
:- comment(#:: / 3, [summary : "The constraint X #::  Y has the truth value B. The predicate is an alias for ::/3.\n\n", template : "#::(?X, ?Y, ?B)", args : ["?X" : "A domain variable", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(::) / 3, (#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment((#<) / 2, [summary : "The linear term X is less than the linear term Y.\n\n", template : "?X #< ?Y", desc : html("   This constraint states that the linear term X is less than the linear\n   term Y. It is activated whenever the maximum or minimum of a domain\n   variable is updated that might require updating other domains.  When\n   propagating domain updates, the system takes into account only maximum\n   and minimum values of the whole domain and makes sure that these values\n   are consistent with those of other domain variables.\n\n<P>\n   If one of the arguments is a non-linear polynomial, this predicate\n   delays until it becomes linear.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   Fails if X is not less than Y.\n\n", see_also : [(#>=) / 2, (#>) / 2, (#<=) / 2, (#=) / 2, ## / 2]]).
:- comment((#<) / 3, [summary : "The constraint X #< Y has the truth value B.\n\n", template : "#<(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment((#<=) / 2, [summary : "The linear term X is less than or equal to the linear term Y.\n\n", template : "?X #<= ?Y", desc : html("   This constraint states that the linear term X is less than or equal to\n   the linear term Y. It is activated whenever the maximum or minimum of a\n   domain variable is updated that might require updating other domains.\n   When propagating domain updates, the system takes into account only\n   maximum and minimum values of the whole domain and makes sure that these\n   values are consistent with those of other domain variables.\n\n<P>\n   If one of the arguments is a non-linear polynomial, this predicate\n   delays until it becomes linear.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   Fails if X is greater than Y.\n\n", see_also : [(#>) / 2, (#<) / 2, (#>=) / 2, (#=) / 2, ## / 2]]).
:- comment((#<=) / 3, [summary : "The constraint X #<= Y has the truth value B.\n\n", template : "#<=(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment(#<=> / 2, [summary : "The constraint expression C1 is equivalent to the constraint expression C2.\n\n", template : "?C1 #<=> ?C2", desc : html("   This constraint states that the constraint expressions C1 and C2\n   evaluate to the same truth value, either both true of both false.  If\n   this is already the case, it simply succeeds.  Otherwise it is suspended\n   and after each domain change that may cause one of the constraint\n   expressions to succeed to fail, it is woken and and re-evaluated.\n   Subsequently, if one of the constraint expressions is true or false, the\n   same truth value is imposed on the other one.\n\n<P>\n"), args : ["?C1" : "An arithmetic constraint expression.", "?C2" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails if C1 and C2 are not bothe true or both false.\n\n", see_also : [#\/ / 2, #/\ / 2, #=> / 2, #\+ / 1]]).
:- comment(#<=> / 3, [summary : "The constraint X #<=> Y has the truth value B.\n\n", template : "#<=>(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A constraint expression.", "?Y" : "A constraint expression.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [#\+ / 2, #/\ / 3, #\/ / 3, #=> / 3, isd / 2]]).
:- comment((#=) / 2, [summary : "X is equal to Y.\n\n", template : "?X #= ?Y", desc : html("   This constraints states that the two linear terms are equal.  It is\n   activated whenever the maximum or minimum of a domain variable is\n   updated that might require updating other domains.  When propagating\n   domain updates, the system takes into account only maximum and minimum\n   values of the whole domain and makes sure that these values are\n   consistent with those of other domain variables.\n\n<P>\n   If one of the arguments is a non-linear polynomial, this predicate\n   delays until it becomes linear.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   Fails if the two linear terms have a different value.\n\n", see_also : [(::) / 2, #:: / 2, ## / 2]]).
:- comment((#=) / 3, [summary : "The constraint X #= Y has the truth value B.\n\n", template : "#=(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment(#=> / 2, [summary : "The constraint expression C1 implies the constraint expression C2.\n\n", template : "?C1 #=> ?C2", desc : html("   This constraint states that the constraint expression C1 implies the\n   constraint expression C2.  If this is already the case, it simply\n   succeeds.  Otherwise it is suspended and after each domain change that\n   may cause C1 to succeed, it is woken and re-evaluated.  If C1 is true,\n   C2 is imposed as a constraint.\n\n<P>\n"), args : ["?C1" : "An arithmetic constraint expression.", "?C2" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails if C1 is true and C2 is false.\n\n", see_also : [#\/ / 2, #/\ / 2, #<=> / 2, #\+ / 1]]).
:- comment(#=> / 3, [summary : "The constraint X #=> Y has the truth value B.\n\n", template : "#=>(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A constraint expression.", "?Y" : "A constraint expression.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [#\+ / 2, #/\ / 3, #\/ / 3, #<=> / 3, isd / 2]]).
:- comment((#>) / 2, [summary : "The linear term X is greater than the linear term Y.\n\n", template : "?X #> ?Y", desc : html("   This constraint states that the linear term X is greater than the linear\n   term Y. It is activated whenever the maximum or minimum of a domain\n   variable is updated that might require updating other domains.  When\n   propagating domain updates, the system takes into account only maximum\n   and minimum values of the whole domain and makes sure that these values\n   are consistent with those of other domain variables.\n\n<P>\n   If one of the arguments is a non-linear polynomial, this predicate\n   delays until it becomes linear.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   Fails if X is not greater than Y.\n\n", see_also : [(#>=) / 2, (#<) / 2, (#<=) / 2, (#=) / 2, ## / 2]]).
:- comment((#>) / 3, [summary : "The constraint X #> Y has the truth value B.\n\n", template : "#>(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment((#>=) / 2, [summary : "The linear term X is greater than or equal to the linear term Y.\n\n", template : "?X #>= ?Y", desc : html("   This constraint states that the linear term X is greater than or equal\n   to the linear term Y. It is activated whenever the maximum or minimum of\n   a domain variable is updated that might require updating other domains.\n   When propagating domain updates, the system takes into account only\n   maximum and minimum values of the whole domain and makes sure that these\n   values are consistent with those of other domain variables.\n\n<P>\n   If one of the arguments is a non-linear polynomial, this predicate\n   delays until it becomes linear.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   Fails if X is less than Y.\n\n", see_also : [(#>) / 2, (#<) / 2, (#<=) / 2, (#=) / 2, ## / 2]]).
:- comment((#>=) / 3, [summary : "The constraint X #>= Y has the truth value B.\n\n", template : "#>=(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment(#\+ / 1, [summary : "The constraint expression C is false.\n\n", template : "#\\+ ?C", desc : html("   This constraint states that the constraint expressions C is false.  If\n   this is already the case, it simply succeeds.  Otherwise it is suspended\n   and after each domain change that may cause C to succeed, it is woken\n   and re-evaluated.  If C is true, the constraint fails.\n\n<P>\n"), args : ["?C" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails if both C is true.\n\n", see_also : [#/\ / 2, #=> / 2, #<=> / 2, #\/ / 2]]).
:- comment(#\+ / 2, [summary : "The constraint #\\+ X has the truth value B.\n\n", template : "#\\+(?X, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A constraint expression.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [#/\ / 3, #\/ / 3, #=> / 3, #<=> / 3, isd / 2]]).
:- comment(#\/ / 2, [summary : "The constraint expression C1 or the constraint expression C2 is true.\n\n", template : "?C1 #\\/ ?C2", desc : html("   This constraint states that at least one of the two constraint\n   expressions C1, C2 must be true.  If this is already the case, it simply\n   succeeds.  Otherwise it is suspended and after each domain change that\n   may cause one of the two expressions to fail, it is woken and\n   re-evaluated.  If one of the two expressions is false, the other is\n   imposed as a constraint, i.e.  it acts as disjunctive constraint.\n\n<P>\n"), args : ["?C1" : "An arithmetic constraint expression.", "?C2" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails if both C1 and C2 are false.\n\n", see_also : [#/\ / 2, #=> / 2, #<=> / 2, #\+ / 1]]).
:- comment(#\/ / 3, [summary : "The constraint X #\\/ Y has the truth value B.\n\n", template : "#\\/(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A constraint expression.", "?Y" : "A constraint expression.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [#/\ / 3, #\/ / 3, #=> / 3, #<=> / 3, isd / 2]]).
:- comment((#\=) / 2, [summary : "X is different from Y.\n\n", template : "?X #\\= ?Y", desc : html("   This constraints states that the two linear terms are not equal.  It is\n   suspended until at most one variable appears in it and then its domain\n   is updated so that the constraint is satisfied.\n\n<P>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term."], resat : "   No.", fail_if : "   The constraint does not hold if X=Y.\n\n", see_also : [(::) / 2, #:: / 2, (#=) / 2]]).
:- comment((#\=) / 3, [summary : "The constraint X #\\= Y has the truth value B.\n\n", template : "#\\=(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A linear term.", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [(#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment((::) / 2, [summary : "Terms in Vars have the domain Domain.\n\n", template : "?Vars ::  ?Domain", desc : html("   The main purpose of this predicate is to create domain variables.\n   Domain can be a closed integer interval denoted as Min..Max, or a sorted\n   list of integer intervals and/or elements.  If Vars is already a domain\n   variable, its domain will be updated according to the new domain; if it\n   is instantiated, the predicate checks if the value lies in the domain.\n   Otherwise, if Vars is a free variable, it is converted to a domain\n   variable.  If Vars is a list, this will be performed for all its\n   elements.\n\n<P>\n   If Vars is a domain variable and Domain is free, it is bound to the\n   domain of the variable.\n\n<P>\n"), args : ["?Vars" : "A variable or a list of variables.", "+Domain" : "Variable, integer, integer interval or a list of integers                and integer intervals."], resat : "   No.", fail_if : "   Fails if Vars cannot have the domain Domain.\n\n", see_also : [#:: / 2, dom_to_list / 2, is_domain / 1]]).
:- comment((::) / 3, [summary : "The constraint X ::  Y has the truth value B.\n\n", template : "::(?X, ?Y, ?B)", desc : html("   This predicate is an evaluation constraint:  it succeeds if and only if\n   the truth value of its associated constraint (the constraint with arity\n   one less and the same arguments except for B) is equal to B, where the\n   value 0 means false and 1 true.  This constraint can be used both to\n   test the validity of the associated constraint (entailment test) and to\n   impose this constraint or its negation.  For the former, B will be\n   instantiated as soon as either the associated constraint or its negation\n   is subsumed by the current state of its domain variables.  For the\n   latter, when B is instantiated, then depending on its value, either the\n   associated constraint or its negation will be imposed on its arguments.\n\n<P>\n   Boolean expressions containing arithmetic constraints are converted by\n   the system to a series of evaluation constraints and arithmetic\n   constraints in a way similar to arithmetic evaluation, e.g.\n\n<P>\n<PRE>\n    X #&gt; Y #=&gt; T #&gt; V #/\\ E #= F\n</PRE>\n   is transformed into\n\n<P>\n<PRE>\n    #&gt;(X, Y, B1),\n    #&gt;(T, V, B2),\n    #=(E, F, B3),\n    #=(B2 + B3, 2, B4),\n    B1 #&lt;= B4.      % i.e.  if B1 then B4\n</PRE>\n"), args : ["?X" : "A domain variable", "?Y" : "A linear term.", "?B" : "A variable with domain 0..1."], resat : "   No.", fail_if : "   Fails if B is not the truth value of the associated constraint.\n\n", see_also : [#:: / 3, (#>=) / 3, (#<) / 3, (#<=) / 3, (#=) / 3, (#\=) / 3]]).
:- comment(alldifferent / 1, [summary : "The elements of the list List are pairwise different.\n\n", template : "alldifferent(?List)", desc : html("   This constraint imposes the constraint ##/2 on every pair of element of\n   List.\n\n<P>\n"), args : ["?List" : "A list of integers and domain variables."], resat : "   No.", fail_if : "   Fails if two element of the list are equal.\n\n", see_also : [(::) / 2, #:: / 2, ## / 2, fd_global : alldifferent / 1]]).
:- comment(alldistinct / 1, [summary : "The elements of the list List are pairwise different.\n\n", template : "alldistinct(?List)", desc : html("\tThis constraint imposes the constraint ##/2 on every pair of\n\telement of List.  It is just a compatibility alias for alldifferent/1.\n"), args : ["?List" : "A list of integers and domain variables."], resat : "   No.", fail_if : "   Fails if two element of the list are equal.\n\n", see_also : [(::) / 2, #:: / 2, ## / 2, alldifferent / 1]]).
:- comment(atmost / 3, [summary : "At most N elements of the list List have the value V.\n\n", template : "atmost(+N, ?List, +V)", desc : html("   If List is a list of domain variables and/or integers, this constraint\n   takes care that at most N element of this list have the value V. As soon\n   as some domain variable from the list is updated, this constraint is\n   woken and it checks if the constraint is still satisfiable and if so, if\n   it is already satisfied or not.\n\n<P>\n"), args : ["+N" : "An integer", "?List" : "A list of domain variables or integers", "+V" : "An integer"], resat : "   No.", fail_if : "   Fails if more than N elements of List are instantiated to V.\n\n", see_also : [(::) / 2, #:: / 2, ## / 2, element / 3]]).
:- comment(constraints_number / 2, [summary : "The number of constraints and suspended goals associated with the variable\nVar is N.\n\n", template : "constraints_number(?Var, ?N)", desc : html("   N is the number of constraints and suspended goals currently attached to\n   the variable Var.  Note that this number may not correspond to the exact\n   number of different constraints attached to Var, as goals in different\n   suspending lists are counted separately.  This predicate is often used\n   when looking for the most or least constrained variable from a set of\n   domain variables.  If Var is instantiated, N is bound to a very large\n   integer, if Var is a free variable, N is zero.\n\n<P>\n"), args : ["?Var" : "Prolog term", "?N" : "Variable or integer"], resat : "   No.", fail_if : "   None.\n\n", see_also : [(::) / 2, #:: / 2, deleteff / 3, deleteffc / 3]]).
:- comment(contigs / 5, [summary : "MaxLength is the longest sequence of Item occurring in List, Occurrences is\nthe total number of occurrences of Item in List and Contigs is the number\nof sequences of Item in List.\n\n", template : "contigs(+List, +Item, ?MaxLength, ?Occurrences, ?Contigs)", desc : html("   The constraint is satisfied when MaxLength is the longest sequence of\n   Item occurring in List, Occurrences is the total number of occurrences\n   of Item in List and Contigs is the number of all uninterrupted sequences\n   of Item in List.\n\n<P>\n"), args : ["+List" : "A list of finite domain variables or integers", "+Item" : "An integer", "?MaxLength" : "An integer finite domain variable or an integer.", "?Occurrences" : "An integer finite domain variable or an integer.", "?Contigs" : "An integer finite domain variable or an integer."], resat : "   No.", fail_if : "   None.\n\n", see_also : [sequence / 4]]).
:- comment(default_domain / 1, [summary : "This predicate is called to assign a default domain to a free variable Var\nwhich occurs in arithmetic constraints.\n\n", template : "default_domain(-Var)", desc : html("   This is a simple hook predicate which allows the user to modify the\n   domain which is by default assigned to domainless variables that occur\n   in arithmetic constraints.  When such a variable is encountered, this\n   predicate is invoked and it must give the variable an integer finite\n   domain.  To modify the default domain, it is necessary to recompile this\n   predicate in the module fd_arith.\n\n<P>\n"), args : ["-Var" : "", "A" : "variable"], resat : "   No.", fail_if : "   None\n\n", eg : "\n   [eclipse 13]: A #> B.\n   A = A[-9999999..10000000]\n   B = B[-10000000..9999999]\n   ...\n   [eclipse 14]: compile(user, fd_arith).\n   default_domain(X) :- X::0..100000000.\n   user       compiled traceable 56 bytes in 0.00 seconds\n   yes.\n   [eclipse 20]: X #> Y.\n   X = X[1..100000000]\n   Y = Y[0..99999999]\n\n\n\n", see_also : [new_domain_var / 1, (::) / 2, #:: / 2]]).
:- comment(deleteff / 3, [summary : "Select from List the variable Var which has the smallest domain and return\nthe rest of the list.\n\n", template : "deleteff(?Var, +List, -Rest)", desc : html("   This predicate is used in the labeling procedures.  When we look for the\n   instantiation of a list of domain variables which is consistent with a\n   set of constraints, it is better to start with instantiations which are\n   most likely to fail, because this will cut down the size of the search\n   space considerably.\n\n<P>\n   The predicate deleteff/3 selects the variable with the smallest\n   domain. If there are several variables with the same domain size,\n   the leftmost one in the list is taken. Constants are treated like\n   variables of domain size one. The list Rest is the same as List\n   except that the selected element is missing. In particular, any\n   existing list order is preserved.\n\n<P>\n"), args : ["-Var" : "A variable.", "-Rest" : "A term unifying with a list of domain variables or integers.", "+List" : "A list of domain variables or integers."], resat : "   No.", fail_if : "   Fails if List is nil.\n\n", see_also : [deleteffc / 3, indomain / 1, fd_search : search / 6]]).
:- comment(deleteffc / 3, [summary : "Select from List the variable Var which has the smallest domain and most\nconstraints and return the rest of the list.\n\n", template : "deleteffc(?Var, +List, -Rest)", desc : html("   This predicate is used in the labeling procedures.  When we look for the\n   instantiation of a list of domain variables which is consistent with a\n   set of constraints, it is better to start with instantiations which are\n   most likely to fail, because this will cut down the size of the search\n   space considerably.  The predicate deleteffc/3 selects among the\n   variables with the smallest domain that one which has most constraints\n   attached to it.  This choice is based on the heuristics that variables\n   with more constraints are more likely to fail when instantiated.\n\n<P>\n   If several variables are equally eligible, the leftmost one in the\n   list is taken.  Constants are treated like variables of domain size\n   one with no constraints attached.  The list Rest is the same as\n   List except that the selected element is missing.  In particular,\n   any existing list order is preserved.\n\n<P>\n"), args : ["-Var" : "A variable.", "-Rest" : "A term unifying with a list of domain variables or integers.", "+List" : "A list of domain variables or integers."], resat : "   No.", fail_if : "   Fails if List is nil.\n\n", see_also : [constraints_number / 2, deleteff / 3, indomain / 1, fd_search : search / 6]]).
:- comment(deletemin / 3, [summary : "Select from List the variable Var which has the smallest lower domain bound,\nand return the rest of the list.\n\n", template : "deletemin(?Var, +List, -Rest)", desc : html("   This predicate is used in labeling procedures.  Especially when labeling\n   start times in scheduling problems, it is often a good strategy to start\n   with the earliest possible tasks, because fixing those will cause useful\n   bounds propagation on the start times of the other tasks. This predicate\n   selects from a list the variable with the smallest lower bound. Numbers\n   are treated as if they were variables with singleton domains.\n\n<P>\n"), args : ["-Var" : "A variable.", "-Rest" : "A term unifying with a list of domain variables or integers.", "+List" : "A list of domain variables or integers."], resat : "   No.", fail_if : "   Fails if List is empty.\n\n", eg : "\n   start_time_labeling([]) :- !.\n   start_time_labeling(Vars) :-\n        deletemin(X, Vars, Rest),\n\tindomain(X),\n\tstart_time_labeling(Rest).\n\n\n\n", see_also : [deleteff / 3, deleteffc / 3, indomain / 1, labeling / 1]]).
:- comment(disjunction / 5, [summary : "Flag indicates which of the two non-overlapping tasks is scheduled as\nfirst.  Either the one with starting time Start1 and duration Duration1\n(then the value of Flag is 1), or the second one with starting time Start2\nand duration Duration2 (and the Flag is 2).\n\n", template : "disjunction(?Start1, +Duration1, ?Start2, +Duration2, ?Flag)", desc : html("   This constraint can be used to model two non-overlapping tasks with\n   known durations.  Given the starting times and durations, this\n   constraint uses constructive disjunction to remove all inconsistent\n   values from the domains of Start1 and Start2.  In addition to\n   maintaining their bounds in a consistent state, it also locally executes\n   both cases (first task before the second one or voce versa) and removes\n   all values which are not consistent with any of these two alternatives.\n\n<P>\n   If Duration1 or Duration2 is not integer, it obtains a default domain.\n\n<P>\n"), args : ["?Start1" : "A finite domain variable or integer", "+Duration1" : "An integer", "?Start2" : "A finite domain variable or integer", "+Duration2" : "An integer", "?Flag" : "A finite domain variable or integer"], resat : "   No.", fail_if : "   Fails if there is no possibility to schedule given two tasks in any\n   order under given conditions.\n\n", eg : "\n   [eclipse 5]: [X, Y]::1..10, disjunction_choose(X, 5, Y, 7, F).\n   X = X[1..10]\n   Y = Y[1..10]\n   F = F[1, 2]\n   Delayed goals:\n   disjunction_choose_1(X[1..10], 5, Y[1..10], 7, F[1, 2])\n   yes.\n   [eclipse 6]: [X, Y]::1..10, disjunction(X, 5, Y, 7, F).\n   X = X[1..5, 8..10]\n   Y = Y[1..3, 6..10]\n   F = F\n   Delayed goals:\n   disjunction(X[1..5, 8..10], 5, Y[1..3, 6..10], 7, F)\n   yes.\n\n\n\n", see_also : [disjunctive / 3, disjunction_choose / 5]]).
:- comment(disjunction_choose / 5, [summary : "Flag indicates which of the two non-overlapping tasks is scheduled as\nfirst.  Either the one with starting time Start1 and duration Duration1\n(then the value of Flag is 1), or the second one with starting time Start2\nand duration Duration2 (and the Flag is 2).\n\n", template : "disjunction_choose(?Start1, +Duration1, ?Start2, +Duration2, ?Flag)", desc : html("   This constraint can be used, if there are two tasks that have to be\n   scheduled on the same machine.  It states which of the two tasks given\n   by their starting times and durations is scheduled as first.  It is\n   activated whenever the maximum or minimum of domain variables Start1 or\n   Start2 resp.  changes or the Flag is set to an integer.\n\n<P>\n"), args : ["?Start1" : "A finite domain variable or integer", "+Duration1" : "An integer", "?Start2" : "A finite domain variable or integer", "+Duration2" : "An integer", "?Flag" : "A variable or integer"], resat : "   No.", fail_if : "   Fails if there is no possibility to schedule given two tasks in any\n   order under given conditions.\n\n", exceptions : [4 : "Duration1 or Duration2 is not instantiated.", 5 : "Duration1 or Duration2 or Flag is instantiated but not an    integer."], eg : "\n   [eclipse 5]: [X, Y]::1..10, disjunction_choose(X, 5, Y, 7, F).\n   X = X[1..10]\n   Y = Y[1..10]\n   F = F[1, 2]\n   Delayed goals:\n   disjunction_choose_1(X[1..10], 5, Y[1..10], 7, F[1, 2])\n   yes.\n   [eclipse 6]: [X, Y]::1..10, disjunction_choose(X, 5, Y, 7, 1).\n   X = X[1..5]\n   Y = Y[6..10]\n   Delayed goals:\n   Y[6..10] - X[1..5]#>=5\n   disjunction_choose_1(X[1..5], 5, Y[6..10], 7, 1)\n   yes.\n   [eclipse 8]: [X, Y]::1..5, disjunction_choose(X, 5, Y, 7, 2).\n   no (more) solution.\n\n\n\n", see_also : [disjunctive / 3, disjunction / 5]]).
:- comment(disjunctive / 3, [summary : "Succeeds if there exists a sequential ordering of non-overlapping tasks\nwith starting times Starts and durations Durations, with respect to the\nordering priorities of single pairs of tasks (elementary disjunctions)\nrepresented in the list Flags.\n\n", template : "disjunctive(?Starts, +Durations, ?Flags)", desc : html("   This constraint can be used by job-shop problems on single machine.  The\n   tasks to be scheduled on one machine are represented by their starting\n   times (Starts) and durations (Durations).  The actual ordering of tasks\n   is represented by list of priority flags (Flags).  The core constraint\n   performs an exhaustive scheme based on maximal subset using extended\n   Carlier and Pinson techniques.  This constraint reacts to reduction\n   events on the flags of the elementary disjunctions it is connected to,\n   in turn it might perform reductions on those flags.  It also updates\n   starting times of operations according to the necessary partial\n   orderings it discovers.\n\n<P>\n   If some of the elements in the lists Starts or Flags is not ground, this\n   predicate delays.\n\n<P>\n"), args : ["?Starts" : "A list of finite domain variables or integers", "+Durations" : "A list of integers", "?Flags" : "A list of finite domain variables or integers"], resat : "   No.", fail_if : "   Fails, if no possible ordering of given list of tasks exist.\n\n", eg : "\n   [eclipse 3]: [X, Y]::1..10, disjunctive([X, Y], [5, 7], F).\n   X = X[1..10]\n   Y = Y[1..10]\n   F = [_g1124[1, 2]]\n   Delayed goals:\n   disjunction_choose_1(X[1..10], 5, Y[1..10], 7, _g1124[1, 2])\n   disjunctive(starts(X[1..10], Y[1..10]), durations(5, 7), [_g1124[1, 2]],\n   flags(_g998, _g1124, _g1002, _g1004))\n   yes.\n   [eclipse 3]: [X, Y, Z]::1..10, disjunctive([X, Y, Z], [3, 7, 5], [1, 2,\n   1]).\n   no (more) solution.\n   [eclipse 4]: [X, Y, Z]::1..10, disjunctive([X, Y, Z], [3, 7, 5], [1, 1,\n   2]).\n   X = X[1, 2]\n   Y = Y[9, 10]\n   Z = Z[4, 5]\n   Delayed goals:\n   Y[9, 10] - X[1, 2]#>=3\n   Y[9, 10] - Z[4, 5]#>=5\n   Z[4, 5] - X[1, 2]#>=3\n   Z[4, 5] - X[1, 2]#>=3\n   disjunction_choose_1(X[1, 2], 3, Z[4, 5], 5, 1)\n   disjunction_choose_1(X[1, 2], 3, Y[9, 10], 7, 1)\n   disjunction_choose_1(Y[9, 10], 7, Z[4, 5], 5, 2)\n   disjunctive(starts(X[1, 2], Y[9, 10], Z[4, 5]), durations(3, 7, 5), [1,\n   1, 2], flags(_g1080, 1, 1, _g1086, _g1088, 2, _g1092, _g1094, _g1096))\n   yes.\n\n\n\n", see_also : [disjunction_choose / 5]]).
:- comment(dom / 2, [summary : "List is the list of elements in the domain of Var.\n\n", template : "dom(+Var, ?List)", desc : html("   If Var is a domain variable, List is unified with a sorted list of all\n   elements in its domain.  If Var is an integer, List is unified with a\n   singleton list.\n\n<P>\n   The predicates ::/2 and #::/2 can also be used to query the domain of a domain\n   variable, however they yield a list of integer intervals, which is the\n   direct domain representation (it is therefore also more efficient\n   because no new structures have to be created).\n\n<P>\n   Use this predicate with care, because it might expand a compact\n   representation of large intervals into an explicit list of their\n   elements.  Unless an explicit list representation of the domain is\n   really required, the predicates working on domains should be preferred.\n\n<P>\n"), args : ["+Var" : "A domain variable or an integer.", "?List" : "Term unifying with a list of integers."], resat : "   No.", fail_if : "   None.\n\n", exceptions : [4 : "Var is not a domain variable."], eg : "\n   [eclipse 9]: X::[1..3, 100..102], dom(X, List), X::I.\n   List = [1, 2, 3, 100, 101, 102]\n   X = X :: [1 .. 3, 100 .. 102]\n   I = [1 .. 3, 100 .. 102]\n   yes.\n\n\n\n", see_also : [(::) / 2, #:: / 2, maxdomain / 2, mindomain / 2]]).
:- comment(dom_check_in / 2, [summary : "Element is in the domain Dom.\n\n", template : "dom_check_in(+Element, +Dom)", desc : html("   Succeed if the term Element is in the domain Dom.\n\n<P>\n"), args : ["+Element" : "A Prolog term.", "+Dom" : "A finite domain."], resat : "   No.", fail_if : "   Fails if the element does not occur in the domain.\n\n", see_also : [dom_compare / 3, dom_member / 2, dom_range / 3, dom_size / 2, dvar_domain / 2]]).
:- comment(dom_compare / 3, [summary : "Res is the result of the comparison of the domains Dom1 and Dom2.\n\n", template : "dom_compare(?Res, +Dom1, +Dom2)", desc : html("   Works like compare/3 for terms.  Res is unified with\n\n<P>\n  * = iff Dom1 is equal to Dom2,\n\n<P>\n  * &lt; iff Dom1 is a proper subset of Dom2,\n\n<P>\n  * &gt; iff Dom2 is a proper subset of Dom1.\n\n<P>\n"), args : ["?Res" : "Atom or variable.", "+Dom1" : "A finite domain.", "+Dom2" : "A finite domain."], resat : "   No.", fail_if : "   Fails if neither domain is a subset of the other one.\n\n", see_also : [dom_member / 2, dom_range / 3, dom_size / 2, dvar_domain / 2]]).
:- comment(dom_copy / 2, [summary : "Dom2 is a copy of the domain Dom1.\n\n", template : "dom_copy(+Dom1, -Dom2)", desc : html("   Dom2 is a copy of the domain Dom1.  Since the updates are done in-place,\n   two domain variables must not share the same physical domain and so when\n   defining a new variable with an existing domain, the domain has to be\n   copied first.\n\n<P>\n"), args : ["+Dom1" : "A finite domain.", "-Dom2" : "A variable."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dom_compare / 3, dom_member / 2, dom_range / 3, dom_size / 2, dvar_domain / 2]]).
:- comment(dom_difference / 4, [summary : "The domain DomDifference is Dom1 \\Dom2 and Size is the number of its\nelements.\n\n", template : "dom_difference(+Dom1, +Dom2, -DomDiff, -Size)", desc : html("   The domain DomDifference is Dom1 \\Dom2 and Size is the number of its\n   elements.\n\n<P>\n"), args : ["+Dom1" : "A finite domain.", "+Dom2" : "A finite domain.", "-DomDiff" : "A variable.", "-Size" : "A variable."], resat : "   No.", fail_if : "   Fails if Dom1 is a subset of Dom2.\n\n", see_also : [dom_compare / 3, dom_member / 2, dom_range / 3, dom_size / 2, dvar_domain / 2]]).
:- comment(dom_intersection / 4, [summary : "The domain DomInt is the intersection of domains Dom1 and Dom2 and Size is\nthe number of its elements.\n\n", template : "dom_intersection(+Dom1, +Dom2, -DomInt, -Size)", desc : html("   The domain DomInt is the intersection of domains Dom1 and Dom2 and Size\n   is the number of its elements.\n\n<P>\n"), args : ["+Dom1" : "A finite domain.", "+Dom2" : "A finite domain.", "-DomInt" : "A variable.", "-Size" : "A variable."], resat : "   No.", fail_if : "   Fails if the intersection is empty.\n\n", see_also : [dom_compare / 3, dom_member / 2, dom_range / 3, dom_size / 2, dvar_domain / 2]]).
:- comment(dom_member / 2, [summary : "Element is in the domain Dom.\n\n", template : "dom_member(?Element, +Dom)", desc : html("   Successively instantiate Element to the values in the domain Dom\n   (similar to indomain/1).\n\n<P>\n"), args : ["?Element" : "A Prolog term.", "+Dom" : "A finite domain."], resat : "   Yes.", fail_if : "   None.\n\n", see_also : [dom_check_in / 2, indomain / 1]]).
:- comment(dom_range / 3, [summary : "Return the minimum and maximum value in the integer domain Dom.\n\n", template : "dom_range(+Dom, ?Min, ?Max)", desc : html("   Return the minimum and maximum value in the integer domain Dom.  This\n   predicate can also be used to test if a given domain is an integer one\n   or not.\n\n<P>\n"), args : ["+Dom" : "A finite domain.", "?Min" : "An integer or a variable.", "?Max" : "An integer or a variable."], resat : "   No.", fail_if : "   Fails if Dom is a domain containing non-integer atomic elements.\n\n", see_also : [dom_check_in / 2, is_integer_domain / 1]]).
:- comment(dom_size / 2, [summary : "Size is the number of elements in the domain Dom.\n\n", template : "dom_size(+Dom, ?Size)", desc : html("   Size is the number of elements in the domain Dom.\n\n<P>\n"), args : ["+Dom" : "A finite domain.", "?Size" : "An integer or a variable."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dom_check_in / 2, dom_range / 3, dvar_domain / 2]]).
:- comment(dom_to_list / 2, [summary : "List is the list of elements in the domain Dom.\n\n", template : "dom_to_list(+Dom, ?List)", desc : html("   List is unified with a sorted list of all elements in the domain Dom.\n\n<P>\n   The predicates ::/2 and #::/2 can also be used to query the domain of a domain\n   variable, however they yield a list of integer intervals, which is the\n   direct domain representation (it is therefore also more efficient\n   because no new structures have to be created).\n\n<P>\n   Use this predicate with care, because it might expand a compact\n   representation of large intervals into an explicit list of their\n   elements.  Unless an explicit list representation of the domain is\n   really required, the predicates working on domains should be preferred.\n\n<P>\n"), args : ["+Dom" : "A finite domain.", "?List" : "Term unifying with a list of integers."], resat : "   No.", fail_if : "   None.\n\n", exceptions : [4 : "Var is not a domain variable."], eg : "\n   [eclipse 9]: X::[1..3, 100..102], dvar_domain(X, D), dom_to_list(D,\n   List), X::I.\n   D = [1..3, 100..102]\n   List = [1, 2, 3, 100, 101, 102]\n   X = X :: [1 .. 3, 100 .. 102]\n   I = [1 .. 3, 100 .. 102]\n   yes.\n\n\n\n", see_also : [(::) / 2, #:: / 2, maxdomain / 2, mindomain / 2]]).
:- comment(dom_union / 4, [summary : "The domain DomUnion is the union of domains Dom1 and Dom2 and Size is the\nnumber of its elements.\n\n", template : "dom_union(+Dom1, +Dom2, -DomUnion, -Size)", desc : html("   The domain DomUnion is the union of domains Dom1 and Dom2 and Size is\n   the number of its elements.\n\n<P>\n   Note that the main use of the predicate is to yield the most specific\n   generalisation of two domains, in the usual cases the domains become\n   smaller, not bigger.\n\n<P>\n"), args : ["+Dom1" : "A finite domain.", "+Dom2" : "A finite domain.", "-DomUnion" : "A variable.", "-Size" : "A variable."], resat : "   No.", fail_if : "   Fails if the union is empty.\n\n", see_also : [dom_compare / 3, dom_member / 2, dom_range / 3, dom_size / 2, dvar_domain / 2]]).
:- comment(dvar_attribute / 2, [summary : "Attrib is the attribute of the domain variable DVar.\n\n", template : "dvar_attribute(+DVar, ?Attrib)", desc : html("   Attrib is the attribute of the domain variable DVar.  If DVar is\n   instantiated, Attrib is bound to an attribute with a singleton domain\n   and empty suspension lists.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "?Attrib" : "Any Prolog term."], resat : "   No.", fail_if : "   None.\n\n", see_also : [#:: / 3, dvar_domain / 2, (::) / 2, #:: / 2]]).
:- comment(dvar_domain / 2, [summary : "Dom is the domain of the domain variable DVar.\n\n", template : "dvar_domain(+DVar, -Dom)", desc : html("   Dom is the domain of the domain variable DVar.  If DVar is instantiated,\n   Dom is bound to a singleton domain.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "-Dom" : "A variable."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_attribute / 2, (::) / 2, #:: / 2]]).
:- comment(dvar_msg / 3, [summary : "MsgDVar is a domain variable which is the most specific generalisation of\ndomain variables or atomic values DVar1 and DVar2.\n\n", template : "dvar_msg(+DVar1, +DVar2, -MsgDVar)", desc : html("   MsgVar is a domain variable which is the most specific generalisation of\n   domain variables or atomic values Var1 and Var2.\n\n<P>\n"), args : ["+DVar1" : "A finite domain or an atomic term.", "+DVar2" : "A finite domain or an atomic term.", "-MsgDVar" : "A free variable."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dom_union / 4, dom_intersection / 4, dvar_domain / 2]]).
:- comment(dvar_range / 3, [summary : "Return the minimum and maximum domain value of DVar", template : "dvar_range(+DVar, ?Min, ?Max)", desc : html("\tReturn the minimum and maximum domain value of the domin\n\tvariable DVar.  This predicate can also be used to test if a\n\tgiven domain is an integer one or not. \n\tIf DVar is instantiated, Min and Max will be identical."), args : ["+DVar" : "A domain variable or integer.", "?Min" : "An integer or a variable.", "?Max" : "An integer or a variable."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_domain / 2, dom_range / 3]]).
:- comment(dvar_remove_element / 2, [summary : "The element El is removed from the domain of DVar and all concerned lists\nare woken.\n\n", template : "dvar_remove_element(+DVar, +El)", desc : html("   The element El is removed from the domain of DVar and all concerned\n   lists are woken.  If the resulting domain is empty, this predicate\n   fails.  If it is a singleton, DVar is instantiated.  If the domain does\n   not contain the element, no updates are made.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "+El" : "An atomic term."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_attribute / 2, (::) / 2, #:: / 2]]).
:- comment(dvar_remove_greater / 2, [summary : "Remove all elements in the domain of DVar which are greater than the\ninteger El and wake all concerned lists.\n\n", template : "dvar_remove_greater(+DVar, +El)", desc : html("   Remove all elements in the domain of DVar which are greater than the\n   integer El and wake all concerned lists.  If the resulting domain is\n   empty, this predicate fails, if it is a singleton, DVar is instantiated.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "+El" : "An atomic term."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_attribute / 2, (::) / 2, #:: / 2]]).
:- comment(dvar_remove_smaller / 2, [summary : "Remove all elements in the domain of DVar which are smaller than the\ninteger El and wake all concerned lists.\n\n", template : "dvar_remove_smaller(+DVar, +El)", desc : html("   Remove all elements in the domain of DVar which are smaller than the\n   integer El and wake all concerned lists.  If the resulting domain is\n   empty, this predicate fails, if it is a singleton, DVar is instantiated.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "+El" : "An atomic term."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_attribute / 2, (::) / 2, #:: / 2]]).
:- comment(dvar_replace / 2, [summary : "Change the domain of the domain variable DVar to NewDom without propagating\nthe changes.\n\n", template : "dvar_replace(+DVar, +NewDom)", desc : html("   If the size of the domain NewDom is 0, the predicate fails.  If the size\n   of the new domain is 1, DVar is given this singleton domain.  Otherwise,\n   if the size of the new domain is smaller than the size of the domain\n   variable's domain, the domain of DVar is replaced by NewDom, but no\n   suspensions are passed to the waking scheduler.\n\n<P>\n   This predicate is useful for local consistency checks.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "+NewDom" : "A finite domain."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_attribute / 2, (::) / 2, #:: / 2, dvar_update / 2]]).
:- comment(dvar_update / 2, [summary : "Change the domain of the domain variable DVar to NewDom and propagate the\nchanges.\n\n", template : "dvar_update(+DVar, +NewDom)", desc : html("   If the size of the domain NewDom is 0, the predicate fails.  If it is 1,\n   the domain variable DVar is instantiated to the value in the domain.\n   Otherwise, if the size of the new domain is smaller than the size of the\n   domain variable's domain, the domain of DVar is replaced by NewDom, the\n   appropriate suspension lists in its attribute are passed to the waking\n   scheduler and so is the constrained list in the suspend attribute of the\n   domain variable.  If the size of the new domain is equal to the old one,\n   no updates and no waking is done, i.e.  this predicate does not check an\n   explicit equality of both domains.  If the size of the new domain is\n   greater than the old one, an error is raised.\n\n<P>\n"), args : ["+DVar" : "A domain variable.", "+NewDom" : "A finite domain."], resat : "   No.", fail_if : "   None.\n\n", see_also : [dvar_attribute / 2, (::) / 2, #:: / 2, dvar_replace / 2]]).
:- comment(element / 3, [summary : "Value is the Index'th element of the integer list List.\n\n", template : "element(?Index, +List, ?Value)", desc : html("   This constraints 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\n<P>\n<PRE>\n                             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\n<P>\n"), args : ["?Index" : "A variable or an integer.", "+List" : "A non-empty list of integers.", "?Value" : "A variable or an integer."], resat : "   No.", fail_if : "   Fails if Value is not the Index'th element of List.\n\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], t(1, 3, 6, 3), V :: [1, 3, 6], 4, 3)\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], t(1, 3, 6, 3), V :: [1, 6], 2, 2)\n   yes.\n\n\n\n", see_also : [(::) / 2, #:: / 2, atmost / 3]]).
:- comment(fd_eval / 1, [summary : "Evaluate and state the constraint expression C.\n\n", template : "fd_eval(?C)", desc : html("   This predicate is used to enforce the evaluation of a given constraint\n   expression on runtime, without macro expansion.  This can be useful in\n   situation where the compile-time macro expansion cannot process its\n   argument properly, because it has no type and mode information about the\n   variable arguments.\n\n<P>\n"), args : ["?C" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails C fails.\n\n", see_also : [isd / 2]]).
:- comment(indomain / 1, [summary : "Instantiate Var to a value in its domain.\n\n", template : "indomain(?Var)", desc : html("   This predicate instantiates the domain variable Var to a value from its\n   domain.  Its starts with the smallest element in the domain and on\n   backtracking successive elements are taken.  It is used mostly to find\n   an instantiation of the variable which is consistent with the current\n   set of constraints in labeling procedures.  If List is a list of all\n   domain variables occurring in the program, the simplest labeling\n   procedure is written as\n\n<P>\n<PRE>\n        labeling([]).\n        labeling([Var|Rest]) :-\n            indomain(Var),\n            labeling(Rest).\n</PRE>\n"), args : ["?Var" : "An integer or a domain variable"], resat : "   Yes.", fail_if : "   None.\n\n", see_also : [(::) / 2, #:: / 2, par_indomain / 1, labeling / 1, fd_search : search / 6]]).
:- comment(integer_list_to_dom / 2, [summary : "Convert a sorted list of integers and integer intervals into a domain Dom.\n\n", template : "integer_list_to_dom(+List, -Dom)", desc : html("   Convert a sorted list of integers and integer intervals into a domain\n   Dom.  List must be sorted and integers must not overlap with intervals.\n   Note that using sort/2 on a list of integers and intervals does not\n   produce correct results because intervals are considered compound terms\n   and thus sorted after all integers.  This predicate converts a list of\n   successive integers into an interval and/or merges it with adjacent\n   intervals.  Typically, it will be used to convert a sorted list of\n   integers into a list of intervals and an appropriate domain.  If the\n   list is already known to contain the right intervals, it is quicker to\n   use sorted_list_to_dom/2.\n\n<P>\n"), args : ["+List" : "A list of integers and integer interval.", "-Dom" : "Variable."], resat : "   No.", fail_if : "   None.\n\n", exceptions : [4 : "List is not ground.", 5 : "List contains an element which is neither integer nor an    integer interval.", 6 : "The size of the resulting domain is too large.", 6 : "The list is not sorted properly."], see_also : [sorted_list_to_dom / 2, dvar_domain / 2]]).
:- comment(integers / 1, [summary : "Constrains Vars to be integers.", amode : integers(+), args : ["Vars" : "List of variables or integers."], resat : "  No.", fail_if : "   Fails if Vars contains non-integers, or variables with non-integer domains.", exceptions : [5 : "Vars is a variable."], desc : html("  Constrains the list Vars to be integers. If Vars contains non-domain \n  variable, such variables will be given the default domain.")]).
:- comment(is_domain / 1, [summary : "Succeeds if Term is a domain variable.\n\n", template : "is_domain(?Term)", desc : html("   This predicate is used to test if a term is a domain variable.\n\n<P>\n"), args : ["?Term" : "A Prolog term."], resat : "   No.", fail_if : "   Fails if Term is not a domain variable.\n\n", see_also : [(::) / 2, #:: / 2]]).
:- comment(is_integer_domain / 1, [summary : "Succeeds if Term is a domain variable with an integer domain.\n\n", template : "is_integer_domain(?Term)", desc : html("   This predicate is used to test if a term is a domain variable with an\n   integer domain.\n\n<P>\n"), args : ["?Term" : "A Prolog term."], resat : "   No.", fail_if : "   Fails if Term is not an integer domain variable.\n\n", see_also : [is_domain / 1, (::) / 2, #:: / 2]]).
:- comment(isd / 2, [summary : "The constraint expression C evaluates to the boolean value B.\n\n", template : "?B isd ?C", desc : html("   This is an evaluation constraint.  It states that the constraint\n   expression C evaluates to the boolean value B, where the value 0 means\n   false and 1 true.  This constraint can be used both to test the validity\n   of the constraint expression (entailment test) and to impose this\n   constraint or its negation.  For the former, B will be instantiated as\n   soon as either the constraint expression or its negation is subsumed by\n   the current state of its domain variables.  For the latter, when B is\n   instantiated, then depending on its value, either the constraint\n   expression or its negation will be imposed on its arguments.\n\n<P>\n"), args : ["?B" : "A variable with domain 0..1.", "?C" : "An arithmetic constraint expression."], resat : "   No.", fail_if : "   Fails if both C is true.\n\n", see_also : [#=> / 3, #<=> / 3, #\/ / 3, #/\ / 3, (is) / 2]]).
:- comment(labeling / 1, [summary : "Instantiate all variables in a list to values in their domain", amode : labeling(+), args : ["Vars" : "List of variables or ground terms."], resat : "Yes", desc : html("    This predicate instantiates all variables in a list to values in their\n    domain, using the indomain/1 predicate. It is simply defined as:\n<PRE>\n        labeling([]).\n        labeling([Var|Rest]) :-\n            indomain(Var),\n            labeling(Rest).\n</PRE>\n    The list can contain ground terms, i.e. variables that are already\n    instantated. These are just skipped, in other words, they are\n    considered as variables with a single value in their domain.\n    "), see_also : [indomain / 1, fd_search : search / 6]]).
:- comment(list_to_dom / 2, [summary : "Convert a list of atomic terms and integer intervals into a domain Dom.\n\n", template : "list_to_dom(+List, -Dom)", desc : html("   Convert a list of atomic terms and integer intervals into a domain Dom.\n   List does not have to be sorted and integers and intervals may overlap.\n\n<P>\n"), args : ["+List" : "A list of atomic terms and integer interval.", "-Dom" : "Variable."], resat : "   No.", fail_if : "   None.\n\n", exceptions : [4 : "List is not ground.", 5 : "List contains an element which is neither atomic nor an    integer interval.", 6 : "The size of the resulting domain is too large.", 6 : "The lower bound of an integer interval is greater than its    upper bound."], see_also : [sorted_list_to_dom / 2, dvar_domain / 2]]).
:- comment(maxdomain / 2, [summary : "Max is the maximum element in the domain of Var.\n\n", template : "maxdomain(+Var, ?Max)", desc : html("   If Var is a domain variable then Max is unified with the maximum value\n   in the domain of Var.  If Var is an integer then Max is unified with\n   Var.\n\n<P>\n"), args : ["+Var" : "A domain variable or an integer.", "?Max" : "A variable or an integer."], resat : "   No.", fail_if : "   None.\n\n", see_also : [mindomain / 2, (::) / 2, #:: / 2, dom_to_list / 2]]).
:- comment(min_max / 2, [summary : "Find the solution of Goal that minimizes the maximum of elements of C.\n\n", template : "min_max(?Goal, ?C)", desc : html("   If C is a linear term, a solution of the goal Goal is found that\n   minimizes the value of C. If C is a list of linear terms, the returned\n   solution minimizes the maximum value of terms in the list.  The solution\n   is found using the branch and bound method; as soon as a partial\n   solution is found that is worse than a previous solution, the search is\n   abandoned and a new solution is searched for.  Every time a new better\n   solution is found, the event 280 is raised, its default handler prints\n   the current cost.\n\n<P>\n"), args : ["+Goal" : "A callable term.", "?C" : "A linear term or a list of linear terms."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", see_also : [min_max / 4, min_max / 5, min_max / 6, min_max / 8, minimize / 2, minimize / 4, minimize / 5, minimize / 6, minimize / 8, deleteff / 3]]).
:- comment(min_max / 4, [summary : "Find the solution of Goal that minimizes the maximum of elements of C,\nand unify the minimized Template with Solution.\n\n", template : "min_max(+Goal, ?Template, ?Solution, ?C)", desc : html("   If C is a linear term, a solution of the goal Goal is found that\n   minimizes the value of C. If C is a list of linear terms, the returned\n   solution minimizes the maximum value of terms in the list.  The solution\n   is found using the branch and bound method; as soon as a partial\n   solution is found that is worse than a previous solution, the search is\n   abandoned and a new solution is searched for.  Every time a new better\n   solution is found, the event 280 is raised, its default handler prints\n   the current cost.\n\n<P>\n   Solutions will be unified with a copy of Template where the variables\n   are replaced with their minimized values. Typically, the Template will\n   contain all or a subset of Goal's variables.\n\n<P>\n   min_max/2 can be written in terms of min_max/4 as follows:\n\n<P>\n<PRE>\n\tmin_max(Goal, Cost) :-\n\t    min_max(Goal, Goal, Goal, Cost).\n</PRE>\n"), args : ["+Goal" : "A callable term.", "?Template" : "A term containing all or some of Goal's variables", "?Solution" : "Term to be unified with the minimized Template", "?C" : "A linear term or a list of linear terms."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", eg : "\n    % Find the minimal C and bind X to the corresponding value\n    [eclipse]: X::1..3, C #= 3-X, min_max(indomain(X), X, X, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = 3\n    C = 0\n    yes.\n\n    % Find the minimal C and don't bind anything\n    [eclipse]: X::1..3, C #= 3-X, min_max(indomain(X), [], [], C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n    % Find the minimal C and return it in MinC. Don't bind X or C.\n    [eclipse]: X::1..3, C #= 3-X, min_max(indomain(X), C, MinC, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    MinC = 0\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n\n\n\n", see_also : [min_max / 2, min_max / 5, min_max / 6, min_max / 8, minimize / 2, minimize / 4, minimize / 5, minimize / 6, minimize / 8]]).
:- comment(min_max / 5, [summary : "Find the solution of Goal that minimizes the maximum of elements of C,\nwithin the bounds set by Lower,Upper and Percent.\n\n", template : "min_max(?Goal, ?C, +Lower, +Upper, +Percent)", desc : html("   If C is a linear term, a solution of the goal Goal is found that\n   minimizes the value of C. If C is a list of linear terms, the returned\n   solution minimizes the maximum value of terms in the list.  The solution\n   is found using the branch and bound method; as soon as a partial\n   solution is found that is worse than a previous solution, the search is\n   abandoned and a new solution is searched for.  The starting assumption\n   is that the value to minimize is less than Upper and that any value less\n   than Lower can be considered as a final solution.  Moreover, solutions\n   whose minimized values are closer than Percent % are considered equal.\n   Every time a new better solution is found, the event 280 is raised, its\n   default handler prints the current cost.\n\n<P>\n   This predicate is to be used for optimization problems when the whole\n   search space is too large or when a suboptimal solution is sufficient.\n\n<P>\n"), args : ["?Goal" : "A callable term.", "?C" : "A linear term or a list of linear terms.", "+Lower" : "An integer.", "+Upper" : "An integer.", "+Percent" : "An integer."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", see_also : [min_max / 2, min_max / 4, min_max / 6, min_max / 8, minimize / 2, minimize / 4, minimize / 5, minimize / 6, minimize / 8]]).
:- comment(min_max / 6, [summary : "Find the solution of Goal that minimizes the maximum of elements of C,\nwithin the bounds set by Lower,Upper and Percent in time not longer than\nTimeout.\n\n", template : "min_max(?Goal, ?C, +Lower, +Upper, +Percent, +Timeout)", desc : html("   If C is a linear term, a solution of the goal Goal is found that\n   minimizes the value of C. If C is a list of linear terms, the returned\n   solution minimizes the maximum value of terms in the list.  The solution\n   is found using the branch and bound method; as soon as a partial\n   solution is found that is worse than a previous solution, the search is\n   abandoned and a new solution is searched for.  The starting assumption\n   is that the value to minimize is less than Upper and that any value less\n   than Lower can be considered as a final solution.  Moreover, solutions\n   whose minimized values are closer than Percent % are considered equal.\n   Every time a new better solution is found, the event 280 is raised, its\n   default handler prints the current cost.\n\n<P>\n   If Timeout is not zero, the predicate will stop after Timeout seconds\n   and report the best solution it has found so far.  Calls with specified\n   Timeout cannot be nested.\n\n<P>\n   This predicate is to be used for optimization problems when the whole\n   search space is too large or when a suboptimal solution is sufficient.\n\n<P>\n"), args : ["?Goal" : "A callable term.", "?C" : "A linear term or a list of linear terms.", "+Lower" : "An integer.", "+Upper" : "An integer.", "+Percent" : "An integer.", "+Timeout" : "A number."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 8, minimize / 2, minimize / 4, minimize / 5, minimize / 6, minimize / 8]]).
:- comment(min_max / 8, [summary : "Find the solution of Goal that minimizes the maximum of elements of C,\nwithin the bounds set by Lower,Upper and Percent in time not longer than\nTimeout.\n\n", template : "min_max(+Goal, ?Template, ?Solution, ?C, +Lower, +Upper, +Percent, +Timeout)", desc : html("   This is the most general version of the min_max predicate with all\n   options.\n\n<P>\n   If C is a linear term, a solution of the goal Goal is found that\n   minimizes the value of C. If C is a list of linear terms, the returned\n   solution minimizes the maximum value of terms in the list.  The solution\n   is found using the branch and bound method; as soon as a partial\n   solution is found that is worse than a previous solution, the search is\n   abandoned and a new solution is searched for.  The starting assumption\n   is that the value to minimize is less than Upper and that any value less\n   than Lower can be considered as a final solution.  Moreover, solutions\n   whose minimized values are closer than Percent % are considered equal.\n   Every time a new better solution is found, the event 280 is raised, its\n   default handler prints the current cost.\n\n<P>\n   Solutions will be unified with a copy of Template where the variables\n   are replaced with their minimized values. Typically, the Template will\n   contain all or a subset of Goal's variables.\n\n<P>\n   If Timeout is not zero, the predicate will stop after Timeout seconds\n   and report the best solution it has found so far.  Calls with specified\n   Timeout cannot be nested.\n\n<P>\n   All other variants of min_max can be written in terms of min_max/9, eg.\n\n<P>\n<PRE>\n\tmin_max(Goal, Cost) :-\n\t    minint(Min), maxint(Max),\n\t    min_max(Goal, Goal, Goal, Cost, Min, Max, 0, 0).\n</PRE>\n"), args : ["+Goal" : "A callable term.", "?Template" : "A term containing all or some of Goal's variables", "?Solution" : "Term to be unified with the minimized Template", "?C" : "A linear term or a list of linear terms.", "+Lower" : "An integer.", "+Upper" : "An integer.", "+Percent" : "An integer.", "+Timeout" : "A number."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", eg : "\n    % Find the minimal C and bind X to the corresponding value\n    [eclipse]: X::1..3, C #= 3-X, min_max(indomain(X), X, X, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = 3\n    C = 0\n    yes.\n\n    % Find the minimal C and don't bind anything\n    [eclipse]: X::1..3, C #= 3-X, min_max(indomain(X), [], [], C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n    % Find the minimal C and return it in MinC. Don't bind X or C.\n    [eclipse]: X::1..3, C #= 3-X, min_max(indomain(X), C, MinC, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    MinC = 0\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n\n\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 6, minimize / 2, minimize / 4, minimize / 5, minimize / 6, minimize / 8]]).
:- comment(mindomain / 2, [summary : "Min is the minimum element in the domain of Var.\n\n", template : "mindomain(+Var, ?Min)", desc : html("   If Var is a domain variable then Min is unified with the minimum value\n   in the domain of Var.  If Var is an integer then Min is unified with\n   Var.\n\n<P>\n"), args : ["+Var" : "A domain variable or an integer.", "?Min" : "A variable or an integer."], resat : "   No.", fail_if : "   None.\n\n", see_also : [maxdomain / 2, (::) / 2, #:: / 2, dom_to_list / 2]]).
:- comment(minimize / 2, [summary : "Find the solution of Goal that minimizes C.\n\n", template : "minimize(?Goal, ?C)", desc : html("   A solution of the goal Goal is found that minimizes the value of C. \n   The solution is found using the branch and bound method.  Whenever\n   a better solution is found, the upper cost bound is tightened and\n   the search for a better solution continues.  Every time a new\n   better solution is found, the event 280 is raised, its default\n   handler prints the current cost.\n\n<P>\n   Note:  Operationally, the difference with min_max/2 is that, after\n   finding a solution, the search is not abandoned and restarted, but\n   continued with a tightened cost bound.\n\n<P>\n"), args : ["+Goal" : "A callable term.", "?C" : "A linear term."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 6, min_max / 8, minimize / 4, minimize / 5, minimize / 6, minimize / 8, minimize_bound_check / 0]]).
:- comment(minimize / 4, [summary : "Find the solution of Goal that minimizes C,\nand unify the minimized Template with Solution.\n\n", template : "minimize(+Goal, ?Template, ?Solution, ?C)", desc : html("   A solution of the goal Goal is found that minimizes the value of C. \n   The solution is found using the branch and bound method.  Whenever\n   a better solution is found, the upper cost bound is tightened and\n   the search for a better solution continues.  Every time a new\n   better solution is found, the event 280 is raised, its default\n   handler prints the current cost.\n\n<P>\n   Solutions will be unified with a copy of Template where the variables\n   are replaced with their minimized values. Typically, the Template will\n   contain all or a subset of Goal's variables.\n\n<P>\n   minimize/2 can be written in terms of minimize/4 as follows:\n\n<P>\n<PRE>\n\tminimize(Goal, Cost) :-\n\t    minimize(Goal, Goal, Goal, Cost).\n</PRE>\n"), args : ["+Goal" : "A callable term.", "?Template" : "A term containing all or some of Goal's variables", "?Solution" : "Term to be unified with the minimized Template", "?C" : "A linear term or a list of linear terms."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", eg : "\n    % Find the minimal C and bind X to the corresponding value\n    [eclipse]: X::1..3, C #= 3-X, minimize(indomain(X), X, X, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = 3\n    C = 0\n    yes.\n\n    % Find the minimal C and don't bind anything\n    [eclipse]: X::1..3, C #= 3-X, minimize(indomain(X), [], [], C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n    % Find the minimal C and return it in MinC. Don't bind X or C.\n    [eclipse]: X::1..3, C #= 3-X, minimize(indomain(X), C, MinC, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    MinC = 0\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n\n\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 6, min_max / 8, minimize / 2, minimize / 5, minimize / 6, minimize / 8, minimize_bound_check / 0]]).
:- comment(minimize / 5, [summary : "Find the solution of Goal that minimizes C, within the bounds set by Lower,\nUpper and Percent.\n\n", template : "minimize(?Goal, ?C, +Lower, +Upper, +Percent)", desc : html("   A solution of the goal Goal is found that minimizes the value of C. \n   The solution is found using the branch and bound method.  Whenever\n   a better solution is found, the upper cost bound is tightened and\n   the search for a better solution continues.\n\n<P>\n   The starting assumption is that the value to minimize is less than\n   Upper and that any value less than Lower can be considered as a\n   solution.  Moreover, solutions whose minimized values are closer\n   than Percent % are considered equal.  Every time a new better\n   solution is found, the event 280 is raised, its default handler\n   prints the current cost.\n\n<P>\n   This predicate is to be used for optimization problems when the whole\n   search space is too large or when a suboptimal solution is sufficient.\n\n<P>\n"), args : ["?Goal" : "A callable term.", "?C" : "A linear term.", "+Lower" : "Integer.", "+Upper" : "Integer.", "+Percent" : "Integer."], resat : "   No.", fail_if : "   Fails if Goal fails.\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 6, min_max / 8, minimize / 2, minimize / 4, minimize / 6, minimize / 8, minimize_bound_check / 0]]).
:- comment(minimize / 6, [summary : "Find the solution of Goal that minimizes C, within the bounds set by Lower,\nUpper and Percent in time not longer than Timeout.\n\n", template : "minimize(?Goal, ?C, +Lower, +Upper, +Percent, +Timeout)", desc : html("   A solution of the goal Goal is found that minimizes the value of C. \n   The solution is found using the branch and bound method.  Whenever\n   a better solution is found, the upper cost bound is tightened and\n   the search for a better solution continues.\n\n<P>\n   The starting assumption is that the value to minimize is less than\n   Upper and that any value less than Lower can be considered as a\n   solution.  Moreover, solutions whose minimized values are closer\n   than Percent % are considered equal.  Every time a new better\n   solution is found, the event 280 is raised, its default handler\n   prints the current cost.\n\n<P>\n   If Timeout is not zero, the predicate will stop after Timeout seconds\n   and report the best solution it has found so far.  Calls with specified\n   Timeout cannot be nested.\n\n<P>\n   This predicate is to be used for optimization problems when the whole\n   search space is too large or when a suboptimal solution is sufficient.\n\n<P>\n"), args : ["?Goal" : "A callable term.", "?C" : "A linear term.", "+Lower" : "Integer.", "+Upper" : "Integer.", "+Percent" : "Integer.", "+Timeout" : "A number."], resat : "   No.", fail_if : "   Fails if Goal fails.\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 6, min_max / 8, minimize / 2, minimize / 4, minimize / 5, minimize / 8, minimize_bound_check / 0]]).
:- comment(minimize / 8, [summary : "Find the solution of Goal that minimizes the maximum of elements of C,\nwithin the bounds set by Lower,Upper and Percent in time not longer than\nTimeout.\n\n", template : "minimize(+Goal, ?Template, ?Solution, ?C, +Lower, +Upper, +Percent, +Timeout)", desc : html("   This is the most general version of the minimize predicate with all\n   options.\n\n<P>\n   A solution of the goal Goal is found that minimizes the value of C. \n   The solution is found using the branch and bound method.  Whenever\n   a better solution is found, the upper cost bound is tightened and\n   the search for a better solution continues.\n\n<P>\n   The starting assumption is that the value to minimize is less than\n   Upper and that any value less than Lower can be considered as a\n   final solution.  Moreover, solutions whose minimized values are\n   closer than Percent % are considered equal.  Every time a new\n   better solution is found, the event 280 is raised, its default\n   handler prints the current cost.\n\n<P>\n   Solutions will be unified with a copy of Template where the variables\n   are replaced with their minimized values. Typically, the Template will\n   contain all or a subset of Goal's variables.\n\n<P>\n   If Timeout is not zero, the predicate will stop after Timeout seconds\n   and report the best solution it has found so far.  Calls with specified\n   Timeout cannot be nested.\n\n<P>\n   All other variants of minimize can be written in terms of minimize/9, eg.\n\n<P>\n<PRE>\n\tminimize(Goal, Cost) :-\n\t    minint(Min), maxint(Max),\n\t    minimize(Goal, Goal, Goal, Cost, Min, Max, 0, 0).\n</PRE>\n"), args : ["+Goal" : "A callable term.", "?Template" : "A term containing all or some of Goal's variables", "?Solution" : "Term to be unified with the minimized Template", "?C" : "A linear term or a list of linear terms.", "+Lower" : "An integer.", "+Upper" : "An integer.", "+Percent" : "An integer.", "+Timeout" : "A number."], resat : "   No.", fail_if : "   Fails if there is no solution to Goal.\n\n", eg : "\n    % Find the minimal C and bind X to the corresponding value\n    [eclipse]: X::1..3, C #= 3-X, minimize(indomain(X), X, X, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = 3\n    C = 0\n    yes.\n\n    % Find the minimal C and don't bind anything\n    [eclipse]: X::1..3, C #= 3-X, minimize(indomain(X), [], [], C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n    % Find the minimal C and return it in MinC. Don't bind X or C.\n    [eclipse]: X::1..3, C #= 3-X, minimize(indomain(X), C, MinC, C).\n    Found a solution with cost 2\n    Found a solution with cost 1\n    Found a solution with cost 0\n    X = X{[1..3]}\n    MinC = 0\n    C = C{[0..2]}\n\n    Delayed goals:\n\t    -3 + X{[1..3]} + C{[0..2]}#=0\n    yes.\n\n\n\n\n", see_also : [min_max / 2, min_max / 4, min_max / 5, min_max / 6, min_max / 8, minimize / 2, minimize / 4, minimize / 5, minimize / 6, minimize_bound_check / 0]]).
:- comment(minimize_bound_check / 0, [summary : "If within a minimization, force a check of the cost variable against\nthe cost bound, which may lead to earlier failure.\n\n", template : "minimize_bound_check", desc : html("   This predicate can be used within a goal that is being minimized\n   using minimize/2 or any of its variants. If used in other contexts\n   it has no effect just succeeds.\n\n<P>\n   The behaviour of minimize/2 is such that the cost bound is tightened\n   whenever a better solution is found, but this tightening does not\n   trigger an automatic check.  It can therefore be advantageous and\n   lead to earlier failure when minimize_bound_check/0 is called after\n   every labeling step.\n\n<P>\n"), args : [], resat : "   No.", fail_if : "   Fails if the current cost cannot become smaller that the cost bound.\n\n", eg : "\n    labeling([]).\n    labeling([X|Xs]) :-\n\t% do the check urgently, before any propagation happens\n\tcall_priority((indomain(X), minimize_bound_check), 2),\n\tlabeling(Xs).\n\n\n\n\n", see_also : [minimize / 2, minimize / 4, minimize / 6, minimize / 8]]).
:- comment(new_domain_var / 1, [summary : "A user hook predicate which is called whenever a variable obtains a default\ndomain from the solver.\n\n", template : "new_domain_var(-Var)", desc : html("   This predicate is a simple hook to notify about free variables being\n   converted into domain variables.  Whenever the finite domain solver\n   assigns a free variable a domain, it invokes this predicate in the\n   module fd_domain with the variable as argument.  To use the mechanism,\n   it is necessary to recompile this predicate in the module fd_domain.\n\n<P>\n"), args : ["-Var" : "A variable."], resat : "   No.", fail_if : "   None.\n\n", eg : "\n   [eclipse 22]: compile(user, fd_domain).\n   new_domain_var(X) :- printf(\"new domain variable created: %mw%n\", [X]).\n   user       compiled traceable 88 bytes in 0.00 seconds\n   yes.\n   [eclipse 23]: X+Y #> T.\n   new domain variable created: X[-10000000..10000000]\n   new domain variable created: Y[-10000000..10000000]\n   new domain variable created: T[-10000000..10000000]\n\n\n\n", see_also : [(::) / 2, #:: / 2, default_domain / 1]]).
:- comment(par_indomain / 1, [summary : "Instantiate Var to a number of values in its domain in parallel.\n\n", template : "par_indomain(?Var)", desc : html("   This predicate instantiates the domain variable Var to a value from its\n   domain.  The instantiation is executed in Or-parallel, i.e.  several\n   parallel jobs are created which may be executed in parallel on different\n   processors.  There is no specified order of enumerating the domain of\n   the variable, the user should not rely on a particular order.  It is\n   used mostly to find an instantiation of the variable which is consistent\n   with the current set of constraints in labeling procedures of a parallel\n   program.  If List is a list of all domain variables occurring in the\n   program, the simplest parallel labeling procedure is written as\n\n<P>\n<PRE>\n        labeling([]).\n        labeling([Var|Rest]) :-\n            par_indomain(Var),\n            labeling(Rest).\n</PRE>\n"), args : ["?Var" : "An integer or a domain variable"], resat : "   Yes.", fail_if : "   None.\n\n", see_also : [(::) / 2, #:: / 2, indomain / 1]]).
:- comment(sequence / 4, [summary : "MaxLength is the longest sequence of Item occurring in List and Occurrences\nis the total number of occurrences of Item in List.\n\n", template : "sequence(+List, +Item, ?MaxLength, ?Occurrences)", desc : html("   The constraint is satisfied when MaxLength is the longest sequence of\n   Item occurring in List and Occurrences is the total number of\n   occurrences of Item in List.\n\n<P>\n"), args : ["+List" : "A list of finite domain variables or integers", "+Item" : "An integer", "?MaxLength" : "An integer finite domain variable or an integer.", "?Occurrences" : "An integer finite domain variable or an integer."], resat : "   No.", fail_if : "   None.\n\n", see_also : [contigs / 5]]).
:- comment(sorted_list_to_dom / 2, [summary : "Convert a sorted list of atomic terms and integer intervals into a domain\nDom.\n\n", template : "sorted_list_to_dom(+List, -Dom)", desc : html("   Convert a sorted list of atomic terms and integer intervals into a\n   domain Dom.  List is assumed to be in the correct order and format for a\n   finite domain.  If it is not, the program will not work correctly.  The\n   purpose of this predicate is to quickly convert small lists to domains.\n\n<P>\n"), args : ["+List" : "A sorted list of atomic terms and integer interval.", "-Dom" : "Variable."], resat : "   No.", fail_if : "   None.\n\n", exceptions : [4 : "List is not ground.", 5 : "List contains an element which is neither atomic nor an    integer interval.", 6 : "The size of the resulting domain is too large.", 6 : "The lower bound of an integer interval is greater than its    upper bound."], see_also : [integer_list_to_dom / 2, list_to_dom / 2, dvar_domain / 2]]).
:- comment(var_fd / 2, [summary : "Create a domain variable with a given domain.\n\n", template : "var_fd(+Var, +Dom)", desc : html("   If Var is a free variable, is becomes a domain variable with the domain\n   Dom and with empty suspension lists.  The domain Dom is copied to make\n   in-place updates logically sound.  If Var is already a domain variable,\n   its domain is intersected with the domain Dom.\n\n<P>\n"), args : ["+Var" : "A variable or a domain variable.", "+Dom" : "A finite domain."], resat : "   No.", fail_if : "   Fails if Var is not a variable.\n\n", see_also : [(::) / 2, #:: / 2, dvar_domain / 2]]).
