this repo has no description
1include "flatzinc_builtins.mzn";
2include "mzncc_builtins.mzn";
3
4/***
5 @groupdef builtins Builtins
6
7 These functions and predicates define built-in operations of the MiniZinc language.
8
9*/
10
11/***
12 @groupdef builtins.compare Comparison Builtins
13
14 These builtins implement comparison operations.
15*/
16
17/** @group builtins.compare Return if \a x is less than \a y */
18function bool: '<'( $T: x, $T: y);
19/** @group builtins.compare Return if \a x is less than \a y */
20function var bool: '<'(var $T: x,var $T: y);
21/** @group builtins.compare Return if \a x is greater than \a y */
22function bool: '>'( $T: x, $T: y);
23/** @group builtins.compare Return if \a x is greater than \a y */
24function var bool: '>'(var $T: x,var $T: y);
25/** @group builtins.compare Return if \a x is less than or equal to \a y */
26function bool: '<='( $T: x, $T: y);
27/** @group builtins.compare Return if \a x is less than or equal to \a y */
28function var bool: '<='(var $T: x, var $T: y);
29/** @group builtins.compare Return if \a x is greater than or equal to \a y */
30function bool: '>='( $T: x, $T: y);
31/** @group builtins.compare Return if \a x is greater than or equal to \a y */
32function var bool: '>='(var $T: x,var $T: y);
33/** @group builtins.compare Return if \a x is equal to \a y */
34function bool: '='( $T: x, $T: y);
35/** @group builtins.compare Return if \a x is equal to \a y */
36function bool: '='(opt $T: x, opt $T: y);
37/** @group builtins.compare Return if \a x is equal to \a y */
38function var bool: '='(var $T: x,var $T: y);
39/** @group builtins.compare Return if \a x is equal to \a y */
40function var bool: '='(var opt $T: x,var opt $T: y);
41
42/** @group builtins.compare Return if \a x is not equal to \a y */
43function bool: '!='( $T: x, $T: y);
44/** @group builtins.compare Return if \a x is not equal to \a y */
45function var bool: '!='(var $T: x, var $T: y);
46
47% Special case comparison operators for integer variable and float constant
48function var bool: '<='(var int: x, float: y) = (x <= floor(y));
49function var bool: '>='(var int: x, float: y) = (x >= ceil(y));
50function var bool: '<='(float: x, var int: y) = (y >= ceil(x));
51function var bool: '>='(float: x, var int: y) = (y <= floor(x));
52
53function var bool: '<'(var int: x, float: y) = (x <= ceil(y)-1);
54function var bool: '>'(float: x, var int: y) = (y <= ceil(x)-1);
55function var bool: '>'(var int: x, float: y) = (x >= floor(y)+1);
56function var bool: '<'(float: x, var int: y) = (y >= floor(x)+1);
57
58function var bool: '='(var int: x, float: y) =
59 if ceil(y)=floor(y) then x=ceil(y) else false endif;
60function var bool: '='(float: x, var int: y) =
61 if ceil(x)=floor(x) then y=ceil(x) else false endif;
62
63function var bool: '!='(var int: x, float: y) =
64 if ceil(y)=floor(y) then x != ceil(y) else true endif;
65function var bool: '!='(float: x, var int: y) =
66 if ceil(x)=floor(x) then y != ceil(x) else true endif;
67
68function bool: '<='(int: x, float: y) = (x <= floor(y));
69function bool: '>='(int: x, float: y) = (x >= ceil(y));
70function bool: '<='(float: x, int: y) = (y >= ceil(x));
71function bool: '>='(float: x, int: y) = (y <= floor(x));
72
73function bool: '<'(int: x, float: y) = (x <= ceil(y)-1);
74function bool: '>'(float: x, int: y) = (y <= ceil(x)-1);
75function bool: '>'(int: x, float: y) = (x >= floor(y)+1);
76function bool: '<'(float: x, int: y) = (y >= floor(x)+1);
77
78function bool: '='(int: x, float: y) =
79 if ceil(y)=floor(y) then x=ceil(y) else false endif;
80function bool: '='(float: x, int: y) =
81 if ceil(x)=floor(x) then y=ceil(x) else false endif;
82
83function bool: '!='(int: x, float: y) =
84 if ceil(y)=floor(y) then x != ceil(y) else true endif;
85function bool: '!='(float: x, int: y) =
86 if ceil(x)=floor(x) then y != ceil(x) else true endif;
87
88
89/** @group builtins.compare Return if array \a x is lexicographically smaller than array \a y */
90function bool: '<'(array[$U] of $T: x,array[$U] of $T: y);
91/** @group builtins.compare Return if array \a x is lexicographically smaller than array \a y */
92function var bool: '<'(array[$U] of var $T: x,array[$U] of var $T: y);
93/** @group builtins.compare Return if array \a x is lexicographically greater than array \a y */
94function bool: '>'(array[$U] of $T: x,array[$U] of $T: y);
95/** @group builtins.compare Return if array \a x is lexicographically greater than array \a y */
96function var bool: '>'(array[$U] of var $T: x,array[$U] of var $T: y);
97/** @group builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */
98function bool: '<='(array[$U] of $T: x,array[$U] of $T: y);
99/** @group builtins.compare Return if array \a x is lexicographically smaller than or equal to array \a y */
100function var bool: '<='(array[$U] of var $T: x,array[$U] of var $T: y);
101/** @group builtins.compare Return if array \a x is lexicographically greater than or equal to array \a y */
102function bool: '>='(array[$U] of $T: x,array[$U] of $T: y);
103function var bool: '>='(array[$U] of var $T: x,array[$U] of var $T: y);
104
105/** @group builtins.compare Return if array \a x is equal to array \a y */
106function bool: '='(array[$T] of int: x,array[$T] of int: y) =
107 let {
108 array[int] of int: xx = array1d(x);
109 array[int] of int: yy = array1d(y);
110 } in
111 assert(index_sets_agree(x,y), "array index sets do not match",
112 forall (i in index_set(xx)) (xx[i]=yy[i])
113 );
114
115/** @group builtins.compare Return if array \a x is equal to array \a y */
116function var bool: '='(array[$T] of var int: x,array[$T] of var int: y) =
117 let {
118 array[int] of var int: xx = array1d(x);
119 array[int] of var int: yy = array1d(y);
120 } in
121 assert(index_sets_agree(x,y), "array index sets do not match",
122 forall (i in index_set(xx)) (xx[i]=yy[i])
123 );
124
125/** @group builtins.compare Return if array \a x is equal to array \a y */
126function bool: '='(array[$T] of bool: x,array[$T] of bool: y) =
127 let {
128 array[int] of bool: xx = array1d(x);
129 array[int] of bool: yy = array1d(y);
130 } in
131 assert(index_sets_agree(x,y), "array index sets do not match",
132 forall (i in index_set(xx)) (xx[i]=yy[i])
133 );
134
135/** @group builtins.compare Return if array \a x is equal to array \a y */
136function var bool: '='(array[$T] of var bool: x,array[$T] of var bool: y) =
137 let {
138 array[int] of var bool: xx = array1d(x);
139 array[int] of var bool: yy = array1d(y);
140 } in
141 assert(index_sets_agree(x,y), "array index sets do not match",
142 forall (i in index_set(xx)) (xx[i]=yy[i])
143 );
144
145/** @group builtins.compare Return if array \a x is equal to array \a y */
146function bool: '='(array[$T] of set of int: x,array[$T] of set of int: y) =
147 let {
148 array[int] of set of int: xx = array1d(x);
149 array[int] of set of int: yy = array1d(y);
150 } in
151 assert(index_sets_agree(x,y), "array index sets do not match",
152 forall (i in index_set(xx)) (xx[i]=yy[i])
153 );
154
155/** @group builtins.compare Return if array \a x is equal to array \a y */
156function var bool: '='(array[$T] of var set of int: x,array[$T] of var set of int: y) =
157 let {
158 array[int] of var set of int: xx = array1d(x);
159 array[int] of var set of int: yy = array1d(y);
160 } in
161 assert(index_sets_agree(x,y), "array index sets do not match",
162 forall (i in index_set(xx)) (xx[i]=yy[i])
163 );
164
165/** @group builtins.compare Return if array \a x is equal to array \a y */
166function bool: '='(array[$T] of float: x,array[$T] of float: y) =
167 let {
168 array[int] of float: xx = array1d(x);
169 array[int] of float: yy = array1d(y);
170 } in
171 assert(index_sets_agree(x,y), "array index sets do not match",
172 forall (i in index_set(xx)) (xx[i]=yy[i])
173 );
174
175/** @group builtins.compare Return if array \a x is equal to array \a y */
176function var bool: '='(array[$T] of var float: x,array[$T] of var float: y) =
177 let {
178 array[int] of var float: xx = array1d(x);
179 array[int] of var float: yy = array1d(y);
180 } in
181 assert(index_sets_agree(x,y), "array index sets do not match",
182 forall (i in index_set(xx)) (xx[i]=yy[i])
183 );
184
185/** @group builtins.compare Return if array \a x is not equal to array \a y */
186function bool: '!='(array[$U] of $T: x,array[$U] of $T: y);
187/** @group builtins.compare Return if array \a x is not equal to array \a y */
188function var bool: '!='(array[$U] of var $T: x,array[$U] of var $T: y);
189
190/***
191 @groupdef builtins.arithmetic Arithmetic Builtins
192
193 These builtins implement arithmetic operations.
194*/
195
196/** @group builtins.arithmetic Return \a x + \a y */
197function int: '+'( int: x, int: y);
198/** @group builtins.arithmetic Return \a x + \a y */
199function var int: '+'(var int: x, var int: y);
200/** @group builtins.arithmetic Return \a x + \a y */
201function float: '+'( float: x, float: y);
202/** @group builtins.arithmetic Return \a x + \a y */
203function var float: '+'(var float: x,var float: y);
204/** @group builtins.arithmetic Return \a x - \a y */
205function int: '-'( int: x, int: y);
206/** @group builtins.arithmetic Return \a x - \a y */
207function var int: '-'(var int: x, var int: y);
208/** @group builtins.arithmetic Return \a x - \a y */
209function float: '-'( float: x, float: y);
210/** @group builtins.arithmetic Return \a x - \a y */
211function var float: '-'(var float: x,var float: y);
212/** @group builtins.arithmetic Return \a x * \a y */
213function int: '*'( int: x, int: y);
214/** @group builtins.arithmetic Return \a x * \a y */
215function var int: '*'(var int: x, var int: y);
216/** @group builtins.arithmetic Return \a x ^ \a y */
217function int: '^'( int: x, int: y);
218/** @group builtins.arithmetic Return \a x ^ \a y */
219function var int: '^'(var int: x, var int: y);
220/** @group builtins.arithmetic Return \a x * \a y */
221function float: '*'( float: x, float: y);
222/** @group builtins.arithmetic Return \a x * \a y */
223function var float: '*'(var float: x,var float: y);
224/** @group builtins.arithmetic Return \a x ^ \a y */
225function float: '^'( float: x, float: y);
226/** @group builtins.arithmetic Return \a x ^ \a y */
227function var float: '^'(var float: x,var float: y);
228/** @group builtins.arithmetic Return negative \a x */
229function int: '-'( int: x);
230/** @group builtins.arithmetic Return negative \a x */
231function var int: '-'(var int: x);
232/** @group builtins.arithmetic Return negative \a x */
233function float: '-'( float: x);
234/** @group builtins.arithmetic Return negative \a x */
235function var float: '-'(var float: x);
236
237/** @group builtins.arithmetic Return result of integer division \a x / \a y */
238function int: 'div'(int: x,int: y);
239
240/** @group builtins.arithmetic Return result of integer division \a x / \a y */
241function var int: 'div'(var int: x,var int: y) =
242 if mzn_in_root_context(y) \/ not (0 in dom(y)) then div_t(x,y) else
243 let { constraint y != 0 } in div_mt(x,y) endif;
244
245/** @group builtins.arithmetic Return remainder of integer division \a x % \a y */
246function int: 'mod'(int: x,int: y);
247
248/** @group builtins.arithmetic Return remainder of integer division \a x % \a y */
249function var int: 'mod'(var int: x,var int: y) =
250 if mzn_in_root_context(y) \/ not (0 in dom(y)) then mod_t(x,y) else
251 let { constraint y != 0 } in mod_mt(x,y) endif;
252
253/** @group builtins.arithmetic Return result of floating point division \a x / \a y */
254function float: '/'( float: x, float: y);
255/** @group builtins.arithmetic Return result of floating point division \a x / \a y */
256function var float: '/'(var float: x,var float: y) =
257 if mzn_in_root_context(y) \/ lb(y) > 0.0 \/ ub(y) < 0.0 then fldiv_t(x,y) else
258 let { constraint y != 0.0 } in fldiv_mt(x,y) endif;
259
260/** @group builtins.arithmetic Return sum of elements in array \a x */
261function int: sum(array[$T] of int: x);
262/** @group builtins.arithmetic Return sum of elements in array \a x */
263function var int: sum(array[$T] of var int: x);
264/** @group builtins.arithmetic Return sum of elements in array \a x */
265function float: sum(array[$T] of float: x);
266/** @group builtins.arithmetic Return sum of elements in array \a x */
267function var float: sum(array[$T] of var float: x);
268
269/** @group builtins.arithmetic Return product of elements in array \a x */
270function int: product(array[$T] of int: x);
271/** @group builtins.arithmetic Return product of elements in array \a x */
272function var int: product(array[$T] of var int: x) =
273 product_rec(array1d(x));
274
275/** @group builtins.arithmetic Return product of elements in array \a x */
276function float: product(array[$T] of float: x);
277/** @group builtins.arithmetic Return product of elements in array \a x */
278function var float: product(array[$T] of var float: x) =
279 product_rec(array1d(x));
280
281% /** @group builtins.arithmetic Return minimum of \a x and \a y */
282% function $T: min( $T: x, $T: y);
283% /** @group builtins.arithmetic Return minimum of elements in array \a x */
284% function $T: min(array[$U] of par $T: x);
285% /** @group builtins.arithmetic Return maximum of \a x and \a y */
286% function $T: max( $T: x, $T: y);
287% /** @group builtins.arithmetic Return maximum of elements in array \a x */
288% function $T: max(array[$U] of $T: x);
289% /** @group builtins.arithmetic Return minimum of elements in set \a x */
290% function $$E: min(set of $$E: x);
291% /** @group builtins.arithmetic Return maximum of elements in set \a x */
292% function $$E: max(set of $$E: x);
293
294/** @group builtins.arithmetic Return maximum of \a x and \a y */
295function var int: max(var int: x, var int: y) :: promise_total =
296 let { var max(lb(x),lb(y))..max(ub(x),ub(y)): m ::is_defined_var;
297 constraint int_max(x,y,m) ::defines_var(m);
298 } in m;
299
300/** @group builtins.arithmetic Return maximum of elements in array \a x */
301function var int: max(array[$U] of var int: x) =
302 let {
303 array[int] of var int: xx = array1d(x);
304 constraint length(x) >= 1;
305 } in max_t(xx);
306
307/** @group builtins.arithmetic Return minimum of \a x and \a y */
308function var int: min(var int: x, var int: y) :: promise_total =
309 let { var min(lb(x),lb(y))..min(ub(x),ub(y)): m ::is_defined_var;
310 constraint int_min(x,y,m) ::defines_var(m);
311 } in m;
312
313/** @group builtins.arithmetic Return minimum of elements in array \a x */
314function var int: min(array[$U] of var int: x) =
315 let {
316 array[int] of var int: xx = array1d(x);
317 constraint length(x) >= 1;
318 } in min_t(xx);
319
320% Floating point min and max
321% TODO: add bounds reasoning
322
323/** @group builtins.arithmetic Return maximum of \a x and \a y */
324function var float: max(var float: x, var float: y) :: promise_total =
325 let { var float: m ::is_defined_var;
326 constraint float_max(x,y,m) ::defines_var(m);
327 } in m;
328
329/** @group builtins.arithmetic Return maximum of elements in array \a x */
330function var float: max(array[$U] of var float: x) =
331 let {
332 array[int] of var float: xx = array1d(x);
333 constraint length(x) >= 1;
334 } in max_t(xx);
335
336/** @group builtins.arithmetic Return minimum of \a x and \a y */
337function var float: min(var float: x, var float: y) :: promise_total =
338 let { var float: m ::is_defined_var;
339 constraint float_min(x,y,m) ::defines_var(m);
340 } in m;
341
342/** @group builtins.arithmetic Return minimum of elements in array \a x */
343function var float: min(array[$U] of var float: x) =
344 let {
345 array[int] of var float: xx = array1d(x);
346 constraint length(x) >= 1;
347 } in min_t(xx);
348
349
350/** @group builtins.arithmetic Return index of minimum of elements in array \a x */
351function $$E: arg_min(array[$$E] of int: x);
352/** @group builtins.arithmetic Return index of minimum of elements in array \a x */
353function $$E: arg_min(array[$$E] of float: x);
354/** @group builtins.arithmetic Return index of maximum of elements in array \a x */
355function $$E: arg_max(array[$$E] of int: x);
356/** @group builtins.arithmetic Return index of maximum of elements in array \a x */
357function $$E: arg_max(array[$$E] of float: x);
358
359/** @group builtins.arithmetic Return absolute value of \a x */
360function int: abs(int: x);
361
362/** @group builtins.arithmetic Return absolute value of \a x */
363function var int: abs(var int: x) :: promise_total =
364 if has_bounds(x) /\ lb(x) >= 0 then x
365 elseif has_bounds(x) /\ ub(x) < 0 then -x else
366 let { var 0..max(-lb(x),ub(x)): m ::is_defined_var;
367 constraint int_abs(x,m) ::defines_var(m);
368 } in m
369 endif;
370
371/** @group builtins.arithmetic Return absolute value of \a x */
372function float: abs(float: x);
373/** @group builtins.arithmetic Return absolute value of \a x */
374function var float: abs(var float: x) :: promise_total =
375 if has_bounds(x) then
376 if lb(x) >= 0.0 then x else
377 let { var 0.0..max(-lb(x),ub(x)): m ::is_defined_var;
378 constraint float_abs(x,m) ::defines_var(m);
379 } in m
380 endif
381 else
382 let { var float: m ::is_defined_var;
383 constraint m >= 0.0;
384 constraint float_abs(x,m) ::defines_var(m);
385 } in m
386 endif;
387
388/** @group builtins.arithmetic Return \(\sqrt{\a x}\) */
389function float: sqrt(float: x);
390/** @group builtins.arithmetic Return \(\sqrt{\a x}\) */
391function var float: sqrt(var float: x) =
392 let {
393 constraint x >= 0.0;
394 } in sqrt_t(x);
395
396function var float: sqrt_t(var float: x) ::promise_total =
397 let {
398 var float: r;
399 var float: xx;
400 constraint x < 0.0 -> xx = 1.0;
401 constraint x < 0.0 \/ xx = x;
402 constraint float_sqrt(xx,r);
403 } in r;
404
405/** @group builtins.arithmetic Return \(\a x ^ {\a y}\) */
406function int: pow(int: x, int: y);
407
408/** @group builtins.arithmetic Return \(\a x ^ {\a y}\) */
409function var int: pow(var int: x, var int: y) =
410 let {
411 int: yy = if is_fixed(y) then fix(y) else -1 endif;
412 } in
413 if yy = 0 then 1
414 elseif yy = 1 then x else
415 let { var int: r ::is_defined_var;
416 constraint if is_fixed(y) then int_pow_fixed(x,fix(y),r) ::defines_var(r) else int_pow(x,y,r) ::defines_var(r) endif;
417 } in r
418 endif;
419
420
421/** @group builtins.arithmetic Return \(\a x ^ {\a y}\) */
422function float: pow(float: x, float: y);
423
424/** @group builtins.arithmetic Return \(\a x ^ {\a y}\) */
425function var float: pow(var float: x, var float: y) =
426 let {
427 float: yy = if is_fixed(y) then fix(y) else -1.0 endif
428 } in
429 if yy = 0.0 then 1.0
430 elseif yy = 1.0 then x else
431 let { var float: r ::is_defined_var;
432 constraint float_pow(x,y,r) ::defines_var(r);
433 } in r
434 endif;
435
436/***
437 @groupdef builtins.explog Exponential and logarithmic builtins
438
439 These builtins implement exponential and logarithmic functions.
440*/
441
442/** @group builtins.explog Return \(e ^ {\a x}\) */
443function float: exp(float: x);
444/** @group builtins.explog Return \(e ^ {\a x}\) */
445function var float: exp(var float: x) ::promise_total =
446 let {
447 var float: r ::is_defined_var;
448 constraint float_exp(x,r) ::defines_var(r);
449 } in r;
450
451/** @group builtins.explog Return \(\ln \a x\) */
452function float: ln(float: x);
453/** @group builtins.explog Return \(\ln \a x\) */
454function var float: ln(var float: x) ::promise_total =
455 let {
456 var float: r ::is_defined_var;
457 constraint float_ln(x,r) ::defines_var(r);
458 } in r;
459
460/** @group builtins.explog Return \(\log_{10} \a x\) */
461function float: log10(float: x);
462/** @group builtins.explog Return \(\log_{10} \a x\) */
463function var float: log10(var float: x) ::promise_total =
464 let {
465 var float: r ::is_defined_var;
466 constraint float_log10(x,r) ::defines_var(r);
467 } in r;
468
469/** @group builtins.explog Return \(\log_{2} \a x\) */
470function float: log2(float: x);
471/** @group builtins.explog Return \(\log_{2} \a x\) */
472function var float: log2(var float: x) ::promise_total =
473 let {
474 var float: r ::is_defined_var;
475 constraint float_log2(x,r) ::defines_var(r);
476 } in r;
477
478/** @group builtins.explog Return \(\log_{\a x} \a y\) */
479function float: log(float: x, float: y);
480
481/***
482 @groupdef builtins.trigonometric Trigonometric functions
483
484 These builtins implement the standard trigonometric functions.
485*/
486
487/** @group builtins.trigonometric Return \(\sin \a x\) */
488function float: sin(float: x);
489/** @group builtins.trigonometric Return \(\sin \a x\) */
490function var float: sin(var float: x) ::promise_total =
491 let {
492 var -1.0..1.0: r ::is_defined_var;
493 constraint float_sin(x,r) ::defines_var(r);
494 } in r;
495
496/** @group builtins.trigonometric Return \(\cos \a x\) */
497function float: cos(float: x);
498/** @group builtins.trigonometric Return \(\cos \a x\) */
499function var float: cos(var float: x) ::promise_total =
500 let {
501 var -1.0..1.0: r ::is_defined_var;
502 constraint float_cos(x,r) ::defines_var(r);
503 } in r;
504
505/** @group builtins.trigonometric Return \(\tan \a x\) */
506function float: tan(float: x);
507/** @group builtins.trigonometric Return \(\tan \a x\) */
508function var float: tan(var float: x) ::promise_total =
509 let {
510 var float: r ::is_defined_var;
511 constraint float_tan(x,r) ::defines_var(r);
512 } in r;
513
514/** @group builtins.trigonometric Return \(\mbox{asin}\ \a x\) */
515function float: asin(float: x);
516/** @group builtins.trigonometric Return \(\mbox{asin}\ \a x\) */
517function var float: asin(var float: x) ::promise_total =
518 let {
519 var float: r ::is_defined_var;
520 constraint float_asin(x,r) ::defines_var(r);
521 } in r;
522
523/** @group builtins.trigonometric Return \(\mbox{acos}\ \a x\) */
524function float: acos(float: x);
525/** @group builtins.trigonometric Return \(\mbox{acos}\ \a x\) */
526function var float: acos(var float: x) ::promise_total =
527 let {
528 var float: r ::is_defined_var;
529 constraint float_acos(x,r) ::defines_var(r);
530 } in r;
531
532/** @group builtins.trigonometric Return \(\mbox{atan}\ \a x\) */
533function float: atan(float: x);
534/** @group builtins.trigonometric Return \(\mbox{atan}\ \a x\) */
535function var float: atan(var float: x) ::promise_total =
536 let {
537 var float: r ::is_defined_var;
538 constraint float_atan(x,r) ::defines_var(r);
539 } in r;
540
541/** @group builtins.trigonometric Return \(\sinh \a x\) */
542function float: sinh(float: x);
543/** @group builtins.trigonometric Return \(\sinh \a x\) */
544function var float: sinh(var float: x) ::promise_total =
545 let {
546 var float: r ::is_defined_var;
547 constraint float_sinh(x,r) ::defines_var(r);
548 } in r;
549
550/** @group builtins.trigonometric Return \(\cosh \a x\) */
551function float: cosh(float: x);
552/** @group builtins.trigonometric Return \(\cosh \a x\) */
553function var float: cosh(var float: x) ::promise_total =
554 let {
555 var float: r ::is_defined_var;
556 constraint float_cosh(x,r) ::defines_var(r);
557 } in r;
558
559/** @group builtins.trigonometric Return \(\tanh \a x\) */
560function float: tanh(float: x);
561/** @group builtins.trigonometric Return \(\tanh \a x\) */
562function var float: tanh(var float: x) ::promise_total =
563 let {
564 var float: r ::is_defined_var;
565 constraint float_tanh(x,r) ::defines_var(r);
566 } in r;
567
568/** @group builtins.trigonometric Return \(\mbox{asinh}\ \a x\) */
569function float: asinh(float: x);
570/** @group builtins.trigonometric Return \(\mbox{asinh}\ \a x\) */
571function var float: asinh(var float: x) ::promise_total =
572 let {
573 var float: r ::is_defined_var;
574 constraint float_asinh(x,r) ::defines_var(r);
575 } in r;
576
577/** @group builtins.trigonometric Return \(\mbox{acosh}\ \a x\) */
578function float: acosh(float: x);
579/** @group builtins.trigonometric Return \(\mbox{acosh}\ \a x\) */
580function var float: acosh(var float: x) ::promise_total =
581 let {
582 var float: r ::is_defined_var;
583 constraint float_acosh(x,r) ::defines_var(r);
584 } in r;
585
586/** @group builtins.trigonometric Return \(\mbox{atanh}\ \a x\) */
587function float: atanh(float: x);
588/** @group builtins.trigonometric Return \(\mbox{atanh}\ \a x\) */
589function var float: atanh(var float: x) ::promise_total =
590 let {
591 var float: r ::is_defined_var;
592 constraint float_atanh(x,r) ::defines_var(r);
593 } in r;
594
595
596/***
597 @groupdef builtins.logic Logical operations
598
599 Logical operations are the standard operators of Boolean logic.
600*/
601
602/** @group builtins.logic Return truth value of \a x ∧ \a y */
603function bool: '/\'( bool: x, bool: y);
604/** @group builtins.logic Return truth value of \a x ∧ \a y */
605function var bool: '/\'(var bool: x, var bool: y);
606/** @group builtins.logic Return truth value of \a x ∨ \a y */
607function bool: '\/'( bool: x, bool: y);
608/** @group builtins.logic Return truth value of \a x ∨ \a y */
609function var bool: '\/'(var bool: x, var bool: y);
610/** @group builtins.logic Return truth value of \a x implies \a y */
611function bool: '->'( bool: x, bool: y);
612/** @group builtins.logic Return truth value of \a x implies \a y */
613function var bool: '->'(var bool: x, var bool: y);
614/** @group builtins.logic Return truth value of \a y implies \a x */
615function bool: '<-'( bool: x, bool: y);
616/** @group builtins.logic Return truth value of \a y implies \a x */
617function var bool: '<-'(var bool: x, var bool: y);
618/** @group builtins.logic Return truth value of \a x if-and-only-if \a y */
619function bool: '<->'( bool: x, bool: y);
620/** @group builtins.logic Return truth value of \a x if-and-only-if \a y */
621function var bool: '<->'(var bool: x, var bool: y);
622/** @group builtins.logic Return truth value of \a x xor \a y */
623function bool: 'xor'( bool: x, bool: y);
624/** @group builtins.logic Return truth value of \a x xor \a y */
625function var bool: 'xor'(var bool: x, var bool: y);
626/** @group builtins.logic Return truth value of the negation of \a x */
627function bool: 'not'( bool: x);
628/** @group builtins.logic Return truth value of the negation of \a x */
629function var bool: 'not'(var bool: x);
630
631/** @group builtins.logic Return truth value of \(\bigwedge_i \a x[i]\) */
632function bool: forall(array[$T] of bool: x);
633/** @group builtins.logic Return truth value of \(\bigwedge_i \a x[i]\) */
634function var bool: forall(array[$T] of var bool: x);
635/** @group builtins.logic Return truth value of \(\bigvee_i \a x[i]\) */
636function bool: exists(array[$T] of bool: x);
637/** @group builtins.logic Return truth value of \(\bigvee_i \a x[i]\) */
638function var bool: exists(array[$T] of var bool: x);
639/** @group builtins.logic Return truth value of \(\oplus_i \a x[i]\) */
640function bool: xorall(array[$T] of bool: x);
641/** @group builtins.logic Return truth value of \(\oplus_i \a x[i]\) */
642function var bool: xorall(array[$T] of var bool: x) =
643 array_bool_xor(array1d(x));
644/** @group builtins.logic Return truth value of \(\text{true}\oplus (\oplus_i \a x[i])\) */
645function bool: iffall(array[$T] of bool: x);
646/** @group builtins.logic Return truth value of \(\text{true}\oplus (\oplus_i \a x[i])\) */
647function var bool: iffall(array[$T] of var bool: x) =
648 array_bool_xor(array1d(x)++[true]);
649/** @group builtins.logic Return truth value of \((\bigvee_i \a x[i]) \lor (\bigvee_j \lnot \a y[j])\) */
650function var bool: clause(array[$T] of var bool: x, array[$T] of var bool: y);
651/** @group builtins.logic Return truth value of \((\bigvee_i \a x[i]) \lor (\bigvee_j \lnot \a y[j])\) */
652function var bool: clause(array[$T] of bool: x, array[$T] of bool: y);
653
654/***
655 @groupdef builtins.set Set operations
656
657 These functions implement the basic operations on sets.
658*/
659
660/** @group builtins.set Test if \a x is an element of the set \a y */
661function bool: 'in'( int: x, set of int: y);
662/** @group builtins.set \a x is an element of the set \a y */
663function var bool: 'in'(var int: x, var set of int: y);
664
665/** @group builtins.set Test if \a x is an element of the set \a y */
666function bool: 'in'( float: x, set of float: y);
667/** @group builtins.set Test if \a x is an element of the set \a y */
668function var bool: 'in'(var float: x, set of float: y);
669
670/** @group builtins.set Test if \a x is a subset of \a y */
671function bool: 'subset'( set of $T: x, set of $T: y);
672/** @group builtins.set \a x is a subset of \a y */
673function var bool: 'subset'(var set of int: x, var set of int: y);
674/** @group builtins.set Test if \a x is a superset of \a y */
675function bool: 'superset'( set of $T: x, set of $T: y);
676/** @group builtins.set \a x is a superset of \a y */
677function var bool: 'superset'(var set of int: x, var set of int: y);
678
679/** @group builtins.set Return the union of sets \a x and \a y */
680function set of $T: 'union'( set of $T: x, set of $T: y);
681/** @group builtins.set Return the union of sets \a x and \a y */
682function var set of $$T: 'union'(var set of $$T: x, var set of $$T: y);
683/** @group builtins.set Return the intersection of sets \a x and \a y */
684function set of $T: 'intersect'( set of $T: x, set of $T: y);
685/** @group builtins.set Return the intersection of sets \a x and \a y */
686function var set of $$T: 'intersect'(var set of $$T: x, var set of $$T: y);
687/** @group builtins.set Return the set difference of sets \a x − \a y */
688function set of $T: 'diff'( set of $T: x, set of $T: y);
689/** @group builtins.set Return the set difference of sets \a x − \a y */
690function var set of $$T: 'diff'(var set of $$T: x, var set of $$T: y);
691/** @group builtins.set Return the symmetric set difference of sets \a x and \a y */
692function set of $T: 'symdiff'( set of $T: x, set of $T: y);
693/** @group builtins.set Return the symmetric set difference of sets \a x and \a y */
694function var set of $$T: 'symdiff'(var set of $$T: x, var set of $$T: y);
695
696/** @group builtins.set Return the set \(\{\a a,\ldots,\a b\}\) */
697function set of $$E: '..'($$E: a,$$E: b);
698/** @group builtins.set Return the set \(\{\a a,\ldots,\a b\}\) */
699function set of float: '..'(float: a,float: b);
700
701function var set of int: '..'(var int: a, var int: b) ::promise_total =
702 let {
703 var set of min(lb(a),lb(b))..max(ub(a),ub(b)): s;
704 constraint forall (i in ub(s)) (i in s <-> (a <= i /\ i <= b));
705 } in s;
706
707/** @group builtins.set Return the cardinality of the set \a x */
708function int: card( set of $T: x);
709/** @group builtins.set Return the cardinality of the set \a x */
710function var int: card(var set of int: x);
711
712/** @group builtins.set Return the union of the sets in array \a x */
713function set of $U: array_union(array[$T] of set of $U: x);
714/** @group builtins.set Return the union of the sets in array \a x */
715function var set of int: array_union(array[int] of var set of int: x) ::promise_total =
716 if length(x)=0 then {}
717 elseif length(x)=1 then x[min(index_set(x))]
718 else
719 let {
720 int: l=min(index_set(x));
721 int: u=max(index_set(x));
722 array[l..u-1] of var set of ub_array(x): y;
723 constraint y[l]=x[l] union x[l+1];
724 constraint forall (i in l+2..u) (y[i-1]=y[i-2] union x[i]);
725 } in y[u-1]
726 endif;
727
728
729/** @group builtins.set Return the intersection of the sets in array \a x */
730function set of $U: array_intersect(array[$T] of set of $U: x);
731
732/** @group builtins.set Return the intersection of the sets in array \a x */
733function var set of int: array_intersect(array[int] of var set of int: x) ::promise_total =
734 if length(x)=0 then assert(false,"can't be!",-infinity..infinity)
735 elseif length(x)=1 then x[min(index_set(x))]
736 else
737 let {
738 int: l=min(index_set(x));
739 int: u=max(index_set(x));
740 array[l..u-1] of var set of ub_array(x): y;
741 constraint y[l]=x[l] intersect x[l+1];
742 constraint forall (i in l+2..u) (y[i-1]=y[i-2] intersect x[i]);
743 } in y[u-1]
744 endif;
745
746/** @group builtins.set Return the minimum of the set \a s */
747function var $$E: min(var set of $$E: s);
748
749/** @group builtins.set Return the maximum of the set \a s */
750function var $$E: max(var set of $$E: s);
751
752/***
753 @groupdef builtins.array Array operations
754
755 These functions implement the basic operations on arrays.
756*/
757
758/** @group builtins.array Return the concatenation of arrays \a x and \a y */
759function array[int] of $T: '++'(array[int] of $T: x, array[int] of $T: y);
760/** @group builtins.array Return the concatenation of arrays \a x and \a y */
761function array[int] of opt $T: '++'(array[int] of opt $T: x, array[int] of opt $T: y);
762/** @group builtins.array Return the concatenation of arrays \a x and \a y */
763function array[int] of var $T: '++'(array[int] of var $T: x, array[int] of var $T: y);
764/** @group builtins.array Return the concatenation of arrays \a x and \a y */
765function array[int] of var opt $T: '++'(array[int] of var opt $T: x, array[int] of var opt $T: y);
766
767/** @group builtins.array Return the length of array \a x
768
769 Note that the length is defined as the number of elements in the
770 array, regardless of its dimensionality.
771*/
772function int: length(array[$T] of var opt $U: x);
773
774/** @group builtins.array Return the array \a x in reverse order
775
776 The resulting array has the same index set as \a x.
777*/
778function array[$$E] of $T: reverse(array[$$E] of $T: x) =
779 let { int: l = max(index_set(x))+min(index_set(x)) } in
780 array1d(index_set(x),[x[l-i] | i in index_set(x)]);
781
782/** @group builtins.array Return the array \a x in reverse order
783
784 The resulting array has the same index set as \a x.
785*/
786function array[$$E] of opt $T: reverse(array[$$E] of opt $T: x) =
787 let { int: l = max(index_set(x))+min(index_set(x)) } in
788 array1d(index_set(x),[x[l-i] | i in index_set(x)]);
789
790/** @group builtins.array Return the array \a x in reverse order
791
792 The resulting array has the same index set as \a x.
793*/
794function array[$$E] of var $T: reverse(array[$$E] of var $T: x) =
795 let { int: l = max(index_set(x))+min(index_set(x)) } in
796 array1d(index_set(x),[x[l-i] | i in index_set(x)]);
797
798/** @group builtins.array Return the array \a x in reverse order
799
800 The resulting array has the same index set as \a x.
801*/
802function array[$$E] of var opt $T: reverse(array[$$E] of var opt $T: x) =
803 let { int: l = max(index_set(x))+min(index_set(x)) } in
804 array1d(index_set(x),[x[l-i] | i in index_set(x)]);
805
806/** @group builtins.array Test if \a x and \a y have the same index sets */
807test index_sets_agree(array[$T] of var opt $U: x, array[$T] of var opt $W: y);
808
809/** @group builtins.array Return index set of one-dimensional array \a x */
810function set of $$E: index_set(array[$$E] of var opt $U: x);
811/** @group builtins.array Return index set of first dimension of two-dimensional array \a x */
812function set of $$E: index_set_1of2(array[$$E,int] of var opt $U: x);
813/** @group builtins.array Return index set of second dimension of two-dimensional array \a x */
814function set of $$E: index_set_2of2(array[int,$$E] of var opt $U: x);
815/** @group builtins.array Return index set of first dimension of 3-dimensional array \a x */
816function set of $$E: index_set_1of3(array[$$E,int,int] of var opt $U: x);
817/** @group builtins.array Return index set of second dimension of 3-dimensional array \a x */
818function set of $$E: index_set_2of3(array[int,$$E,int] of var opt $U: x);
819/** @group builtins.array Return index set of third dimension of 3-dimensional array \a x */
820function set of $$E: index_set_3of3(array[int,int,$$E] of var opt $U: x);
821/** @group builtins.array Return index set of first dimension of 4-dimensional array \a x */
822function set of $$E: index_set_1of4(array[$$E,int,int,int] of var opt $U: x);
823/** @group builtins.array Return index set of second dimension of 4-dimensional array \a x */
824function set of $$E: index_set_2of4(array[int,$$E,int,int] of var opt $U: x);
825/** @group builtins.array Return index set of third dimension of 4-dimensional array \a x */
826function set of $$E: index_set_3of4(array[int,int,$$E,int] of var opt $U: x);
827/** @group builtins.array Return index set of fourth dimension of 4-dimensional array \a x */
828function set of $$E: index_set_4of4(array[int,int,int,$$E] of var opt $U: x);
829/** @group builtins.array Return index set of first dimension of 5-dimensional array \a x */
830function set of $$E: index_set_1of5(array[$$E,int,int,int,int] of var opt $U: x);
831/** @group builtins.array Return index set of second dimension of 5-dimensional array \a x */
832function set of $$E: index_set_2of5(array[int,$$E,int,int,int] of var opt $U: x);
833/** @group builtins.array Return index set of third dimension of 5-dimensional array \a x */
834function set of $$E: index_set_3of5(array[int,int,$$E,int,int] of var opt $U: x);
835/** @group builtins.array Return index set of fourth dimension of 5-dimensional array \a x */
836function set of $$E: index_set_4of5(array[int,int,int,$$E,int] of var opt $U: x);
837/** @group builtins.array Return index set of fifth dimension of 5-dimensional array \a x */
838function set of $$E: index_set_5of5(array[int,int,int,int,$$E] of var opt $U: x);
839/** @group builtins.array Return index set of first dimension of 6-dimensional array \a x */
840function set of $$E: index_set_1of6(array[$$E,int,int,int,int,int] of var opt $U: x);
841/** @group builtins.array Return index set of second dimension of 6-dimensional array \a x */
842function set of $$E: index_set_2of6(array[int,$$E,int,int,int,int] of var opt $U: x);
843/** @group builtins.array Return index set of third dimension of 6-dimensional array \a x */
844function set of $$E: index_set_3of6(array[int,int,$$E,int,int,int] of var opt $U: x);
845/** @group builtins.array Return index set of fourth dimension of 6-dimensional array \a x */
846function set of $$E: index_set_4of6(array[int,int,int,$$E,int,int] of var opt $U: x);
847/** @group builtins.array Return index set of fifth dimension of 6-dimensional array \a x */
848function set of $$E: index_set_5of6(array[int,int,int,int,$$E,int] of var opt $U: x);
849/** @group builtins.array Return index set of sixth dimension of 6-dimensional array \a x */
850function set of $$E: index_set_6of6(array[int,int,int,int,int,$$E] of var opt $U: x);
851
852/** @group builtins.array Return array \a x coerced to index set 1..length(\a x).
853 Coercions are perfomed by considering the array \a x in row-major order. */
854function array[int] of $V: array1d(array[$U] of $V: x);
855/** @group builtins.array Return array \a x coerced to index set 1..length(\a x).
856 Coercions are perfomed by considering the array \a x in row-major order. */
857function array[int] of opt $V: array1d(array[$U] of opt $V: x);
858/** @group builtins.array Return array \a x coerced to index set 1..length(\a x).
859 Coercions are perfomed by considering the array \a x in row-major order. */
860function array[int] of var $V: array1d(array[$U] of var $V: x);
861/** @group builtins.array Return array \a x coerced to index set 1..length(\a x).
862 Coercions are perfomed by considering the array \a x in row-major order. */
863function array[int] of var opt $V: array1d(array[$U] of var opt $V: x);
864
865/** @group builtins.array Return array \a x coerced to one-dimensional array with index set \a S.
866 Coercions are perfomed by considering the array \a x in row-major order. */
867function array[$$E] of $V: array1d(set of $$E: S,
868 array[$U] of $V: x);
869/** @group builtins.array Return array \a x coerced to one-dimensional array with index set \a S.
870 Coercions are perfomed by considering the array \a x in row-major order. */
871function array[$$E] of opt $V: array1d(set of $$E: S,
872 array[$U] of opt $V: x);
873/** @group builtins.array Return array \a x coerced to one-dimensional array with index set \a S.
874 Coercions are perfomed by considering the array \a x in row-major order. */
875function array[$$E] of var $V: array1d(set of $$E: S,
876 array[$U] of var $V: x);
877/** @group builtins.array Return array \a x coerced to one-dimensional array with index set \a S.
878 Coercions are perfomed by considering the array \a x in row-major order. */
879function array[$$E] of var opt $V: array1d(set of $$E: S,
880 array[$U] of var opt $V: x);
881
882/** @group builtins.array Return array \a x coerced to two-dimensional array with index sets \a S1 and \a S2.
883 Coercions are perfomed by considering the array \a x in row-major order. */
884function array[$$E,$$F] of $V: array2d(set of $$E: S1, set of $$F: S2,
885 array[$U] of $V: x);
886/** @group builtins.array Return array \a x coerced to two-dimensional array with index sets \a S1 and \a S2.
887 Coercions are perfomed by considering the array \a x in row-major order. */
888function array[$$E,$$F] of opt $V: array2d(set of $$E: S1, set of $$F: S2,
889 array[$U] of opt $V: x);
890/** @group builtins.array Return array \a x coerced to two-dimensional array with index sets \a S1 and \a S2.
891 Coercions are perfomed by considering the array \a x in row-major order. */
892function array[$$E,$$F] of var $V: array2d(set of $$E: S1, set of $$F: S2,
893 array[$U] of var $V: x);
894/** @group builtins.array Return array \a x coerced to two-dimensional array with index sets \a S1 and \a S2.
895 Coercions are perfomed by considering the array \a x in row-major order. */
896function array[$$E,$$F] of var opt $V: array2d(set of $$E: S1, set of $$F: S2,
897 array[$U] of var opt $V: x);
898
899/** @group builtins.array Return array \a x coerced to three-dimensional array with
900 index sets \a S1, \a S2 and \a S3.
901 Coercions are perfomed by considering the array \a x in row-major order.
902*/
903function array[$$E,$$F,$$G] of $V: array3d(set of $$E: S1,
904 set of $$F: S2,
905 set of $$G: S3,
906 array[$U] of $V: x);
907/** @group builtins.array Return array \a x coerced to three-dimensional array with
908 index sets \a S1, \a S2 and \a S3.
909 Coercions are perfomed by considering the array \a x in row-major order.
910*/
911function array[$$E,$$F,$$G] of opt $V: array3d(set of $$E: S1,
912 set of $$F: S2,
913 set of $$G: S3,
914 array[$U] of opt $V: x);
915/** @group builtins.array Return array \a x coerced to three-dimensional array with
916 index sets \a S1, \a S2 and \a S3.
917 Coercions are perfomed by considering the array \a x in row-major order.
918*/
919function array[$$E,$$F,$$G] of var $V: array3d(set of $$E: S1,
920 set of $$F: S2,
921 set of $$G: S3,
922 array[$U] of var $V: x);
923/** @group builtins.array Return array \a x coerced to three-dimensional array with
924 index sets \a S1, \a S2 and \a S3.
925 Coercions are perfomed by considering the array \a x in row-major order.
926*/
927function array[$$E,$$F,$$G] of var opt $V: array3d(set of $$E: S1,
928 set of $$F: S2,
929 set of $$G: S3,
930 array[$U] of var opt $V: x);
931
932/** @group builtins.array Return array \a x coerced to 4-dimensional array with
933 index sets \a S1, \a S2, \a S3 and \a S4.
934 Coercions are perfomed by considering the array \a x in row-major order.
935*/
936function array[$$E,$$F,$$G,$$H] of $V: array4d(set of $$E: S1,
937 set of $$F: S2,
938 set of $$G: S3,
939 set of $$H: S4,
940 array[$U] of $V: x);
941/** @group builtins.array Return array \a x coerced to 4-dimensional array with
942 index sets \a S1, \a S2, \a S3 and \a S4.
943 Coercions are perfomed by considering the array \a x in row-major order.
944*/
945function array[$$E,$$F,$$G,$$H] of opt $V: array4d(set of $$E: S1,
946 set of $$F: S2,
947 set of $$G: S3,
948 set of $$H: S4,
949 array[$U] of opt $V: x);
950/** @group builtins.array Return array \a x coerced to 4-dimensional array with
951 index sets \a S1, \a S2, \a S3 and \a S4.
952 Coercions are perfomed by considering the array \a x in row-major order.
953*/
954function array[$$E,$$F,$$G,$$H] of var $V: array4d(set of $$E: S1,
955 set of $$F: S2,
956 set of $$G: S3,
957 set of $$H: S4,
958 array[$U] of var $V: x);
959/** @group builtins.array Return array \a x coerced to 4-dimensional array with
960 index sets \a S1, \a S2, \a S3 and \a S4.
961 Coercions are perfomed by considering the array \a x in row-major order.
962*/
963function array[$$E,$$F,$$G,$$H] of var opt $V: array4d(set of $$E: S1,
964 set of $$F: S2,
965 set of $$G: S3,
966 set of $$H: S4,
967 array[$U] of var opt $V: x);
968
969/** @group builtins.array Return array \a x coerced to 5-dimensional array with
970 index sets \a S1, \a S2, \a S3, \a S4 and \a S5.
971 Coercions are perfomed by considering the array \a x in row-major order.
972*/
973function array[$$E,$$F,$$G,$$H,$$I] of $V: array5d(set of $$E: S1,
974 set of $$F: S2,
975 set of $$G: S3,
976 set of $$H: S4,
977 set of $$I: S5,
978 array[$U] of $V: x);
979/** @group builtins.array Return array \a x coerced to 5-dimensional array with
980 index sets \a S1, \a S2, \a S3, \a S4 and \a S5.
981 Coercions are perfomed by considering the array \a x in row-major order.
982*/
983function array[$$E,$$F,$$G,$$H,$$I] of opt $V: array5d(set of $$E: S1,
984 set of $$F: S2,
985 set of $$G: S3,
986 set of $$H: S4,
987 set of $$I: S5,
988 array[$U] of opt $V: x);
989/** @group builtins.array Return array \a x coerced to 5-dimensional array with
990 index sets \a S1, \a S2, \a S3, \a S4 and \a S5.
991 Coercions are perfomed by considering the array \a x in row-major order.
992*/
993function array[$$E,$$F,$$G,$$H,$$I] of var $V: array5d(set of $$E: S1,
994 set of $$F: S2,
995 set of $$G: S3,
996 set of $$H: S4,
997 set of $$I: S5,
998 array[$U] of var $V: x);
999/** @group builtins.array Return array \a x coerced to 5-dimensional array with
1000 index sets \a S1, \a S2, \a S3, \a S4 and \a S5.
1001 Coercions are perfomed by considering the array \a x in row-major order.
1002*/
1003function array[$$E,$$F,$$G,$$H,$$I] of var opt $V: array5d(set of $$E: S1,
1004 set of $$F: S2,
1005 set of $$G: S3,
1006 set of $$H: S4,
1007 set of $$I: S5,
1008 array[$U] of var opt $V: x);
1009
1010/** @group builtins.array Return array \a x coerced to 6-dimensional array with
1011 index sets \a S1, \a S2, \a S3, \a S4, \a S5 and \a S6.
1012 Coercions are perfomed by considering the array \a x in row-major order.
1013*/
1014function array[$$E,$$F,$$G,$$H,$$I,$$J] of $V: array6d(set of $$E: S1,
1015 set of $$F: S2,
1016 set of $$G: S3,
1017 set of $$H: S4,
1018 set of $$I: S5,
1019 set of $$J: S6,
1020 array[$U] of $V: x);
1021/** @group builtins.array Return array \a x coerced to 6-dimensional array with
1022 index sets \a S1, \a S2, \a S3, \a S4, \a S5 and \a S6.
1023 Coercions are perfomed by considering the array \a x in row-major order.
1024*/
1025function array[$$E,$$F,$$G,$$H,$$I,$$J] of opt $V: array6d(set of $$E: S1,
1026 set of $$F: S2,
1027 set of $$G: S3,
1028 set of $$H: S4,
1029 set of $$I: S5,
1030 set of $$J: S6,
1031 array[$U] of opt $V: x);
1032/** @group builtins.array Return array \a x coerced to 6-dimensional array with
1033 index sets \a S1, \a S2, \a S3, \a S4, \a S5 and \a S6.
1034 Coercions are perfomed by considering the array \a x in row-major order.
1035*/
1036function array[$$E,$$F,$$G,$$H,$$I,$$J] of var $V: array6d(set of $$E: S1,
1037 set of $$F: S2,
1038 set of $$G: S3,
1039 set of $$H: S4,
1040 set of $$I: S5,
1041 set of $$J: S6,
1042 array[$U] of var $V: x);
1043/** @group builtins.array Return array \a x coerced to 6-dimensional array with
1044 index sets \a S1, \a S2, \a S3, \a S4, \a S5 and \a S6.
1045 Coercions are perfomed by considering the array \a x in row-major order.
1046*/
1047function array[$$E,$$F,$$G,$$H,$$I,$$J] of var opt $V: array6d(set of $$E: S1,
1048 set of $$F: S2,
1049 set of $$G: S3,
1050 set of $$H: S4,
1051 set of $$I: S5,
1052 set of $$J: S6,
1053 array[$U] of var opt $V: x);
1054
1055/** @group builtins.array Return array \a y coerced to array with same number of
1056 dimensions and same index sets as array \a x.
1057 Coercions are perfomed by considering the array \a y in row-major order.
1058*/
1059function array[$T] of $V: arrayXd(array[$T] of var opt $X: x, array[$U] of $V: y);
1060/** @group builtins.array Return array \a y coerced to array with same number of
1061 dimensions and same index sets as array \a x.
1062 Coercions are perfomed by considering the array \a y in row-major order.
1063*/
1064function array[$T] of opt $V: arrayXd(array[$T] of var opt $X: x, array[$U] of opt $V: y);
1065/** @group builtins.array Return array \a y coerced to array with same number of
1066 dimensions and same index sets as array \a x.
1067 Coercions are perfomed by considering the array \a y in row-major order.
1068*/
1069function array[$T] of var $V: arrayXd(array[$T] of var opt $X: x, array[$U] of var $V: y);
1070/** @group builtins.array Return array \a y coerced to array with same number of
1071 dimensions and same index sets as array \a x.
1072 Coercions are perfomed by considering the array \a y in row-major order.
1073*/
1074function array[$T] of var opt $V: arrayXd(array[$T] of var opt $X: x, array[$U] of var opt $V: y);
1075
1076/** @group builtins.array Return row \a r of array \a x */
1077function array[$$E] of $T: row(array[int, $$E] of $T: x, int: r) = x[r,..];
1078/** @group builtins.array Return row \a r of array \a x */
1079function array[$$E] of opt $T: row(array[int, $$E] of opt $T: x, int: r) = x[r,..];
1080/** @group builtins.array Return row \a r of array \a x */
1081function array[$$E] of var $T: row(array[int, $$E] of var $T: x, int: r) = x[r,..];
1082/** @group builtins.array Return row \a r of array \a x */
1083function array[$$E] of var opt $T: row(array[int, $$E] of var opt $T: x, int: r) = x[r,..];
1084
1085/** @group builtins.array Return column \a c of array \a x */
1086function array[$$E] of $T: col(array[$$E,int] of $T: x, int: c) = x[..,c];
1087/** @group builtins.array Return column \a c of array \a x */
1088function array[$$E] of opt $T: col(array[$$E,int] of opt $T: x, int: c) = x[..,c];
1089/** @group builtins.array Return column \a c of array \a x */
1090function array[$$E] of var $T: col(array[$$E,int] of var $T: x, int: c) = x[..,c];
1091/** @group builtins.array Return column \a c of array \a x */
1092function array[$$E] of var opt $T: col(array[$$E,int] of var opt $T: x, int: c) = x[..,c];
1093
1094/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new array with index sets \a dims */
1095function array[int] of $T: slice_Xd(array[$E] of $T: x, array[int] of set of int: s, array[int] of set of int: dims);
1096/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 1d array with index set \a dims1 */
1097function array[int] of $T: slice_1d(array[$E] of $T: x, array[int] of set of int: s, set of int: dims1);
1098/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 2d array with index sets \a dims1 and \a dims2 */
1099function array[int,int] of $T: slice_2d(array[$E] of $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2);
1100/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2 and \a dims3 */
1101function array[int,int,int] of $T: slice_3d(array[$E] of $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3);
1102/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4 */
1103function array[int,int,int] of $T: slice_4d(array[$E] of $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4);
1104/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5 */
1105function array[int,int,int] of $T: slice_5d(array[$E] of $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5);
1106/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5, \a dims6 */
1107function array[int,int,int] of $T: slice_6d(array[$E] of $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5, set of int: dims6);
1108
1109/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new array with index sets \a dims */
1110function array[int] of opt $T: slice_Xd(array[$E] of opt $T: x, array[int] of set of int: s, array[int] of set of int: dims);
1111/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 1d array with index set \a dims1 */
1112function array[int] of opt $T: slice_1d(array[$E] of opt $T: x, array[int] of set of int: s, set of int: dims1);
1113/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 2d array with index sets \a dims1 and \a dims2 */
1114function array[int,int] of opt $T: slice_2d(array[$E] of opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2);
1115/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2 and \a dims3 */
1116function array[int,int,int] of opt $T: slice_3d(array[$E] of opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3);
1117/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4 */
1118function array[int,int,int] of opt $T: slice_4d(array[$E] of opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4);
1119/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5 */
1120function array[int,int,int] of opt $T: slice_5d(array[$E] of opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5);
1121/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5, \a dims6 */
1122function array[int,int,int] of opt $T: slice_6d(array[$E] of opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5, set of int: dims6);
1123
1124/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new array with index sets \a dims */
1125function array[int] of var $T: slice_Xd(array[$E] of var $T: x, array[int] of set of int: s, array[int] of set of int: dims);
1126/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 1d array with index set \a dims1 */
1127function array[int] of var $T: slice_1d(array[$E] of var $T: x, array[int] of set of int: s, set of int: dims1);
1128/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 2d array with index sets \a dims1 and \a dims2 */
1129function array[int,int] of var $T: slice_2d(array[$E] of var $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2);
1130/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2 and \a dims3 */
1131function array[int,int,int] of var $T: slice_3d(array[$E] of var $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3);
1132/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4 */
1133function array[int,int,int] of var $T: slice_4d(array[$E] of var $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4);
1134/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5 */
1135function array[int,int,int] of var $T: slice_5d(array[$E] of var $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5);
1136/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5, \a dims6 */
1137function array[int,int,int] of var $T: slice_6d(array[$E] of var $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5, set of int: dims6);
1138
1139/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new array with index sets \a dims */
1140function array[int] of var opt $T: slice_Xd(array[$E] of var opt $T: x, array[int] of set of int: s, array[int] of set of int: dims);
1141/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 1d array with index set \a dims1 */
1142function array[int] of var opt $T: slice_1d(array[$E] of var opt $T: x, array[int] of set of int: s, set of int: dims1);
1143/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 2d array with index sets \a dims1 and \a dims2 */
1144function array[int,int] of var opt $T: slice_2d(array[$E] of var opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2);
1145/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2 and \a dims3 */
1146function array[int,int,int] of var opt $T: slice_3d(array[$E] of var opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3);
1147/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4 */
1148function array[int,int,int] of var opt $T: slice_4d(array[$E] of var opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4);
1149/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5 */
1150function array[int,int,int] of var opt $T: slice_5d(array[$E] of var opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5);
1151/** @group builtins.array Return slice of array \a x specified by sets \a s, coerced to new 3d array with index sets \a dims1, \a dims2, \a dims3, \a dims4, \a dims5, \a dims6 */
1152function array[int,int,int] of var opt $T: slice_6d(array[$E] of var opt $T: x, array[int] of set of int: s, set of int: dims1, set of int: dims2, set of int: dims3, set of int: dims4, set of int: dims5, set of int: dims6);
1153
1154
1155/** @group builtins.array Test if \a i is in the index set of \a x */
1156test has_index(int: i, array[int] of var opt $T: x) = i in index_set(x);
1157/** @group builtins.array Test if \a e is an element of array \a x */
1158test has_element($T: e, array[int] of $T: x) = exists (i in index_set(x)) (x[i]=e);
1159/** @group builtins.array Test if \a e is an element of array \a x */
1160test has_element($T: e, array[int] of opt $T: x) = exists (i in index_set(x)) (x[i]=e);
1161/** @group builtins.array Test if \a e is an element of array \a x */
1162predicate has_element($T: e, array[$$E] of var opt $T: x) = exists (i in index_set(x)) (x[i]=e);
1163
1164/***
1165 @groupdef builtins.sort Array sorting operations
1166*/
1167
1168/** @group builtins.sort Return array \a x sorted by the values in \a y in non-decreasing order
1169
1170The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then
1171\a x[\p i] will appear in the output before \a x[\p j].
1172*/
1173function array[$$E] of var opt $T: sort_by(array[$$E] of var opt $T: x, array[$$E] of int: y);
1174/** @group builtins.sort Return array \a x sorted by the values in \a y in non-decreasing order
1175
1176The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then
1177\a x[\p i] will appear in the output before \a x[\p j].
1178*/
1179function array[$$E] of var $T: sort_by(array[$$E] of var $T: x, array[$$E] of int: y);
1180/** @group builtins.sort Return array \a x sorted by the values in \a y in non-decreasing order
1181
1182The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then
1183\a x[\p i] will appear in the output before \a x[\p j].
1184*/
1185function array[$$E] of $T: sort_by(array[$$E] of $T: x, array[$$E] of int: y);
1186
1187/** @group builtins.sort Return array \a x sorted by the values in \a y in non-decreasing order
1188
1189The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then
1190\a x[\p i] will appear in the output before \a x[\p j].
1191*/
1192function array[$$E] of var opt $T: sort_by(array[$$E] of var opt $T: x, array[$$E] of float: y);
1193/** @group builtins.sort Return array \a x sorted by the values in \a y in non-decreasing order
1194
1195The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then
1196\a x[\p i] will appear in the output before \a x[\p j].
1197*/
1198function array[$$E] of var $T: sort_by(array[$$E] of var $T: x, array[$$E] of float: y);
1199/** @group builtins.sort Return array \a x sorted by the values in \a y in non-decreasing order
1200
1201The sort is stable, i.e. if \a y[\p i] = \a y[\p j] with \p i < \p j, then
1202\a x[\p i] will appear in the output before \a x[\p j].
1203*/
1204function array[$$E] of $T: sort_by(array[$$E] of $T: x, array[$$E] of float: y);
1205
1206function array[$$E] of bool: internal_sort(array[$$E] of bool: x);
1207function array[$$E] of int: internal_sort(array[$$E] of int: x);
1208/** @group builtins.sort Return values from array \a x sorted in non-decreasing order */
1209function array[$$E] of int: sort(array[$$E] of int: x) = internal_sort(x);
1210/** @group builtins.sort Return values from array \a x sorted in non-decreasing order */
1211function array[$$E] of float: sort(array[$$E] of float: x);
1212/** @group builtins.sort Return values from array \a x sorted in non-decreasing order */
1213function array[$$E] of bool: sort(array[$$E] of bool: x) = internal_sort(x);
1214
1215/** @group builtins.sort
1216Returns the permutation \a p which causes \a x to be in sorted order hence
1217\a x[\a p[\p i]] <= \a x[\a p[\p i+1]].
1218
1219The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1].
1220*/
1221function array[int] of $$E: arg_sort(array[$$E] of int:x) =
1222 sort_by([i | i in index_set(x)], x);
1223
1224/** @group builtins.sort
1225Returns the permutation \a p which causes \a x to be in sorted order hence
1226\a x[\a p[\p i]] <= \a x[\a p[\p i+1]].
1227
1228The permutation is the stable sort hence \a x[\a p[\p i]] = \a x[\a p[\p i+1]] \(\rightarrow\) \a p[\p i] < \a p[\p i+1].
1229*/
1230function array[int] of $$E: arg_sort(array[$$E] of float:x) =
1231 sort_by([i | i in index_set(x)], x);
1232
1233/***
1234 @groupdef builtins.coercion Coercions
1235
1236 These functions implement coercions, or channeling, between different types.
1237*/
1238
1239/** @group builtins.coercion Return \( \lceil{ \a x} \rceil \) */
1240function int: ceil(float: x);
1241/** @group builtins.coercion Return \( \lfloor{ \a x} \rfloor \) */
1242function int: floor(float: x);
1243/** @group builtins.coercion Return \a x rounded to nearest integer */
1244function int: round(float: x);
1245
1246/** @group builtins.coercion Return Boolean \a b coerced to an integer */
1247function int: bool2int(bool: b);
1248/** @group builtins.coercion Return Boolean \a b coerced to a float */
1249function float: bool2float(bool: b) = if b then 1.0 else 0.0 endif;
1250/** @group builtins.coercion Return array of Booleans \a x coerced to an array of floats */
1251function array[$T] of float: bool2float(array[$T] of bool: x) ::promise_total =
1252 let {
1253 array[int] of bool: xx = array1d(x)
1254 } in arrayXd(x,[bool2float(xx[i]) | i in index_set(xx)]);
1255/** @group builtins.coercion Return array of Booleans \a x coerced to an array of floats */
1256function array[$T] of var float: bool2float(array[$T] of var bool: x) ::promise_total =
1257 let {
1258 array[int] of var bool: xx = array1d(x)
1259 } in arrayXd(x,[bool2float(xx[i]) | i in index_set(xx)]);
1260/** @group builtins.coercion Return Boolean \a b coerced to an integer */
1261function var int: bool2int(var bool: b);
1262/** @group builtins.coercion Return array of Booleans \a b coerced to an array of integers */
1263function array[$$E] of var int: bool2int(array[$$E] of var bool: b);
1264/** @group builtins.coercion Return Boolean \a b coerced to a float */
1265function var float: bool2float(var bool: b) = int2float(bool2int(b));
1266/** @group builtins.coercion Return integer \a x coerced to a float */
1267function float: int2float(int: x);
1268/** @group builtins.coercion Return integer \a x coerced to a float */
1269function var float: int2float(var int: x) ::promise_total;
1270
1271function set of int: bool2int(set of bool: b) =
1272 if b={false,true} then {0,1}
1273 elseif b={false} then {0}
1274 elseif b={true} then {1}
1275 else {} endif;
1276
1277/** @group builtins.coercion Return array of Booleans \a x coerced to an array of integers */
1278function array[$T] of int: bool2int(array[$T] of bool: x) ::promise_total =
1279 let {
1280 array[int] of bool: xx = array1d(x)
1281 } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]);
1282
1283/** @group builtins.coercion Return array of sets of Booleans \a x coerced to an array of sets of integers */
1284function array[$T] of set of int: bool2int(array[$T] of set of bool: x) ::promise_total =
1285 let {
1286 array[int] of set of bool: xx = array1d(x)
1287 } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]);
1288
1289/** @group builtins.coercion Return array of Booleans \a x coerced to an array of integers */
1290function array[$T] of var int: bool2int(array[$T] of var bool: x) ::promise_total =
1291 let {
1292 array[int] of var bool: xx = array1d(x)
1293 } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]);
1294
1295/** @group builtins.coercion Return array of Booleans \a x coerced to an array of integers */
1296function array[$T] of var opt int: bool2int(array[$T] of var opt bool: x) ::promise_total =
1297 let {
1298 array[int] of var opt bool: xx = array1d(x)
1299 } in arrayXd(x,[bool2int(xx[i]) | i in index_set(xx)]);
1300
1301/** @group builtins.coercion Return array of integers \a x coerced to an array of floats */
1302function array[$T] of float: int2float(array[$T] of int: x) ::promise_total =
1303 let {
1304 array[int] of int: xx = array1d(x)
1305 } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]);
1306
1307/** @group builtins.coercion Return array of integers \a x coerced to an array of floats */
1308function array[$T] of var float: int2float(array[$T] of var int: x) ::promise_total =
1309 let {
1310 array[int] of var int: xx = array1d(x)
1311 } in arrayXd(x,[int2float(xx[i]) | i in index_set(xx)]);
1312
1313% Only supported for set of int:
1314% function array[int] of $T: set2array(set of $T);
1315/** @group builtins.coercion Return a set of integers \a x coerced to an array of integers */
1316function array[int] of $$E: set2array(set of $$E: x);
1317
1318
1319/***
1320 @groupdef builtins.string String operations
1321
1322 These functions implement operations on strings.
1323*/
1324
1325/** @group builtins.string Convert \a x into a string */
1326function string: show(var opt set of $T: x);
1327/** @group builtins.string Convert \a x into a string */
1328function string: show(var opt $T: x);
1329/** @group builtins.string Convert \a x into a string */
1330function string: show(array[$U] of var opt $T: x);
1331
1332function string: showDzn(var opt set of $T: x);
1333function string: showDzn(var opt $T: x);
1334function string: showDzn(array[$U] of var opt $T: x);
1335function string: showDznId(string: x);
1336
1337
1338/** @group builtins.string Formatted to-string conversion for integers
1339
1340Converts the integer \a x into a string right
1341justified by the number of characters given by \a w, or left
1342justified if \a w is negative.
1343*/
1344function string: show_int(int: w, var int: x);
1345/** @group builtins.string Formatted to-string conversion for floats.
1346
1347Converts the float \a x into a string right justified
1348by the number of characters given by \a w, or left justified if
1349\a w is negative. The number of digits to appear after the decimal
1350point is given by \a p. It is a run-time error for \a p to be negative.
1351*/
1352function string: show_float(int: w, int: p, var float: x);
1353
1354/** @group builtins.string Convert two-dimensional array \a x into a string */
1355function string: show2d(array[int,int] of var opt $T: x) =
1356 let { int: rows=card(index_set_1of2(x));
1357 int: cols=card(index_set_2of2(x));
1358 array[int] of string: s = [show(x[i,j]) | i in index_set_1of2(x), j in index_set_2of2(x)];
1359 int: max_length = max([string_length(s[i]) | i in index_set(s)])
1360 } in
1361 "[| "++
1362 concat([format_justify_string(max_length,s[(i-1)*cols+j])++
1363 if j<cols then ", "
1364 elseif i<rows then " |\n " else " |]\n"
1365 endif | i in 1..rows, j in 1..cols
1366 ])++if rows=0 then "|]" else "" endif;
1367
1368/** @group builtins.string Convert three-dimensional array \a x into a string */
1369function string: show3d(array[int,int,int] of var opt $T: x) =
1370 let { int: len1=card(index_set_1of3(x));
1371 int: len2=card(index_set_2of3(x));
1372 int: len3=card(index_set_3of3(x));
1373 array[int] of string: s = [show(x[i,j,k]) | i in index_set_1of3(x),
1374 j in index_set_2of3(x),
1375 k in index_set_3of3(x)];
1376 int: max_length = max([string_length(s[i]) | i in index_set(s)])
1377 } in
1378 "[| | "++
1379 concat([format_justify_string(max_length,s[(i-1)*len2*len3+(j-1)*len3+k])++
1380 if k<len3 then ", "
1381 elseif j<len2 then " |\n "
1382 elseif i<len1 then " |,\n\n | "
1383 else " | |]\n"
1384 endif | i in 1..len1, j in 1..len2, k in 1..len3
1385 ])++if len1=0 then "| |]" else "" endif;
1386
1387/** @group builtins.string Convert \a x into JSON string */
1388function string: showJSON(var opt $T: x);
1389
1390/** @group builtins.string Convert \a x into JSON string */
1391function string: showJSON(array[$U] of var opt $T: x);
1392
1393/** @group builtins.string Return length of \a s */
1394function int: string_length(string: s);
1395
1396/** @group builtins.string Return concatenation of \a s1 and \a s2 */
1397function string: '++'(string: s1, string: s2);
1398/** @group builtins.string Return concatenation of strings in array \a s */
1399function string: concat(array[$T] of string: s);
1400/** @group builtins.string Join string in array \a s using delimiter \a d */
1401function string: join(string: d, array[$T] of string: s);
1402
1403/** @group builtins.string Convert \a x into a string */
1404function string: format(var opt $T: x) = show(x);
1405/** @group builtins.string Convert \a x into a string */
1406function string: format(var opt set of $T: x) = show(x);
1407/** @group builtins.string Convert \a x into a string */
1408function string: format(array[$U] of var opt $T: x) = show(x);
1409
1410/** @group builtins.string Return array for output of all variables in JSON format */
1411function array[int] of string: outputJSON();
1412/** @group builtins.string Return array for output of all parameters in JSON format */
1413function array[int] of string: outputJSONParameters();
1414
1415/** @group builtins.string Formatted to-string conversion
1416
1417Converts the value \a x into a string right
1418justified by the number of characters given by \a w, or left
1419justified if \a w is negative.
1420
1421The maximum length of the string representation of \a x is given by
1422\a p, or the maximum number of digits after the decimal point for floating
1423point numbers. It is a run-time error for \a p to be negative.
1424*/
1425function string: format(int: w, int: p, var opt $T: x);
1426/** @group builtins.string Formatted to-string conversion
1427
1428Converts the value \a x into a string right
1429justified by the number of characters given by \a w, or left
1430justified if \a w is negative.
1431
1432The maximum length of the string representation of \a x is given by
1433\a p. It is a run-time error for \a p to be negative.
1434*/
1435function string: format(int: w, int: p, var opt set of $T: x);
1436/** @group builtins.string Formatted to-string conversion
1437
1438Converts the value \a x into a string right
1439justified by the number of characters given by \a w, or left
1440justified if \a w is negative.
1441
1442The maximum length of the string representation of \a x is given by
1443\a p. It is a run-time error for \a p to be negative.
1444*/
1445function string: format(int: w, int: p, array[$U] of var opt $T: x);
1446
1447/** @group builtins.string Formatted to-string conversion
1448
1449Converts the value \a x into a string right
1450justified by the number of characters given by \a w, or left
1451justified if \a w is negative.
1452*/
1453function string: format(int: w, var opt $T: x);
1454/** @group builtins.string Formatted to-string conversion
1455
1456Converts the value \a x into a string right
1457justified by the number of characters given by \a w, or left
1458justified if \a w is negative.
1459*/
1460function string: format(int: w, var opt set of $T: x);
1461/** @group builtins.string Formatted to-string conversion
1462
1463Converts the value \a x into a string right
1464justified by the number of characters given by \a w, or left
1465justified if \a w is negative.
1466*/
1467function string: format(int: w, array[$U] of var opt $T: x);
1468/** @group builtins.string String justification
1469
1470Returns the string \a x right
1471justified by the number of characters given by \a w, or left
1472justified if \a w is negative.
1473*/
1474function string: format_justify_string(int: w, string: x);
1475
1476/** @group builtins.string Return path of file where this function is called */
1477function string: file_path();
1478
1479/***
1480 @groupdef builtins.reflect Reflection operations
1481
1482 These functions return information about declared or inferred variable
1483 bounds and domains.
1484*/
1485
1486/** @group builtins.reflect Return lower bound of \a x */
1487function int: lb(var int: x);
1488/** @group builtins.reflect Return upper bound of \a x */
1489function int: ub(var int: x);
1490/** @group builtins.reflect Return lower bound of \a x */
1491function int: lb(var opt int: x);
1492/** @group builtins.reflect Return upper bound of \a x */
1493function int: ub(var opt int: x);
1494/** @group builtins.reflect Return lower bound of \a x */
1495function float: lb(var float: x);
1496/** @group builtins.reflect Return upper bound of \a x */
1497function float: ub(var float: x);
1498/** @group builtins.reflect Return lower bound of \a x */
1499function set of int: lb(var set of int: x);
1500/** @group builtins.reflect Return upper bound of \a x */
1501function set of int: ub(var set of int: x);
1502/** @group builtins.reflect Return array of lower bounds of the elements in array \a x */
1503function array[$U] of int: lb(array[$U] of var int: x) =
1504 arrayXd(x,[lb(xx) | xx in array1d(x)]);
1505/** @group builtins.reflect Return array of upper bounds of the elements in array \a x */
1506function array[$U] of int: ub(array[$U] of var int: x) =
1507 arrayXd(x,[ub(xx) | xx in array1d(x)]);
1508/** @group builtins.reflect Return array of lower bounds of the elements in array \a x */
1509function array[$U] of float: lb(array[$U] of var float: x) =
1510 arrayXd(x,[lb(xx) | xx in array1d(x)]);
1511/** @group builtins.reflect Return array of upper bounds of the elements in array \a x */
1512function array[$U] of float: ub(array[$U] of var float: x) =
1513 arrayXd(x,[ub(xx) | xx in array1d(x)]);
1514/** @group builtins.reflect Return array of lower bounds of the elements in array \a x */
1515function array[$U] of set of int: lb(array[$U] of var set of int: x) =
1516 arrayXd(x,[lb(xx) | xx in array1d(x)]);
1517/** @group builtins.reflect Return array of upper bounds of the elements in array \a x */
1518function array[$U] of set of int: ub(array[$U] of var set of int: x) =
1519 arrayXd(x,[ub(xx) | xx in array1d(x)]);
1520/** @group builtins.reflect Return minimum of all lower bounds of the elements in array \a x */
1521function int: lb_array(array[$U] of var opt int: x);
1522/** @group builtins.reflect Return maximum of all upper bounds of the elements in array \a x */
1523function int: ub_array(array[$U] of var opt int: x);
1524/** @group builtins.reflect Return minimum of all lower bounds of the elements in array \a x */
1525function float: lb_array(array[$U] of var float: x);
1526/** @group builtins.reflect Return maximum of all upper bounds of the elements in array \a x */
1527function float: ub_array(array[$U] of var float: x);
1528/** @group builtins.reflect Return intersection of all lower bounds of the elements in array \a x */
1529function set of int: lb_array(array[$U] of var set of int: x);
1530/** @group builtins.reflect Return union of all upper bounds of the elements in array \a x */
1531function set of int: ub_array(array[$U] of var set of int: x);
1532/** @group builtins.reflect Return domain of \a x */
1533function set of int: dom(var int: x);
1534function set of int: dom(var bool: b) =
1535 if is_fixed(b) then if fix(b) then {1} else {0} endif else {0,1} endif;
1536
1537/** @group builtins.reflect Return union of all domains of the elements in array \a x */
1538function set of int: dom_array(array[$T] of var int: x);
1539/** @group builtins.reflect Return approximation of union of all domains of the elements in array \a x */
1540function set of int: dom_bounds_array(array[$T] of var int: x);
1541/** @group builtins.reflect Return cardinality of the domain of \a x */
1542function int: dom_size(var int: x) = card(dom(x));
1543
1544/** @group builtins.reflect Test if variable \a x has declared, finite bounds */
1545function par bool: has_bounds(var int: x);
1546/** @group builtins.reflect Test if variable \a x has declared, finite bounds */
1547function par bool: has_bounds(var float: x);
1548/** @group builtins.reflect Test if variable \a x has a declared, finite upper bound */
1549function par bool: has_ub_set(var set of int: x);
1550
1551/** @group builtins.reflect Check if the value of \a x is fixed at this point
1552 in evaluation. If it is fixed, return its value, otherwise abort. */
1553function $T: fix(var opt $T: x);
1554/** @group builtins.reflect Check if the value of every element of the array \a x is fixed
1555at this point in evaluation. If all are fixed, return an array of their values, otherwise abort. */
1556function array[$U] of $T: fix(array[$U] of var opt $T: x);
1557/** @group builtins.reflect Test if \a x is fixed */
1558function bool: is_fixed(var opt $T: x);
1559/** @group builtins.reflect Test if every element of array \a x is fixed */
1560function bool: is_fixed(array[$U] of var opt $T: x);
1561
1562/***
1563 @groupdef builtins.debug Assertions and debugging functions
1564
1565 These functions help debug models and check that input data conforms to
1566 the expectations.
1567*/
1568
1569/** @group builtins.debug If \a b is true, return \a x, otherwise abort with message \a msg. */
1570function $T: assert(bool: b, string: msg, $T: x);
1571/** @group builtins.debug If \a b is true, return \a x, otherwise abort with message \a msg. */
1572function var $T: assert(bool: b, string: msg, var $T: x);
1573/** @group builtins.debug If \a b is true, return \a x, otherwise abort with message \a msg. */
1574function var opt $T: assert(bool: b, string: msg, var opt $T: x);
1575
1576/** @group builtins.debug If \a b is true, return \a x, otherwise abort with message \a msg. */
1577function array[$U] of $T: assert(bool: b, string: msg, array[$U] of $T: x);
1578/** @group builtins.debug If \a b is true, return \a x, otherwise abort with message \a msg. */
1579function array[$U] of var $T: assert(bool: b, string: msg, array[$U] of var $T: x);
1580/** @group builtins.debug If \a b is true, return \a x, otherwise abort with message \a msg. */
1581function array[$U] of var opt $T: assert(bool: b, string: msg, array[$U] of var opt $T: x);
1582
1583/** @group builtins.debug If \a b is true, return true, otherwise abort with message \a msg. */
1584function bool: assert(bool: b, string: msg);
1585/** @group builtins.debug Return \a x, and print message \a msg. */
1586function $T: trace(string: msg, $T: x);
1587/** @group builtins.debug Return \a x, and print message \a msg. */
1588function var $T: trace(string: msg, var $T: x);
1589/** @group builtins.debug Return \a x, and print message \a msg. */
1590function var opt $T: trace(string: msg, var opt $T: x);
1591/** @group builtins.debug Return true, and print message \a msg. */
1592function bool: trace(string: msg);
1593
1594/** @group builtins.debug Return \a x, and print message \a msg. */
1595function $T: trace_stdout(string: msg, $T: x);
1596/** @group builtins.debug Return \a x, and print message \a msg. */
1597function var $T: trace_stdout(string: msg, var $T: x);
1598/** @group builtins.debug Return \a x, and print message \a msg. */
1599function var opt $T: trace_stdout(string: msg, var opt $T: x);
1600/** @group builtins.debug Return true, and print message \a msg. */
1601function bool: trace_stdout(string: msg);
1602
1603/** @group builtins.debug Abort evaluation and print message \a msg. */
1604function bool: abort(string: msg);
1605
1606/***
1607 @groupdef builtins.enum Functions for enums
1608
1609*/
1610
1611/** @group builtins.enum Return next greater enum value of \a x in enum \a e */
1612function $$E: enum_next(set of $$E: e, $$E: x);
1613/** @group builtins.enum Return next greater enum value of \a x in enum \a e */
1614function var $$E: enum_next(set of $$E: e, var $$E: x) =
1615 let { constraint x < max(e) } in x+1;
1616
1617/** @group builtins.enum Return next smaller enum value of \a x in enum \a e */
1618function $$E: enum_prev(set of $$E: e, $$E: x);
1619/** @group builtins.enum Return next smaller enum value of \a x in enum \a e */
1620function var $$E: enum_prev(set of $$E: e, var $$E: x) =
1621 let { constraint x > min(e) } in x-1;
1622
1623/** @group builtins.enum Convert \a x to enum type \a X */
1624function $$E: to_enum(set of $$E: X, int: x);
1625/** @group builtins.enum Convert \a x to enum type \a X */
1626function var $$E: to_enum(set of $$E: X, var int: x) =
1627 let { constraint x in X } in x;
1628
1629/** @group builtins.enum Convert \a x to enum type \a X */
1630function array[$U] of $$E: to_enum(set of $$E: X, array[$U] of int: x) =
1631 let { array[int] of int: xx = array1d(x) } in
1632 arrayXd(x, [ to_enum(X,xx[i]) | i in index_set(xx)]);
1633
1634/** @group builtins.enum Convert \a x to enum type \a X */
1635function array[$U] of var $$E: to_enum(set of $$E: X, array[$U] of var int: x) =
1636 let { array[int] of var int: xx = array1d(x) } in
1637 arrayXd(x, [ to_enum(X,xx[i]) | i in index_set(xx)]);
1638
1639/** @group builtins.enum Convert \a x to enum type \a X */
1640function set of $$E: to_enum(set of $$E: X, set of int: x) = { to_enum(X,i) | i in x };
1641
1642%/** @group builtins.enum Convert \a x to enum type \a X */
1643function var set of $$E: to_enum(set of $$E: X, var set of int: x) =
1644 let { var set of X: y; constraint x subset X; constraint forall (i in X) (i in x <-> i in y); } in y;
1645
1646
1647
1648%-----------------------------------------------------------------------------%
1649%
1650% Internal compiler functions
1651%
1652% These functions are used internally by the compiler.
1653%
1654
1655% domain constraints
1656predicate var_dom(var int:x, set of int: s) =
1657 if has_bounds(x) /\ dom(x) subset s then true
1658 else x in s
1659 endif;
1660predicate var_dom(var set of int: x, set of int: s) =
1661 if has_ub_set(x) /\ ub(x) subset s then true
1662 else set_subset(x,s)
1663 endif;
1664predicate var_dom(var float:x, float: l, float: u) =
1665 if has_bounds(x) /\ lb(x) >= l /\ ub(x) <= u then true
1666 else x >= l /\ x <= u
1667 endif;
1668predicate var_dom(var float:x, set of float: d) =
1669 x in d;
1670test var_dom(float:x, float: l, float: u) =
1671 x >= l /\ x <= u;
1672test var_dom(float:x, set of float: d) =
1673 x in d;
1674
1675predicate var_dom(array[$T] of var set of int: x, set of int: d) =
1676 let { array[int] of var set of int: xx = array1d(x) }
1677 in forall (i in index_set(xx)) (var_dom(xx[i],d));
1678predicate var_dom(array[$T] of var int: x, set of int: d) =
1679 let { array[int] of var int: xx = array1d(x) }
1680 in forall (i in index_set(xx)) (var_dom(xx[i],d));
1681predicate var_dom(array[$T] of var float: x, float: l, float: u) =
1682 let { array[int] of var float: xx = array1d(x) }
1683 in forall (i in index_set(xx)) (var_dom(xx[i],l,u));
1684predicate var_dom(array[$T] of var float: x, set of float: d) =
1685 let { array[int] of var float: xx = array1d(x) }
1686 in forall (i in index_set(xx)) (var_dom(xx[i],d));
1687
1688test var_dom(array[$T] of set of int: x, set of int: d) =
1689 let { array[int] of set of int: xx = array1d(x) }
1690 in forall (i in index_set(xx)) (xx[i] subset d);
1691test var_dom(array[$T] of int: x, set of int: d) =
1692 let { array[int] of int: xx = array1d(x) }
1693 in forall (i in index_set(xx)) (xx[i] in d);
1694test var_dom(array[$T] of float: x, float: l, float: u) =
1695 let { array[int] of float: xx = array1d(x) }
1696 in forall (i in index_set(xx)) (var_dom(xx[i],l,u));
1697test var_dom(array[$T] of float: x, set of float: d) =
1698 let { array[int] of float: xx = array1d(x) }
1699 in forall (i in index_set(xx)) (var_dom(xx[i],d));
1700
1701function var set of int: array2set(array[int] of var int: x) ::promise_total =
1702 let {
1703 var set of int: y = array_union([
1704 let { var set of dom(x[i]): s;
1705 constraint x[i] in s /\ card(s)=1;
1706 } in s | i in index_set(x)]);
1707 } in y;
1708
1709function set of $$T: array2set(array[int] of $$T: x) =
1710 { x[i] | i in index_set(x) };
1711
1712predicate array_var_int_element(var int: x, array[int] of int: y, var int: z) =
1713 array_int_element(x,y,z);
1714predicate array_var_bool_element(var int: x, array[int] of bool: y, var bool: z) =
1715 array_bool_element(x,y,z);
1716predicate array_var_float_element(var int: x, array[int] of float: y, var float: z) =
1717 array_float_element(x,y,z);
1718predicate array_var_set_element(var int: x, array[int] of set of int: y, var set of int: z) =
1719 array_set_element(x,y,z);
1720
1721predicate bool_xor_reif(var bool: a, var bool: b, var bool: c) =
1722 bool_xor(a,b,c);
1723
1724predicate xorall_reif(array[int] of var bool: b, var bool: c) =
1725 let { var bool: nc ::is_defined_var; constraint xorall([nc]++b) ::defines_var(nc); } in c = not nc;
1726
1727function var int: lin_exp(array[int] of int, array[int] of var int, int);
1728function var float: lin_exp(array[int] of float, array[int] of var float, float);
1729
1730test mzn_in_root_context(var $T);
1731
1732test mzn_in_redundant_constraint();
1733
1734%-----------------------------------------------------------------------------%
1735%
1736% Element constraint implementations
1737%
1738% MiniZinc compiles element constraints using a series of intermediate
1739% functions that test whether the constraint is total and perform array slicing
1740% for multi-dimensional element constraints.
1741%
1742
1743%%%%%%%%%%%%%%%%%%%
1744% Element on ints
1745
1746function var int: element_t(var int: idx, array[int] of var int: x) :: promise_total =
1747 let {
1748 var dom_bounds_array(x): r ::is_defined_var;
1749 constraint idx in index_set(x);
1750 constraint array_var_int_element_nonshifted(idx,x,r) ::defines_var(r);
1751 } in r;
1752
1753function var int: element_mt(var int: idx, array[int] of var int: x) :: promise_total =
1754 let {
1755 var lb_array(x)..ub_array(x): r ::is_defined_var;
1756 var min(index_set(x))..max(index_set(x)): idx2;
1757 constraint idx in index_set(x) -> idx2=idx;
1758 constraint idx in index_set(x) \/ idx2=min(index_set(x));
1759 constraint array_var_int_element_nonshifted(idx2,x,r) ::defines_var(r);
1760 } in r;
1761
1762function var int: element(var int: idx, array[int] of var int: x) =
1763 if is_fixed(idx) then
1764 x[fix(idx)]
1765 elseif mzn_in_root_context(idx) then let {
1766 constraint idx in index_set(x)
1767 } in element_t(idx,x)
1768 elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then
1769 element_t(idx,x)
1770 else let {
1771 constraint idx in index_set(x)
1772 } in element_mt(idx,x)
1773 endif;
1774
1775function var int: element(var int: idx1, var int: idx2,
1776 array[int,int] of var int: x) =
1777 if is_fixed(idx1) /\ is_fixed(idx2) then
1778 x[fix(idx1), fix(idx2)]
1779 elseif is_fixed(idx1) then
1780 element(idx2, x[fix(idx1),..])
1781 elseif is_fixed(idx2) then
1782 element(idx1, x[.., fix(idx2)])
1783 else
1784 let {
1785 int: dim = card(index_set_2of2(x));
1786 int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1;
1787 } in if mzn_in_root_context(idx1) then
1788 let {
1789 constraint idx1 in index_set_1of2(x);
1790 constraint idx2 in index_set_2of2(x);
1791 } in element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
1792 elseif
1793 ((has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x)))
1794 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x))))
1795 then
1796 element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
1797 else
1798 let {
1799 constraint idx1 in index_set_1of2(x);
1800 constraint idx2 in index_set_2of2(x);
1801 } in element_mt( (idx1*dim+idx2-min_flat)::domain, array1d(x))
1802 endif
1803 endif;
1804
1805function var int: element(var int: idx1, var int: idx2, var int: idx3,
1806 array[int,int,int] of var int: x) =
1807 let {
1808 int: dim2 = card(index_set_2of3(x));
1809 int: dim3 = card(index_set_3of3(x));
1810
1811 int: min = min(index_set_1of3(x))*dim2*dim3+
1812 min(index_set_2of3(x))*dim3+
1813 min(index_set_3of3(x))-1;
1814 } in if mzn_in_root_context(idx1) then
1815 let {
1816 constraint idx1 in index_set_1of3(x);
1817 constraint idx2 in index_set_2of3(x);
1818 constraint idx3 in index_set_3of3(x);
1819 } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
1820 elseif (
1821 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x)))
1822 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x)))
1823 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))))
1824 then
1825 element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
1826 else let {
1827 constraint idx1 in index_set_1of3(x);
1828 constraint idx2 in index_set_2of3(x);
1829 constraint idx3 in index_set_3of3(x);
1830 } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
1831 endif;
1832
1833function var int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4,
1834 array[int,int,int,int] of var int: x) =
1835 let {
1836 int: dim2 = card(index_set_2of4(x));
1837 int: dim3 = card(index_set_3of4(x));
1838 int: dim4 = card(index_set_4of4(x));
1839
1840 int: min = min(index_set_1of4(x))*dim2*dim3*dim4+
1841 min(index_set_2of4(x))*dim3*dim4+
1842 min(index_set_3of4(x))*dim4+
1843 min(index_set_4of4(x))-1;
1844 } in if mzn_in_root_context(idx1) then
1845 let {
1846 constraint idx1 in index_set_1of4(x);
1847 constraint idx2 in index_set_2of4(x);
1848 constraint idx3 in index_set_3of4(x);
1849 constraint idx4 in index_set_4of4(x);
1850 } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
1851 elseif (
1852 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x)))
1853 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x)))
1854 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x)))
1855 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) )
1856 then
1857 element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
1858 else let {
1859 constraint idx1 in index_set_1of4(x);
1860 constraint idx2 in index_set_2of4(x);
1861 constraint idx3 in index_set_3of4(x);
1862 constraint idx4 in index_set_4of4(x);
1863 } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
1864 endif;
1865
1866function var int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5,
1867 array[int,int,int,int,int] of var int: x) =
1868 let {
1869 int: dim2 = card(index_set_2of5(x));
1870 int: dim3 = card(index_set_3of5(x));
1871 int: dim4 = card(index_set_4of5(x));
1872 int: dim5 = card(index_set_5of5(x));
1873
1874 int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+
1875 min(index_set_2of5(x))*dim3*dim4*dim5+
1876 min(index_set_3of5(x))*dim4*dim5+
1877 min(index_set_4of5(x))*dim5+
1878 min(index_set_5of5(x))-1;
1879 } in if mzn_in_root_context(idx1) then
1880 let {
1881 constraint idx1 in index_set_1of5(x);
1882 constraint idx2 in index_set_2of5(x);
1883 constraint idx3 in index_set_3of5(x);
1884 constraint idx4 in index_set_4of5(x);
1885 constraint idx5 in index_set_5of5(x);
1886 } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
1887 elseif (
1888 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x)))
1889 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x)))
1890 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x)))
1891 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x)))
1892 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) )
1893 then
1894 element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
1895 else let {
1896 constraint idx1 in index_set_1of5(x);
1897 constraint idx2 in index_set_2of5(x);
1898 constraint idx3 in index_set_3of5(x);
1899 constraint idx4 in index_set_4of5(x);
1900 constraint idx5 in index_set_5of5(x);
1901 } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
1902 endif;
1903
1904function var int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6,
1905 array[int,int,int,int,int,int] of var int: x) =
1906 let {
1907 int: dim2 = card(index_set_2of6(x));
1908 int: dim3 = card(index_set_3of6(x));
1909 int: dim4 = card(index_set_4of6(x));
1910 int: dim5 = card(index_set_5of6(x));
1911 int: dim6 = card(index_set_6of6(x));
1912
1913 int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+
1914 min(index_set_2of6(x))*dim3*dim4*dim5*dim6+
1915 min(index_set_3of6(x))*dim4*dim5*dim6+
1916 min(index_set_4of6(x))*dim5*dim6+
1917 min(index_set_5of6(x))*dim6+
1918 min(index_set_6of6(x))-1;
1919 } in if mzn_in_root_context(idx1) then
1920 let {
1921 constraint idx1 in index_set_1of6(x);
1922 constraint idx2 in index_set_2of6(x);
1923 constraint idx3 in index_set_3of6(x);
1924 constraint idx4 in index_set_4of6(x);
1925 constraint idx5 in index_set_5of6(x);
1926 constraint idx6 in index_set_6of6(x);
1927 } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
1928 elseif (
1929 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x)))
1930 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x)))
1931 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x)))
1932 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x)))
1933 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x)))
1934 /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) )
1935 then
1936 element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
1937 else let {
1938 constraint idx1 in index_set_1of6(x);
1939 constraint idx2 in index_set_2of6(x);
1940 constraint idx3 in index_set_3of6(x);
1941 constraint idx4 in index_set_4of6(x);
1942 constraint idx5 in index_set_5of6(x);
1943 constraint idx6 in index_set_6of6(x);
1944 } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
1945 endif;
1946
1947%%%%%%%%%%%%%%%%%%%
1948% Element on floats
1949
1950function var float: element_t(var int: idx, array[int] of var float: x) :: promise_total =
1951 let {
1952 var lb_array(x)..ub_array(x): r ::is_defined_var;
1953 constraint idx in index_set(x);
1954 constraint array_var_float_element_nonshifted(idx,x,r) ::defines_var(r);
1955 } in r;
1956
1957function var float: element_mt(var int: idx, array[int] of var float: x) :: promise_total =
1958 let {
1959 var lb_array(x)..ub_array(x): r ::is_defined_var;
1960 var min(index_set(x))..max(index_set(x)): idx2;
1961 constraint idx in index_set(x) -> idx2=idx;
1962 constraint idx in index_set(x) \/ idx2=min(index_set(x));
1963 constraint array_var_float_element_nonshifted(idx2,x,r) ::defines_var(r);
1964 } in r;
1965
1966function var float: element(var int: idx, array[int] of var float: x) =
1967 if mzn_in_root_context(idx) then let {
1968 constraint idx in index_set(x)
1969 } in element_t(idx,x)
1970 elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then
1971 element_t(idx,x)
1972 else let {
1973 constraint idx in index_set(x)
1974 } in element_mt(idx,x)
1975 endif;
1976
1977function var float: element(var int: idx1, var int: idx2,
1978 array[int,int] of var float: x) =
1979 let {
1980 int: dim = card(index_set_2of2(x));
1981 int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1;
1982 } in if mzn_in_root_context(idx1) then
1983 let {
1984 constraint idx1 in index_set_1of2(x);
1985 constraint idx2 in index_set_2of2(x);
1986 } in element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
1987 elseif (
1988 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x)))
1989 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x))) )
1990 then
1991 element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
1992 else
1993 let {
1994 constraint idx1 in index_set_1of2(x);
1995 constraint idx2 in index_set_2of2(x);
1996 } in element_mt( (idx1*dim+idx2-min_flat)::domain, array1d(x))
1997 endif;
1998
1999function var float: element(var int: idx1, var int: idx2, var int: idx3,
2000 array[int,int,int] of var float: x) =
2001 let {
2002 int: dim2 = card(index_set_2of3(x));
2003 int: dim3 = card(index_set_3of3(x));
2004
2005 int: min = min(index_set_1of3(x))*dim2*dim3+
2006 min(index_set_2of3(x))*dim3+
2007 min(index_set_3of3(x))-1;
2008 } in if mzn_in_root_context(idx1) then let {
2009 constraint idx1 in index_set_1of3(x);
2010 constraint idx2 in index_set_2of3(x);
2011 constraint idx3 in index_set_3of3(x);
2012 } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2013 elseif (
2014 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x)))
2015 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x)))
2016 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))) )
2017 then
2018 element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2019 else let {
2020 constraint idx1 in index_set_1of3(x);
2021 constraint idx2 in index_set_2of3(x);
2022 constraint idx3 in index_set_3of3(x);
2023 } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2024 endif;
2025
2026function var float: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4,
2027 array[int,int,int,int] of var float: x) =
2028 let {
2029 int: dim2 = card(index_set_2of4(x));
2030 int: dim3 = card(index_set_3of4(x));
2031 int: dim4 = card(index_set_4of4(x));
2032
2033 int: min = min(index_set_1of4(x))*dim2*dim3*dim4+
2034 min(index_set_2of4(x))*dim3*dim4+
2035 min(index_set_3of4(x))*dim4+
2036 min(index_set_4of4(x))-1;
2037 } in if mzn_in_root_context(idx1) then let {
2038 constraint idx1 in index_set_1of4(x);
2039 constraint idx2 in index_set_2of4(x);
2040 constraint idx3 in index_set_3of4(x);
2041 constraint idx4 in index_set_4of4(x);
2042 } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2043 elseif (
2044 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x)))
2045 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x)))
2046 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x)))
2047 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) )
2048 then
2049 element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2050 else let {
2051 constraint idx1 in index_set_1of4(x);
2052 constraint idx2 in index_set_2of4(x);
2053 constraint idx3 in index_set_3of4(x);
2054 constraint idx4 in index_set_4of4(x);
2055 } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2056 endif;
2057
2058function var float: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5,
2059 array[int,int,int,int,int] of var float: x) =
2060 let {
2061 int: dim2 = card(index_set_2of5(x));
2062 int: dim3 = card(index_set_3of5(x));
2063 int: dim4 = card(index_set_4of5(x));
2064 int: dim5 = card(index_set_5of5(x));
2065
2066 int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+
2067 min(index_set_2of5(x))*dim3*dim4*dim5+
2068 min(index_set_3of5(x))*dim4*dim5+
2069 min(index_set_4of5(x))*dim5+
2070 min(index_set_5of5(x))-1;
2071 } in if mzn_in_root_context(idx1) then
2072 let {
2073 constraint idx1 in index_set_1of5(x);
2074 constraint idx2 in index_set_2of5(x);
2075 constraint idx3 in index_set_3of5(x);
2076 constraint idx4 in index_set_4of5(x);
2077 constraint idx5 in index_set_5of5(x);
2078 } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2079 elseif (
2080 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x)))
2081 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x)))
2082 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x)))
2083 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x)))
2084 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) )
2085 then
2086 element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2087 else let {
2088 constraint idx1 in index_set_1of5(x);
2089 constraint idx2 in index_set_2of5(x);
2090 constraint idx3 in index_set_3of5(x);
2091 constraint idx4 in index_set_4of5(x);
2092 constraint idx5 in index_set_5of5(x);
2093 } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2094 endif;
2095
2096function var float: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6,
2097 array[int,int,int,int,int,int] of var float: x) =
2098 let {
2099 int: dim2 = card(index_set_2of6(x));
2100 int: dim3 = card(index_set_3of6(x));
2101 int: dim4 = card(index_set_4of6(x));
2102 int: dim5 = card(index_set_5of6(x));
2103 int: dim6 = card(index_set_6of6(x));
2104
2105 int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+
2106 min(index_set_2of6(x))*dim3*dim4*dim5*dim6+
2107 min(index_set_3of6(x))*dim4*dim5*dim6+
2108 min(index_set_4of6(x))*dim5*dim6+
2109 min(index_set_5of6(x))*dim6+
2110 min(index_set_6of6(x))-1;
2111 } in if mzn_in_root_context(idx1) then
2112 let {
2113 constraint idx1 in index_set_1of6(x);
2114 constraint idx2 in index_set_2of6(x);
2115 constraint idx3 in index_set_3of6(x);
2116 constraint idx4 in index_set_4of6(x);
2117 constraint idx5 in index_set_5of6(x);
2118 constraint idx6 in index_set_6of6(x);
2119 } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2120 elseif (
2121 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x)))
2122 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x)))
2123 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x)))
2124 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x)))
2125 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x)))
2126 /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) )
2127 then
2128 element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2129 else let {
2130 constraint idx1 in index_set_1of6(x);
2131 constraint idx2 in index_set_2of6(x);
2132 constraint idx3 in index_set_3of6(x);
2133 constraint idx4 in index_set_4of6(x);
2134 constraint idx5 in index_set_5of6(x);
2135 constraint idx6 in index_set_6of6(x);
2136 } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2137 endif;
2138
2139%%%%%%%%%%%%%%%%%
2140% Element on sets
2141
2142function var set of int: element_t(var int: idx, array[int] of var set of int: x) :: promise_total =
2143 let {
2144 var set of min(ub_array(x))..max(ub_array(x)): r ::is_defined_var;
2145 constraint idx in index_set(x);
2146 constraint array_var_set_element_nonshifted(idx,x,r) ::defines_var(r);
2147 } in r;
2148
2149function var set of int: element_mt(var int: idx, array[int] of var set of int: x) :: promise_total =
2150 let {
2151 var set of min(ub_array(x))..max(ub_array(x)): r ::is_defined_var;
2152 var min(index_set(x))..max(index_set(x)): idx2;
2153 constraint idx in index_set(x) -> idx2=idx;
2154 constraint idx in index_set(x) \/ idx2=min(index_set(x));
2155 constraint array_var_set_element_nonshifted(idx2,x,r) ::defines_var(r);
2156 } in r;
2157
2158function var set of int: element(var int: idx, array[int] of var set of int: x) =
2159 if mzn_in_root_context(idx) then let {
2160 constraint idx in index_set(x)
2161 } in element_t(idx,x)
2162 elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then
2163 element_t(idx,x)
2164 else let {
2165 constraint idx in index_set(x)
2166 } in element_mt(idx,x)
2167 endif;
2168
2169function var set of int: element(var int: idx1, var int: idx2,
2170 array[int,int] of var set of int: x) =
2171 let {
2172 int: dim = card(index_set_2of2(x));
2173 int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1;
2174 } in if mzn_in_root_context(idx1) then
2175 let {
2176 constraint idx1 in index_set_1of2(x);
2177 constraint idx2 in index_set_2of2(x);
2178 } in element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
2179 elseif (
2180 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x)))
2181 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x))) )
2182 then
2183 element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
2184 else
2185 let {
2186 constraint idx1 in index_set_1of2(x);
2187 constraint idx2 in index_set_2of2(x);
2188 } in element_mt( (idx1*dim+idx2-min_flat)::domain, array1d(x))
2189 endif;
2190
2191function var set of int: element(var int: idx1, var int: idx2, var int: idx3,
2192 array[int,int,int] of var set of int: x) =
2193 let {
2194 int: dim2 = card(index_set_2of3(x));
2195 int: dim3 = card(index_set_3of3(x));
2196
2197 int: min = min(index_set_1of3(x))*dim2*dim3+
2198 min(index_set_2of3(x))*dim3+
2199 min(index_set_3of3(x))-1;
2200 } in if mzn_in_root_context(idx1) then
2201 let {
2202 constraint idx1 in index_set_1of3(x);
2203 constraint idx2 in index_set_2of3(x);
2204 constraint idx3 in index_set_3of3(x);
2205 } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2206 elseif (
2207 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x)))
2208 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x)))
2209 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))) )
2210 then
2211 element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2212 else let {
2213 constraint idx1 in index_set_1of3(x);
2214 constraint idx2 in index_set_2of3(x);
2215 constraint idx3 in index_set_3of3(x);
2216 } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2217 endif;
2218
2219function var set of int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4,
2220 array[int,int,int,int] of var set of int: x) =
2221 let {
2222 int: dim2 = card(index_set_2of4(x));
2223 int: dim3 = card(index_set_3of4(x));
2224 int: dim4 = card(index_set_4of4(x));
2225
2226 int: min = min(index_set_1of4(x))*dim2*dim3*dim4+
2227 min(index_set_2of4(x))*dim3*dim4+
2228 min(index_set_3of4(x))*dim4+
2229 min(index_set_4of4(x))-1;
2230 } in if mzn_in_root_context(idx1) then
2231 let {
2232 constraint idx1 in index_set_1of4(x);
2233 constraint idx2 in index_set_2of4(x);
2234 constraint idx3 in index_set_3of4(x);
2235 constraint idx4 in index_set_4of4(x);
2236 } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2237 elseif (
2238 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x)))
2239 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x)))
2240 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x)))
2241 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) )
2242 then
2243 element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2244 else let {
2245 constraint idx1 in index_set_1of4(x);
2246 constraint idx2 in index_set_2of4(x);
2247 constraint idx3 in index_set_3of4(x);
2248 constraint idx4 in index_set_4of4(x);
2249 } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2250 endif;
2251
2252function var set of int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5,
2253 array[int,int,int,int,int] of var set of int: x) =
2254 let {
2255 int: dim2 = card(index_set_2of5(x));
2256 int: dim3 = card(index_set_3of5(x));
2257 int: dim4 = card(index_set_4of5(x));
2258 int: dim5 = card(index_set_5of5(x));
2259
2260 int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+
2261 min(index_set_2of5(x))*dim3*dim4*dim5+
2262 min(index_set_3of5(x))*dim4*dim5+
2263 min(index_set_4of5(x))*dim5+
2264 min(index_set_5of5(x))-1;
2265 } in if mzn_in_root_context(idx1) then
2266 let {
2267 constraint idx1 in index_set_1of5(x);
2268 constraint idx2 in index_set_2of5(x);
2269 constraint idx3 in index_set_3of5(x);
2270 constraint idx4 in index_set_4of5(x);
2271 constraint idx5 in index_set_5of5(x);
2272 } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2273 elseif (
2274 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x)))
2275 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x)))
2276 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x)))
2277 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x)))
2278 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) )
2279 then
2280 element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2281 else let {
2282 constraint idx1 in index_set_1of5(x);
2283 constraint idx2 in index_set_2of5(x);
2284 constraint idx3 in index_set_3of5(x);
2285 constraint idx4 in index_set_4of5(x);
2286 constraint idx5 in index_set_5of5(x);
2287 } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2288 endif;
2289
2290function var set of int: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6,
2291 array[int,int,int,int,int,int] of var set of int: x) =
2292 let {
2293 int: dim2 = card(index_set_2of6(x));
2294 int: dim3 = card(index_set_3of6(x));
2295 int: dim4 = card(index_set_4of6(x));
2296 int: dim5 = card(index_set_5of6(x));
2297 int: dim6 = card(index_set_6of6(x));
2298
2299 int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+
2300 min(index_set_2of6(x))*dim3*dim4*dim5*dim6+
2301 min(index_set_3of6(x))*dim4*dim5*dim6+
2302 min(index_set_4of6(x))*dim5*dim6+
2303 min(index_set_5of6(x))*dim6+
2304 min(index_set_6of6(x))-1;
2305 } in if mzn_in_root_context(idx1) then
2306 let {
2307 constraint idx1 in index_set_1of6(x);
2308 constraint idx2 in index_set_2of6(x);
2309 constraint idx3 in index_set_3of6(x);
2310 constraint idx4 in index_set_4of6(x);
2311 constraint idx5 in index_set_5of6(x);
2312 constraint idx6 in index_set_6of6(x);
2313 } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2314 elseif (
2315 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x)))
2316 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x)))
2317 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x)))
2318 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x)))
2319 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x)))
2320 /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) )
2321 then
2322 element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2323 else let {
2324 constraint idx1 in index_set_1of6(x);
2325 constraint idx2 in index_set_2of6(x);
2326 constraint idx3 in index_set_3of6(x);
2327 constraint idx4 in index_set_4of6(x);
2328 constraint idx5 in index_set_5of6(x);
2329 constraint idx6 in index_set_6of6(x);
2330 } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2331 endif;
2332
2333%%%%%%%%%%%%%%%%%%
2334% Element on bools
2335
2336function var bool: element_t(var int: idx, array[int] of var bool: x) :: promise_total =
2337 let {
2338 var bool: r ::is_defined_var;
2339 constraint idx in index_set(x);
2340 constraint array_var_bool_element_nonshifted(idx,x,r) ::defines_var(r);
2341 } in r;
2342
2343function var bool: element_mt(var int: idx, array[int] of var bool: x) :: promise_total =
2344 let {
2345 var bool: r ::is_defined_var;
2346 var min(index_set(x))..max(index_set(x)): idx2;
2347 constraint idx in index_set(x) -> idx2=idx;
2348 constraint idx in index_set(x) \/ idx2=min(index_set(x));
2349 constraint array_var_bool_element_nonshifted(idx2,x,r) ::defines_var(r);
2350 } in r;
2351
2352function var bool: element(var int: idx, array[int] of var bool: x) =
2353 if mzn_in_root_context(idx) then
2354 idx in index_set(x) /\ element_t(idx,x)
2355 elseif (has_bounds(idx) /\ lb(idx) >= min(index_set(x)) /\ ub(idx) <= max(index_set(x))) then
2356 element_t(idx,x)
2357 else idx in index_set(x) /\ element_mt(idx,x)
2358 endif;
2359
2360function var bool: element(var int: idx1, var int: idx2,
2361 array[int,int] of var bool: x) =
2362 let {
2363 int: dim = card(index_set_2of2(x));
2364 int: min_flat = min(index_set_1of2(x))*dim+min(index_set_2of2(x))-1;
2365 } in if mzn_in_root_context(idx1) then
2366 let {
2367 constraint idx1 in index_set_1of2(x);
2368 constraint idx2 in index_set_2of2(x);
2369 } in element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
2370 elseif (
2371 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of2(x)) /\ ub(idx1) <= max(index_set_1of2(x)))
2372 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of2(x)) /\ ub(idx2) <= max(index_set_2of2(x))) )
2373 then
2374 element_t( (idx1*dim+idx2-min_flat)::domain, array1d(x))
2375 else
2376 let {
2377 constraint idx1 in index_set_1of2(x);
2378 constraint idx2 in index_set_2of2(x);
2379 } in element_mt( (idx1*dim+idx2-min_flat)::domain, array1d(x))
2380 endif;
2381
2382function var bool: element(var int: idx1, var int: idx2, var int: idx3,
2383 array[int,int,int] of var bool: x) =
2384 let {
2385 int: dim2 = card(index_set_2of3(x));
2386 int: dim3 = card(index_set_3of3(x));
2387
2388 int: min = min(index_set_1of3(x))*dim2*dim3+
2389 min(index_set_2of3(x))*dim3+
2390 min(index_set_3of3(x))-1;
2391 } in if mzn_in_root_context(idx1) then
2392 let {
2393 constraint idx1 in index_set_1of3(x);
2394 constraint idx2 in index_set_2of3(x);
2395 constraint idx3 in index_set_3of3(x);
2396 } in element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2397 elseif (
2398 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of3(x)) /\ ub(idx1) <= max(index_set_1of3(x)))
2399 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of3(x)) /\ ub(idx2) <= max(index_set_2of3(x)))
2400 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of3(x)) /\ ub(idx3) <= max(index_set_3of3(x))) )
2401 then
2402 element_t( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2403 else let {
2404 constraint idx1 in index_set_1of3(x);
2405 constraint idx2 in index_set_2of3(x);
2406 constraint idx3 in index_set_3of3(x);
2407 } in element_mt( (idx1*(dim2*dim3)+idx2*dim3+idx3-min)::domain, array1d(x))
2408 endif;
2409
2410function var bool: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4,
2411 array[int,int,int,int] of var bool: x) =
2412 let {
2413 int: dim2 = card(index_set_2of4(x));
2414 int: dim3 = card(index_set_3of4(x));
2415 int: dim4 = card(index_set_4of4(x));
2416
2417 int: min = min(index_set_1of4(x))*dim2*dim3*dim4+
2418 min(index_set_2of4(x))*dim3*dim4+
2419 min(index_set_3of4(x))*dim4+
2420 min(index_set_4of4(x))-1;
2421 } in if mzn_in_root_context(idx1) then
2422 let {
2423 constraint idx1 in index_set_1of4(x);
2424 constraint idx2 in index_set_2of4(x);
2425 constraint idx3 in index_set_3of4(x);
2426 constraint idx4 in index_set_4of4(x);
2427 } in element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2428 elseif (
2429 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of4(x)) /\ ub(idx1) <= max(index_set_1of4(x)))
2430 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of4(x)) /\ ub(idx2) <= max(index_set_2of4(x)))
2431 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of4(x)) /\ ub(idx3) <= max(index_set_3of4(x)))
2432 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of4(x)) /\ ub(idx4) <= max(index_set_4of4(x))) )
2433 then
2434 element_t( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2435 else let {
2436 constraint idx1 in index_set_1of4(x);
2437 constraint idx2 in index_set_2of4(x);
2438 constraint idx3 in index_set_3of4(x);
2439 constraint idx4 in index_set_4of4(x);
2440 } in element_mt( (idx1*(dim2*dim3*dim4)+idx2*(dim3*dim4)+idx3*dim4+idx4-min)::domain, array1d(x))
2441 endif;
2442
2443function var bool: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5,
2444 array[int,int,int,int,int] of var bool: x) =
2445 let {
2446 int: dim2 = card(index_set_2of5(x));
2447 int: dim3 = card(index_set_3of5(x));
2448 int: dim4 = card(index_set_4of5(x));
2449 int: dim5 = card(index_set_5of5(x));
2450
2451 int: min = min(index_set_1of5(x))*dim2*dim3*dim4*dim5+
2452 min(index_set_2of5(x))*dim3*dim4*dim5+
2453 min(index_set_3of5(x))*dim4*dim5+
2454 min(index_set_4of5(x))*dim5+
2455 min(index_set_5of5(x))-1;
2456 } in if mzn_in_root_context(idx1) then
2457 let {
2458 constraint idx1 in index_set_1of5(x);
2459 constraint idx2 in index_set_2of5(x);
2460 constraint idx3 in index_set_3of5(x);
2461 constraint idx4 in index_set_4of5(x);
2462 constraint idx5 in index_set_5of5(x);
2463 } in element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2464 elseif (
2465 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of5(x)) /\ ub(idx1) <= max(index_set_1of5(x)))
2466 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of5(x)) /\ ub(idx2) <= max(index_set_2of5(x)))
2467 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of5(x)) /\ ub(idx3) <= max(index_set_3of5(x)))
2468 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of5(x)) /\ ub(idx4) <= max(index_set_4of5(x)))
2469 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of5(x)) /\ ub(idx5) <= max(index_set_5of5(x))) )
2470 then
2471 element_t( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2472 else let {
2473 constraint idx1 in index_set_1of5(x);
2474 constraint idx2 in index_set_2of5(x);
2475 constraint idx3 in index_set_3of5(x);
2476 constraint idx4 in index_set_4of5(x);
2477 constraint idx5 in index_set_5of5(x);
2478 } in element_mt( (idx1*(dim2*dim3*dim4*dim5)+idx2*(dim3*dim4*dim5)+idx3*(dim4*dim5)+idx4*dim5+idx5-min)::domain, array1d(x))
2479 endif;
2480
2481function var bool: element(var int: idx1, var int: idx2, var int: idx3, var int: idx4, var int: idx5, var int: idx6,
2482 array[int,int,int,int,int,int] of var bool: x) =
2483 let {
2484 int: dim2 = card(index_set_2of6(x));
2485 int: dim3 = card(index_set_3of6(x));
2486 int: dim4 = card(index_set_4of6(x));
2487 int: dim5 = card(index_set_5of6(x));
2488 int: dim6 = card(index_set_6of6(x));
2489
2490 int: min = min(index_set_1of6(x))*dim2*dim3*dim4*dim5*dim6+
2491 min(index_set_2of6(x))*dim3*dim4*dim5*dim6+
2492 min(index_set_3of6(x))*dim4*dim5*dim6+
2493 min(index_set_4of6(x))*dim5*dim6+
2494 min(index_set_5of6(x))*dim6+
2495 min(index_set_6of6(x))-1;
2496 } in if mzn_in_root_context(idx1) then
2497 let {
2498 constraint idx1 in index_set_1of6(x);
2499 constraint idx2 in index_set_2of6(x);
2500 constraint idx3 in index_set_3of6(x);
2501 constraint idx4 in index_set_4of6(x);
2502 constraint idx5 in index_set_5of6(x);
2503 constraint idx6 in index_set_6of6(x);
2504 } in element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2505 elseif (
2506 (has_bounds(idx1) /\ lb(idx1) >= min(index_set_1of6(x)) /\ ub(idx1) <= max(index_set_1of6(x)))
2507 /\ (has_bounds(idx2) /\ lb(idx2) >= min(index_set_2of6(x)) /\ ub(idx2) <= max(index_set_2of6(x)))
2508 /\ (has_bounds(idx3) /\ lb(idx3) >= min(index_set_3of6(x)) /\ ub(idx3) <= max(index_set_3of6(x)))
2509 /\ (has_bounds(idx4) /\ lb(idx4) >= min(index_set_4of6(x)) /\ ub(idx4) <= max(index_set_4of6(x)))
2510 /\ (has_bounds(idx5) /\ lb(idx5) >= min(index_set_5of6(x)) /\ ub(idx5) <= max(index_set_5of6(x)))
2511 /\ (has_bounds(idx6) /\ lb(idx6) >= min(index_set_6of6(x)) /\ ub(idx6) <= max(index_set_6of6(x))) )
2512 then
2513 element_t( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2514 else let {
2515 constraint idx1 in index_set_1of6(x);
2516 constraint idx2 in index_set_2of6(x);
2517 constraint idx3 in index_set_3of6(x);
2518 constraint idx4 in index_set_4of6(x);
2519 constraint idx5 in index_set_5of6(x);
2520 constraint idx6 in index_set_6of6(x);
2521 } in element_mt( (idx1*(dim2*dim3*dim4*dim5*dim6)+idx2*(dim3*dim4*dim5*dim6)+idx3*(dim4*dim5*dim6)+idx4*(dim5*dim6)+idx5*dim6+idx6-min)::domain, array1d(x))
2522 endif;
2523
2524%-----------------------------------------------------------------------------%
2525%
2526% Internal functions for implementing div, mod etc
2527
2528function set of int:compute_div_bounds(var int: x, var int: y);
2529
2530function var int: div_t(var int: x, var int: y) :: promise_total =
2531 let {
2532 var (compute_div_bounds(x,y)): z ::is_defined_var;
2533 constraint y != 0;
2534 constraint int_div(x,y,z) ::defines_var(z); } in z;
2535
2536function var int: div_mt(var int: x, var int: y) :: promise_total =
2537 let {
2538 var ((dom(y) diff {0}) union {1}): yy = if y=0 then 1 else y endif;
2539 } in div_t(x,yy);
2540
2541function var float: fldiv_t(var float: x, var float: y) :: promise_total =
2542 let {
2543 var float: z ::is_defined_var; % TODO: Compute division boundaries
2544 constraint y != 0.0;
2545 constraint float_div(x, y, z) ::defines_var(z); } in z;
2546
2547function var float: fldiv_mt(var float: x, var float: y) :: promise_total =
2548 let {
2549 var (lb(y)..ub(y) diff {0.0}) union {1.0}: yy = if (y = 0.0) then 1.0 else y endif;
2550 } in fldiv_t(x, yy);
2551
2552function var int: mod_t(var int: x, var int: y) :: promise_total =
2553 let { var -(max(ub(y),-lb(y)))..max(ub(y),-lb(y)): z;
2554 constraint y != 0;
2555 constraint int_mod(x,y,z); } in z;
2556
2557function var int: mod_mt(var int: x, var int: y) :: promise_total =
2558 let {
2559 var {1} union dom(y): yy = if y=0 then 1 else y endif;
2560 } in mod_t(x,yy);
2561
2562function var int: product_rec(array[int] of var int: x) =
2563 if length(x)=0 then 1
2564 elseif length(x)=1 then x[min(index_set(x))]
2565 else x[min(index_set(x))]*
2566 product_rec([x[i] | i in min(index_set(x))+1..max(index_set(x))])
2567 endif;
2568
2569function var float: product_rec(array[int] of var float: x) =
2570 if length(x)=0 then 1.0
2571 elseif length(x)=1 then x[min(index_set(x))]
2572 else x[min(index_set(x))]*
2573 product_rec([x[i] | i in min(index_set(x))+1..max(index_set(x))])
2574 endif;
2575
2576function var int: max_t(array[int] of var int: x) :: promise_total =
2577 if length(x)=0 then 0
2578 elseif length(x)=1 then x[min(index_set(x))]
2579 elseif length(x)=2 then max(x[1],x[2])
2580 else let {
2581 var lb_array(x)..ub_array(x): m ::is_defined_var;
2582 constraint array_int_maximum(m,x) ::defines_var(m);
2583 } in m
2584 endif;
2585
2586function var int: min_t(array[int] of var int: x) :: promise_total =
2587 if length(x)=0 then 0
2588 elseif length(x)=1 then x[1]
2589 elseif length(x)=2 then min(x[1],x[2])
2590 else let {
2591 var lb_array(x)..ub_array(x): m ::is_defined_var;
2592 constraint array_int_minimum(m,x) ::defines_var(m);
2593 } in m
2594 endif;
2595
2596function var float: max_t(array[int] of var float: x) :: promise_total =
2597 if length(x)=0 then 0.0
2598 elseif length(x)=1 then x[min(index_set(x))]
2599 elseif length(x)=2 then max(x[1],x[2])
2600 else let {
2601 var lb_array(x)..ub_array(x): m ::is_defined_var;
2602 constraint array_float_maximum(m,x) ::defines_var(m);
2603 } in m
2604 endif;
2605
2606function var float: min_t(array[int] of var float: x) :: promise_total =
2607 if length(x)=0 then 0.0
2608 elseif length(x)=1 then x[1]
2609 elseif length(x)=2 then min(x[1],x[2])
2610 else let {
2611 var lb_array(x)..ub_array(x): m ::is_defined_var;
2612 constraint array_float_minimum(m,x) ::defines_var(m);
2613 } in m
2614 endif;
2615
2616/***
2617 @groupdef builtins.random Random Number Generator builtins
2618
2619 These functions implement random number generators from different
2620 probability distributions.
2621*/
2622
2623/** @group builtins.random Return a sample from the normal distribution defined by \(\a mean, \a std\) */
2624function float: normal(float: mean, float: std);
2625
2626/** @group builtins.random Return a sample from the normal distribution defined by \(\a mean, \a std\) */
2627function float: normal(int: mean, float: std);
2628
2629/** @group builtins.random Return a sample from the uniform distribution defined by \(\a lowerbound, \a upperbound\) */
2630function float: uniform(float: lowerbound, float: upperbound);
2631
2632/** @group builtins.random Return a sample from the uniform distribution defined by \(\a lowerbound, \a upperbound\) */
2633function int: uniform(int: lowerbound, int: upperbound);
2634
2635/** @group builtins.random Return a sample from the poisson distribution defined by \a mean */
2636function int: poisson(float: mean);
2637
2638/** @group builtins.random Return a sample from the poisson distribution defined by an integer \a mean */
2639function int: poisson(int: mean);
2640
2641/** @group builtins.random Return a sample from the gamma distribution defined by \(\a alpha, \a beta\) */
2642function float: gamma(float: alpha, float: beta);
2643
2644/** @group builtins.random Return a sample from the gamma distribution defined by \(\a alpha, \a beta\) */
2645function float: gamma(int: alpha, float: beta);
2646
2647/** @group builtins.random Return a sample from the Weibull distribution defined by \(\a shape, \a scale\) */
2648function float: weibull(float: shape, float: scale);
2649
2650/** @group builtins.random Return a sample from the Weibull distribution defined by \(\a shape, \a scale\) */
2651function float: weibull(int: shape, float: scale);
2652
2653/** @group builtins.random Return a sample from the exponential distribution defined by \(\a lambda\) */
2654function float: exponential(int: lambda);
2655
2656/** @group builtins.random Return a sample from the exponential distribution defined by \(\a lambda\) */
2657function float: exponential(float: lambda);
2658
2659/** @group builtins.random Return a sample from the lognormal distribution defined by \(\a mean, \a std\) */
2660function float: lognormal(float: mean, float: std);
2661
2662/** @group builtins.random Return a sample from the lognormal distribution defined by \(\a mean, \a std\) */
2663function float: lognormal(int: mean, float: std);
2664
2665/** @group builtins.random Return a sample from the chi-squared distribution defined by the degree of freedom \(\a n\) */
2666function float: chisquared(int: n);
2667
2668/** @group builtins.random Return a sample from the chi-squared distribution defined by the degree of freedom \(\a n\) */
2669function float: chisquared(float: n);
2670
2671/** @group builtins.random Return a sample from the cauchy distribution defined by \(\a mean, \a scale\) */
2672function float: cauchy(float: mean, float: scale);
2673
2674/** @group builtins.random Return a sample from the cauchy distribution defined by \(\a mean, \a scale\) */
2675function float: cauchy(int: mean, float: scale);
2676
2677/** @group builtins.random Return a sample from the Fisher-Snedecor F-distribution defined by the degrees of freedom \(\a d1, \a d2\) */
2678function float: fdistribution(float: d1, float: d2);
2679
2680/** @group builtins.random Return a sample from the Fisher-Snedecor F-distribution defined by the degrees of freedom \(\a d1, \a d2\) */
2681function float: fdistribution(int: d1, int: d2);
2682
2683/** @group builtins.random Return a sample from the student's t-distribution defined by the sample size \(\a n\) */
2684function float: tdistribution(float: n);
2685
2686/** @group builtins.random Return a sample from the student's t-distribution defined by the sample size \(\a n\) */
2687function float: tdistribution(int: n);
2688
2689/** @group builtins.random Return a sample from the discrete distribution defined by the array of weights \(\a weights\) that assigns a weight to each integer starting from zero */
2690function int: discrete_distribution(array[int] of int: weights);
2691
2692/** @group builtins.random Return a boolean sample from the Bernoulli distribution defined by probability \(\a p\) */
2693function bool: bernoulli(float: p);
2694
2695/** @group builtins.random Return a sample from the binomial distribution defined by sample number \a t and probability \a p */
2696function int: binomial(int: t, float: p);
2697
2698/***
2699 @groupdef builtins.special Special constraints
2700
2701 These predicates allow users to mark constraints as e.g. symmetry breaking
2702 or redundant, so that solvers can choose to implement them differently.
2703
2704 We cannot easily use annotations for this purpose, since annotations are
2705 propagated to all constraints in a decomposition, which may be incorrect
2706 for redundant or symmetry breaking constraints in the presence of
2707 common subexpression elimination (CSE).
2708*/
2709
2710/** @group builtins.special Mark \a b as a symmetry breaking constraint */
2711predicate symmetry_breaking_constraint(var bool: b);
2712
2713/** @group builtins.special Mark \a b as a redundant constraint */
2714predicate redundant_constraint(var bool: b);
2715
2716/** @group builtins.special Mark \a b as an implied constraint (synonym for redundant_constraint) */
2717predicate implied_constraint(var bool: b) = redundant_constraint(b);
2718
2719function set of int: anon_enum(int: n) = 1..n;
2720
2721function set of int: anon_enum(array[int] of string: x);
2722
2723/***
2724 @groupdef builtins.language Language information
2725
2726 These functions return information about the MiniZinc system.
2727*/
2728
2729/** @group builtins.language Return MiniZinc version encoded as an integer (major*10000+minor*1000+patch). */
2730function int: mzn_compiler_version();
2731
2732/** @group builtins.language Return string representation of \a v given an integer major*10000+minor*1000+patch
2733*/
2734function string: mzn_version_to_string(int: v) =
2735 show(v div 10000)++"."++show((v div 1000) mod 10)++"."++show(v mod 100);
2736
2737%-----------------------------------------------------------------------------%
2738%-----------------------------------------------------------------------------%
2739
2740% Include solver-specific redefinitions for any FlatZinc built-ins.
2741%
2742include "redefinitions.mzn";
2743include "redefinitions-2.0.mzn";
2744include "redefinitions-2.0.2.mzn";
2745include "redefinitions-2.1.mzn";
2746include "redefinitions-2.1.1.mzn";
2747include "redefinitions-2.2.1.mzn";
2748
2749%-----------------------------------------------------------------------------%
2750%-----------------------------------------------------------------------------%