git-subtree-dir: software/minizinc git-subtree-split: 4f10c82056ffcb1041d7ffef29d77a7eef92cf76
117 lines
5.3 KiB
MiniZinc
117 lines
5.3 KiB
MiniZinc
/***
|
|
@groupdef stdlib.set Set operations
|
|
|
|
These functions implement the basic operations on sets.
|
|
*/
|
|
|
|
/** @group stdlib.set Test if \a x is an element of the set \a y */
|
|
function bool: 'in'( int: x, set of int: y);
|
|
/** @group stdlib.set \a x is an element of the set \a y */
|
|
function var bool: 'in'(var int: x, var set of int: y);
|
|
|
|
/** @group stdlib.set Test if \a x is an element of the set \a y */
|
|
function bool: 'in'( float: x, set of float: y);
|
|
/** @group stdlib.set Test if \a x is an element of the set \a y */
|
|
function var bool: 'in'(var float: x, set of float: y);
|
|
|
|
/** @group stdlib.set Test if \a x is a subset of \a y */
|
|
function bool: 'subset'( set of $T: x, set of $T: y);
|
|
/** @group stdlib.set \a x is a subset of \a y */
|
|
function var bool: 'subset'(var set of int: x, var set of int: y);
|
|
/** @group stdlib.set Test if \a x is a superset of \a y */
|
|
function bool: 'superset'( set of $T: x, set of $T: y);
|
|
/** @group stdlib.set \a x is a superset of \a y */
|
|
function var bool: 'superset'(var set of int: x, var set of int: y);
|
|
|
|
/** @group stdlib.set Return the union of sets \a x and \a y */
|
|
function set of $T: 'union'( set of $T: x, set of $T: y);
|
|
/** @group stdlib.set Return the union of sets \a x and \a y */
|
|
function var set of $$T: 'union'(var set of $$T: x, var set of $$T: y);
|
|
/** @group stdlib.set Return the intersection of sets \a x and \a y */
|
|
function set of $T: 'intersect'( set of $T: x, set of $T: y);
|
|
/** @group stdlib.set Return the intersection of sets \a x and \a y */
|
|
function var set of $$T: 'intersect'(var set of $$T: x, var set of $$T: y);
|
|
/** @group stdlib.set Return the set difference of sets \(\a x \setminus \a y \) */
|
|
function set of $T: 'diff'( set of $T: x, set of $T: y);
|
|
/** @group stdlib.set Return the set difference of sets \(\a x \setminus \a y \) */
|
|
function var set of $$T: 'diff'(var set of $$T: x, var set of $$T: y);
|
|
/** @group stdlib.set Return the symmetric set difference of sets \a x and \a y */
|
|
function set of $T: 'symdiff'( set of $T: x, set of $T: y);
|
|
/** @group stdlib.set Return the symmetric set difference of sets \a x and \a y */
|
|
function var set of $$T: 'symdiff'(var set of $$T: x, var set of $$T: y);
|
|
|
|
/** @group stdlib.set Return the set \(\{\a a,\ldots,\a b\}\) */
|
|
function set of $$E: '..'($$E: a,$$E: b);
|
|
/** @group stdlib.set Return the set \(\{\a a,\ldots,\a b\}\) */
|
|
function set of float: '..'(float: a,float: b);
|
|
/** @group stdlib.set Return the set \(\{\a a,\ldots,\a b\}\) */
|
|
function set of bool: '..'(bool: a,bool: b) =
|
|
if a then if b then {true} else {} endif elseif b then {false,true} else {false} endif;
|
|
|
|
function var set of int: '..'(var int: a, var int: b) ::promise_total =
|
|
let {
|
|
var set of min(lb(a),lb(b))..max(ub(a),ub(b)): s;
|
|
constraint forall (i in ub(s)) (i in s <-> (a <= i /\ i <= b));
|
|
} in s;
|
|
|
|
/** @group stdlib.set Return the cardinality of the set \a x */
|
|
function int: card( set of $T: x);
|
|
/** @group stdlib.set Return the cardinality of the set \a x */
|
|
function var int: card(var set of int: x) ::promise_total = let {
|
|
var 0..card(ub(x)): c;
|
|
constraint set_card(x,c);
|
|
} in c;
|
|
|
|
/** @group stdlib.set Return the union of the sets in array \a x */
|
|
function set of $U: array_union(array[$T] of set of $U: x);
|
|
/** @group stdlib.set Return the union of the sets in array \a x */
|
|
function var set of int: array_union(array[int] of var set of int: x) ::promise_total =
|
|
if length(x)=0 then {}
|
|
elseif length(x)=1 then x[min(index_set(x))]
|
|
else
|
|
let {
|
|
int: l=min(index_set(x));
|
|
int: u=max(index_set(x));
|
|
array[l..u-1] of var set of ub_array(x): y;
|
|
constraint y[l]=x[l] union x[l+1];
|
|
constraint forall (i in l+2..u) (y[i-1]=y[i-2] union x[i]);
|
|
} in y[u-1]
|
|
endif;
|
|
|
|
|
|
/** @group stdlib.set Return the intersection of the sets in array \a x */
|
|
function set of $U: array_intersect(array[$T] of set of $U: x);
|
|
|
|
/** @group stdlib.set Return the intersection of the sets in array \a x */
|
|
function var set of int: array_intersect(array[int] of var set of int: x) ::promise_total =
|
|
if length(x)=0 then assert(false,"can't be!",-infinity..infinity)
|
|
elseif length(x)=1 then x[min(index_set(x))]
|
|
else
|
|
let {
|
|
int: l=min(index_set(x));
|
|
int: u=max(index_set(x));
|
|
array[l..u-1] of var set of ub_array(x): y;
|
|
constraint y[l]=x[l] intersect x[l+1];
|
|
constraint forall (i in l+2..u) (y[i-1]=y[i-2] intersect x[i]);
|
|
} in y[u-1]
|
|
endif;
|
|
|
|
/** @group stdlib.set Return the minimum of the set \a s */
|
|
function var $$E: min(var set of $$E: s);
|
|
|
|
/** @group stdlib.set Return the maximum of the set \a s */
|
|
function var $$E: max(var set of $$E: s);
|
|
|
|
/* Rewrite set membership on float variables to correct FlatZinc builtin */
|
|
predicate set_in(var float: x, set of float: S) = float_set_in(x, S);
|
|
|
|
/** @group stdlib.set Return a sorted list of the non-overlapping ranges in \a S */
|
|
function array[int] of int: set_to_ranges(set of int: S);
|
|
/** @group stdlib.set Return a sorted list of the non-overlapping ranges in \a S */
|
|
function array[int] of float: set_to_ranges(set of float: S);
|
|
/** @group stdlib.set Return a sorted list of the non-overlapping ranges in \a S */
|
|
function array[int] of bool: set_to_ranges(set of bool: S) =
|
|
if S={false} then [false,false] elseif S={true} then [true,true] else [false,true] endif;
|
|
|
|
|