1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker fad1b07018 Squashed 'software/minizinc/' content from commit 4f10c8205
git-subtree-dir: software/minizinc
git-subtree-split: 4f10c82056ffcb1041d7ffef29d77a7eef92cf76
2021-06-16 14:06:46 +10:00

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;