this repo has no description
at develop 138 kB view raw
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 &and; \a y */ 603function bool: '/\'( bool: x, bool: y); 604/** @group builtins.logic Return truth value of \a x &and; \a y */ 605function var bool: '/\'(var bool: x, var bool: y); 606/** @group builtins.logic Return truth value of \a x &or; \a y */ 607function bool: '\/'( bool: x, bool: y); 608/** @group builtins.logic Return truth value of \a x &or; \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 &minus; \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 &minus; \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%-----------------------------------------------------------------------------%