this repo has no description
at develop 11 kB view raw
1/*** 2 @groupdef builtins.logic Logical operations 3 4 Logical operations are the standard operators of Boolean logic. 5*/ 6 7/** @group builtins.logic Return truth value of the negation of \a x */ 8function bool: op_not(bool: x) = not x; 9/** @group builtins.logic Return truth value of the negation of \a x */ 10function var bool: op_not(var bool: x) ::promise_total = 11 let { 12 var bool: y; 13 constraint bool_not(x, y); 14 } in y; 15 16/** @group builtins.compare Return if array \a x is equal to array \a y */ 17function bool: op_equals(array[$T] of int: x,array[$T] of int: y) = 18 let { 19 array[int] of int: xx = array1d(x); 20 array[int] of int: yy = array1d(y); 21 } in 22 assert(index_sets_agree(x,y), "array index sets do not match", 23 forall (i in index_set(xx)) (xx[i]=yy[i]) 24 ); 25 26/** @group builtins.compare Return if array \a x is equal to array \a y */ 27function var bool: op_equals(array[$T] of var int: x, array[$T] of var int: y) = 28 let { 29 array[int] of var int: xx = array1d(x); 30 array[int] of var int: yy = array1d(y); 31 } in 32 assert(index_sets_agree(x,y), "array index sets do not match", 33 forall (i in index_set(xx)) (xx[i]=yy[i]) 34 ); 35 36/** @group builtins.compare Return if array \a x is equal to array \a y */ 37function bool: op_equals(array[$T] of bool: x, array[$T] of bool: y) = 38 let { 39 array[int] of bool: xx = array1d(x); 40 array[int] of bool: yy = array1d(y); 41 } in 42 assert(index_sets_agree(x,y), "array index sets do not match", 43 forall (i in index_set(xx)) (xx[i]=yy[i]) 44 ); 45 46/** @group builtins.compare Return if array \a x is equal to array \a y */ 47function var bool: op_equals(array[$T] of var bool: x,array[$T] of var bool: y) = 48 let { 49 array[int] of var bool: xx = array1d(x); 50 array[int] of var bool: yy = array1d(y); 51 } in 52 assert(index_sets_agree(x,y), "array index sets do not match", 53 forall (i in index_set(xx)) (xx[i]=yy[i]) 54 ); 55 56 57/*** 58 @groupdef builtins.arithmetic Arithmetic Builtins 59 60 These builtins implement arithmetic operations. 61*/ 62 63predicate int_minus(var int:x, var int:y, var int:z); 64 65/** @group builtins.arithmetic Return \a -x */ 66function int: op_minus(int: x) ::promise_total = -x; 67/** @group builtins.arithmetic Return \a x - \a y */ 68function var int: op_minus(var int: x) ::promise_total = 69 let { 70 var int: y; 71 constraint int_minus(0,x,y); 72 } in y; 73 74/** @group builtins.arithmetic Return \a x - \a y */ 75function int: op_minus(int: x, int: y) ::promise_total = x - y; 76/** @group builtins.arithmetic Return \a x - \a y */ 77function var int: op_minus(var int: x, int: y) ::promise_total = 78 if y = 0 then 79 x 80 else 81 let { 82 var int: z; 83 constraint int_minus(x,y,z); 84 } in z 85 endif; 86/** @group builtins.arithmetic Return \a x - \a y */ 87function var int: op_minus(var int: x, var int: y) ::promise_total = 88 let { 89 var int: z; 90 constraint int_minus(x, y, z); 91 } in z; 92/** @group builtins.arithmetic Return \a x + \a y */ 93function int: op_plus(int: x, int: y) = x + y; 94/** @group builtins.arithmetic Return \a x + \a y */ 95function var int: op_plus(int: x, var int: y) ::promise_total = 96 if x = 0 then 97 y 98 else 99 let { 100 var int: z; 101 constraint int_plus(x, y, z); 102 } in z 103 endif; 104/** @group builtins.arithmetic Return \a x + \a y */ 105function var int: op_plus(var int: x, int: y) = op_plus(y, x); 106/** @group builtins.arithmetic Return \a x + \a y */ 107function var int: op_plus(var int: x, var int: y) ::promise_total = 108 let { 109 var int: z; 110 constraint int_plus(x, y, z); 111 } in z; 112 113/** @group builtins.arithmetic Return \a x * \a y */ 114function int: op_times(int: x, int: y) = x * y; 115function var int: op_times(int: x, var int: y) ::promise_total = 116 if x = 1 then 117 y 118 else 119 let { 120 var int: z; 121 constraint int_times(x, y, z); 122 } in z 123 endif; 124function var int: op_times(var int: x, int: y) = op_times(y, x); 125/** @group builtins.arithmetic Return \a x * \a y */ 126function var int: op_times(var int: x, var int: y) ::promise_total = 127 let { 128 var int: z; 129 constraint int_times(x, y, z); 130 } in z; 131 132/* Negated versions of FlatZinc builtins */ 133predicate int_lin_le_neg(array[int] of int: as, array[int] of var int: bs, int: c) = 134 int_lin_le([-a | a in as], bs, -c-1); 135predicate int_lin_eq_neg(array[int] of int: as, array[int] of var int: bs, int: c) = 136 int_lin_ne(as, bs, c); 137 138predicate pre_int_lin_eq(array[int] of int: as, array[int] of var int: bs, int: c) = if length(as)=0 then c=0 else int_lin_eq(as,bs,c) endif; 139 140predicate pre_int_lin_eq_neg(array[int] of int: as, array[int] of var int: bs, int: c) = if length(as)=0 then c!=0 else int_lin_ne(as,bs,c) endif; 141 142predicate pre_int_lin_le(array[int] of int: as, array[int] of var int: bs, int: c) = if length(as)=0 then 0<=c else int_lin_le(as,bs,c) endif; 143 144predicate pre_int_lin_le_neg(array[int] of int: as, array[int] of var int: bs, int: c) = if length(as)=0 then 0>c else int_lin_le_neg(as,bs,c) endif; 145 146 147/** @group builtins.arithmetic Return result of integer division \a x / \a y */ 148function int: op_int_division(int: x, int: y) = x div y; 149/** @group builtins.arithmetic Return result of integer division \a x / \a y */ 150function var int: op_int_division(var int: x, var int: y) = 151 if mzn_in_root_context(y) \/ not (0 in dom(y)) then div_t(x,y) else 152 let { constraint y != 0 } in div_mt(x,y) endif; 153 154/** @group builtins.arithmetic Return result of integer division \a x / \a y */ 155function int: op_modulus(int: x, int: y) = x mod y; 156/** @group builtins.arithmetic Return result of integer division \a x / \a y */ 157function var int: op_modulus(var int: x, var int: y) = 158 if mzn_in_root_context(y) \/ not (0 in dom(y)) then mod_t(x,y) else 159 let { constraint y != 0 } in mod_mt(x,y) endif; 160 161/** @group builtins.arithmetic Return result of floating point division \a x / \a y */ 162function float: op_float_division(float: x, float: y) = x / y; 163/** @group builtins.arithmetic Return result of floating point division \a x / \a y */ 164function var float: op_float_division(var float: x, var float: y) = 165 if mzn_in_root_context(y) \/ lb(y) > 0.0 \/ ub(y) < 0.0 then fldiv_t(x,y) else 166 let { constraint y != 0.0 } in fldiv_mt(x,y) endif; 167 168 169function int: internal_max(array[$U] of int: x); 170function int: internal_set_max(set of int: x); 171function bool: internal_max(array[$U] of bool: x); 172/** @group builtins.arithmetic Return maximum of \a x and \a y */ 173function $T: max($T: x, $T: y) = 174 if x > y then 175 x 176 else 177 y 178 endif; 179/** @group builtins.arithmetic Return maximum of elements in set \a x */ 180function int: max(set of int: x) = internal_set_max(x); 181/** @group builtins.arithmetic Return maximum of elements in array \a x */ 182function int: max(array[$U] of int: x) = internal_max(array1d(x)); 183/** @group builtins.arithmetic Return maximum of elements in array \a x */ 184function bool: max(array[$U] of bool: x) = internal_max(array1d(x)); 185 186function int: internal_min(array[$U] of int: x); 187function int: internal_set_min(set of int: x); 188function bool: internal_min(array[$U] of bool: x); 189/** @group builtins.arithmetic Return minimum of \a x and \a y */ 190function $T: min($T: x, $T: y) = 191 if x < y then 192 x 193 else 194 y 195 endif; 196function int: min(set of int: x) = internal_set_min(x); 197function int: min(array[$U] of int: x) = internal_min(array1d(x)); 198function bool: min(array[$U] of bool: x) = internal_min(array1d(x)); 199 200predicate int_sum(array[int] of var int: xs, var int: x); 201/** @group builtins.arithmetic Return sum of elements in array \a x */ 202function var int: sum_cc(array[$T] of var int: x) ::promise_total = 203 let { 204 array[int] of var int: xs = array1d(x); 205 var int: res; 206 constraint int_sum(xs, res); 207 } in res; 208 209function int: abs(int: x) = 210 if x<0 then 211 -x 212 else 213 x 214 endif; 215 216% --------------- 217 218/*** 219 @groupdef builtins.ifthenelse Conditionals 220 221 These functions implement conditional (if-then-else-endif) constraints. 222*/ 223 224/** @group builtins.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ y=x[i] \}\) 225 226 This constraint is generated by the compiler for if-then-else expressions. 227 The last entry in the \a c array is always the constant true, corresponding 228 to the else case. 229*/ 230function var int: if_then_else(array[int] of var bool: c, array[int] of int: x) ::promise_total = 231 let { 232 var dom_array(x): y; 233 constraint fzn_if_then_else_int(c, x, y); 234 } in y; 235 236/** @group builtins.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ y=x[i] \}\) 237 238 This constraint is generated by the compiler for if-then-else expressions. 239 The last entry in the \a c array is always the constant true, corresponding 240 to the else case. 241*/ 242function var int: if_then_else(array[int] of var bool: c, array[int] of var int: x) ::promise_total = 243 let { 244 var dom_array(x): y; 245 constraint fzn_if_then_else_var_int(c, x, y); 246 } in y; 247 248/** @group builtins.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ y=x[i] \}\) 249 250 This constraint is generated by the compiler for if-then-else expressions. 251 The last entry in the \a c array is always the constant true, corresponding 252 to the else case. 253*/ 254function var bool: if_then_else(array[int] of var bool: c, array[int] of bool: x) ::promise_total = 255 let { 256 var bool: y; 257 constraint fzn_if_then_else_bool(c, x, y); 258 } in y; 259 260/** @group builtins.ifthenelse Conditional constraint \(\{\a c[i]\land\not\exists \a c[1..i-1]\ \rightarrow\ y=x[i] \}\) 261 262 This constraint is generated by the compiler for if-then-else expressions. 263 The last entry in the \a c array is always the constant true, corresponding 264 to the else case. 265*/ 266function var bool: if_then_else(array[int] of var bool: c, array[int] of var bool: x) ::promise_total = 267 let { 268 var bool: y; 269 constraint fzn_if_then_else_var_bool(c, x, y); 270 } in y; 271 272/** @group builtins.ifthenelse Conditional partiality constraint 273 274 This constraint is generated by the compiler for if-then-else expressions 275 with potentially undefined cases. 276 The last entry in the \a c array is always the constant true, corresponding 277 to the else case. 278 The \a d[i] variable represents whether case 279 \p i is defined. Constrains that if \b is defined, then the selected case must be defined, and 280 if the selected case is undefined, then \a b must be undefined. 281*/ 282function var bool: if_then_else_partiality(array[int] of var bool: c, array[int] of var bool: d) ::promise_total = 283 let { 284 var bool: b; 285 constraint fzn_if_then_else_partiality(c, d, b); 286 } in b; 287 288 289 290% Include solver-specific redefinitions for any FlatZinc built-ins. 291% 292include "fzn_if_then_else_int.mzn"; 293include "fzn_if_then_else_var_int.mzn"; 294include "fzn_if_then_else_bool.mzn"; 295include "fzn_if_then_else_var_bool.mzn"; 296include "fzn_if_then_else_partiality.mzn"; 297% Include interpreter definitions always to be included 298include "mznasm_builtins.mzn";