47 #ifdef GECODE_HAS_SET_VARS
50 #ifdef GECODE_HAS_FLOAT_VARS
55 namespace Gecode {
namespace FlatZinc {
64 std::map<std::string,poster>::iterator
i = r.find(ce.
id);
67 std::string(
"Constraint ")+ce.
id+
" not found");
69 i->second(s, ce, ann);
107 void p_distinct(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
108 IntVarArgs va = s.arg2intvarargs(ce[0]);
112 void p_distinctOffset(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
113 IntVarArgs va = s.arg2intvarargs(ce[1]);
114 AST::Array* offs = ce.args->a[0]->getArray();
115 IntArgs oa(offs->a.size());
116 for (
int i=offs->
a.size();
i--; ) {
117 oa[
i] = offs->a[
i]->getInt();
123 void p_all_equal(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
124 IntVarArgs va = s.arg2intvarargs(ce[0]);
128 void p_int_CMP(FlatZincSpace& s,
IntRelType irt,
const ConExpr& ce,
130 if (ce[0]->isIntVar()) {
131 if (ce[1]->isIntVar()) {
132 rel(s, s.arg2IntVar(ce[0]), irt, s.arg2IntVar(ce[1]),
135 rel(s, s.arg2IntVar(ce[0]), irt, ce[1]->getInt(), s.ann2icl(ann));
138 rel(s, s.arg2IntVar(ce[1]), swap(irt), ce[0]->getInt(),
142 void p_int_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
143 p_int_CMP(s,
IRT_EQ, ce, ann);
145 void p_int_ne(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
146 p_int_CMP(s,
IRT_NQ, ce, ann);
148 void p_int_ge(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
149 p_int_CMP(s,
IRT_GQ, ce, ann);
151 void p_int_gt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
152 p_int_CMP(s,
IRT_GR, ce, ann);
154 void p_int_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
155 p_int_CMP(s,
IRT_LQ, ce, ann);
157 void p_int_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
158 p_int_CMP(s,
IRT_LE, ce, ann);
160 void p_int_CMP_reif(FlatZincSpace& s,
IntRelType irt,
const ConExpr& ce,
162 if (ce[2]->isBool()) {
163 if (ce[2]->getBool()) {
164 p_int_CMP(s, irt, ce, ann);
166 p_int_CMP(s,
neg(irt), ce, ann);
170 if (ce[0]->isIntVar()) {
171 if (ce[1]->isIntVar()) {
172 rel(s, s.arg2IntVar(ce[0]), irt, s.arg2IntVar(ce[1]),
173 s.arg2BoolVar(ce[2]), s.ann2icl(ann));
175 rel(s, s.arg2IntVar(ce[0]), irt, ce[1]->getInt(),
176 s.arg2BoolVar(ce[2]), s.ann2icl(ann));
179 rel(s, s.arg2IntVar(ce[1]), swap(irt), ce[0]->getInt(),
180 s.arg2BoolVar(ce[2]), s.ann2icl(ann));
185 void p_int_eq_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
186 p_int_CMP_reif(s,
IRT_EQ, ce, ann);
188 void p_int_ne_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
189 p_int_CMP_reif(s,
IRT_NQ, ce, ann);
191 void p_int_ge_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
192 p_int_CMP_reif(s,
IRT_GQ, ce, ann);
194 void p_int_gt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
195 p_int_CMP_reif(s,
IRT_GR, ce, ann);
197 void p_int_le_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
198 p_int_CMP_reif(s,
IRT_LQ, ce, ann);
200 void p_int_lt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
201 p_int_CMP_reif(s,
IRT_LE, ce, ann);
205 void p_int_lin_CMP(FlatZincSpace& s,
IntRelType irt,
const ConExpr& ce,
207 IntArgs ia = s.arg2intargs(ce[0]);
209 if (s.isBoolArray(ce[1],singleIntVar)) {
210 if (singleIntVar != -1) {
211 if (
std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
212 IntVar siv = s.arg2IntVar(ce[1]->getArray()->
a[singleIntVar]);
213 BoolVarArgs iv = s.arg2boolvarargs(ce[1], 0, singleIntVar);
214 IntArgs ia_tmp(ia.size()-1);
216 for (
int i=0;
i<ia.
size();
i++) {
217 if (
i != singleIntVar)
218 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[
i] : -ia[
i];
220 IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
221 linear(s, ia_tmp, iv, t, siv, s.ann2icl(ann));
223 IntVarArgs iv = s.arg2intvarargs(ce[1]);
224 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
227 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
228 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
231 IntVarArgs iv = s.arg2intvarargs(ce[1]);
232 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
235 void p_int_lin_CMP_reif(FlatZincSpace& s,
IntRelType irt,
236 const ConExpr& ce, AST::Node* ann) {
237 if (ce[2]->isBool()) {
238 if (ce[2]->getBool()) {
239 p_int_lin_CMP(s, irt, ce, ann);
241 p_int_lin_CMP(s,
neg(irt), ce, ann);
245 IntArgs ia = s.arg2intargs(ce[0]);
247 if (s.isBoolArray(ce[1],singleIntVar)) {
248 if (singleIntVar != -1) {
249 if (
std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
250 IntVar siv = s.arg2IntVar(ce[1]->getArray()->
a[singleIntVar]);
251 BoolVarArgs iv = s.arg2boolvarargs(ce[1], 0, singleIntVar);
252 IntArgs ia_tmp(ia.size()-1);
254 for (
int i=0;
i<ia.
size();
i++) {
255 if (
i != singleIntVar)
256 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[
i] : -ia[
i];
258 IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
259 linear(s, ia_tmp, iv, t, siv, s.arg2BoolVar(ce[3]),
262 IntVarArgs iv = s.arg2intvarargs(ce[1]);
263 linear(s, ia, iv, irt, ce[2]->getInt(),
264 s.arg2BoolVar(ce[3]), s.ann2icl(ann));
267 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
268 linear(s, ia, iv, irt, ce[2]->getInt(),
269 s.arg2BoolVar(ce[3]), s.ann2icl(ann));
272 IntVarArgs iv = s.arg2intvarargs(ce[1]);
273 linear(s, ia, iv, irt, ce[2]->getInt(), s.arg2BoolVar(ce[3]),
277 void p_int_lin_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
278 p_int_lin_CMP(s,
IRT_EQ, ce, ann);
280 void p_int_lin_eq_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
281 p_int_lin_CMP_reif(s,
IRT_EQ, ce, ann);
283 void p_int_lin_ne(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
284 p_int_lin_CMP(s,
IRT_NQ, ce, ann);
286 void p_int_lin_ne_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
287 p_int_lin_CMP_reif(s,
IRT_NQ, ce, ann);
289 void p_int_lin_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
290 p_int_lin_CMP(s,
IRT_LQ, ce, ann);
292 void p_int_lin_le_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
293 p_int_lin_CMP_reif(s,
IRT_LQ, ce, ann);
295 void p_int_lin_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
296 p_int_lin_CMP(s,
IRT_LE, ce, ann);
298 void p_int_lin_lt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
299 p_int_lin_CMP_reif(s,
IRT_LE, ce, ann);
301 void p_int_lin_ge(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
302 p_int_lin_CMP(s,
IRT_GQ, ce, ann);
304 void p_int_lin_ge_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
305 p_int_lin_CMP_reif(s,
IRT_GQ, ce, ann);
307 void p_int_lin_gt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
308 p_int_lin_CMP(s,
IRT_GR, ce, ann);
310 void p_int_lin_gt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
311 p_int_lin_CMP_reif(s,
IRT_GR, ce, ann);
314 void p_bool_lin_CMP(FlatZincSpace& s,
IntRelType irt,
const ConExpr& ce,
316 IntArgs ia = s.arg2intargs(ce[0]);
317 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
318 if (ce[2]->isIntVar())
319 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], s.ann2icl(ann));
321 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
323 void p_bool_lin_CMP_reif(FlatZincSpace& s,
IntRelType irt,
324 const ConExpr& ce, AST::Node* ann) {
325 if (ce[2]->isBool()) {
326 if (ce[2]->getBool()) {
327 p_bool_lin_CMP(s, irt, ce, ann);
329 p_bool_lin_CMP(s,
neg(irt), ce, ann);
333 IntArgs ia = s.arg2intargs(ce[0]);
334 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
335 if (ce[2]->isIntVar())
336 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], s.arg2BoolVar(ce[3]),
339 linear(s, ia, iv, irt, ce[2]->getInt(), s.arg2BoolVar(ce[3]),
342 void p_bool_lin_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
343 p_bool_lin_CMP(s,
IRT_EQ, ce, ann);
345 void p_bool_lin_eq_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
347 p_bool_lin_CMP_reif(s,
IRT_EQ, ce, ann);
349 void p_bool_lin_ne(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
350 p_bool_lin_CMP(s,
IRT_NQ, ce, ann);
352 void p_bool_lin_ne_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
354 p_bool_lin_CMP_reif(s,
IRT_NQ, ce, ann);
356 void p_bool_lin_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
357 p_bool_lin_CMP(s,
IRT_LQ, ce, ann);
359 void p_bool_lin_le_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
361 p_bool_lin_CMP_reif(s,
IRT_LQ, ce, ann);
363 void p_bool_lin_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
365 p_bool_lin_CMP(s,
IRT_LE, ce, ann);
367 void p_bool_lin_lt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
369 p_bool_lin_CMP_reif(s,
IRT_LE, ce, ann);
371 void p_bool_lin_ge(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
372 p_bool_lin_CMP(s,
IRT_GQ, ce, ann);
374 void p_bool_lin_ge_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
376 p_bool_lin_CMP_reif(s,
IRT_GQ, ce, ann);
378 void p_bool_lin_gt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
379 p_bool_lin_CMP(s,
IRT_GR, ce, ann);
381 void p_bool_lin_gt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
383 p_bool_lin_CMP_reif(s,
IRT_GR, ce, ann);
388 void p_int_plus(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
389 if (!ce[0]->isIntVar()) {
390 rel(s, ce[0]->getInt() + s.arg2IntVar(ce[1])
391 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
392 }
else if (!ce[1]->isIntVar()) {
393 rel(s, s.arg2IntVar(ce[0]) + ce[1]->getInt()
394 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
395 }
else if (!ce[2]->isIntVar()) {
396 rel(s, s.arg2IntVar(ce[0]) + s.arg2IntVar(ce[1])
397 == ce[2]->getInt(), s.ann2icl(ann));
399 rel(s, s.arg2IntVar(ce[0]) + s.arg2IntVar(ce[1])
400 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
404 void p_int_minus(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
405 if (!ce[0]->isIntVar()) {
406 rel(s, ce[0]->getInt() - s.arg2IntVar(ce[1])
407 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
408 }
else if (!ce[1]->isIntVar()) {
409 rel(s, s.arg2IntVar(ce[0]) - ce[1]->getInt()
410 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
411 }
else if (!ce[2]->isIntVar()) {
412 rel(s, s.arg2IntVar(ce[0]) - s.arg2IntVar(ce[1])
413 == ce[2]->getInt(), s.ann2icl(ann));
415 rel(s, s.arg2IntVar(ce[0]) - s.arg2IntVar(ce[1])
416 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
420 void p_int_times(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
421 IntVar x0 = s.arg2IntVar(ce[0]);
422 IntVar x1 = s.arg2IntVar(ce[1]);
423 IntVar x2 = s.arg2IntVar(ce[2]);
424 mult(s, x0, x1, x2, s.ann2icl(ann));
426 void p_int_div(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
427 IntVar x0 = s.arg2IntVar(ce[0]);
428 IntVar x1 = s.arg2IntVar(ce[1]);
429 IntVar x2 = s.arg2IntVar(ce[2]);
430 div(s,x0,x1,x2, s.ann2icl(ann));
432 void p_int_mod(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
433 IntVar x0 = s.arg2IntVar(ce[0]);
434 IntVar x1 = s.arg2IntVar(ce[1]);
435 IntVar x2 = s.arg2IntVar(ce[2]);
436 mod(s,x0,x1,x2, s.ann2icl(ann));
439 void p_int_min(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
440 IntVar x0 = s.arg2IntVar(ce[0]);
441 IntVar x1 = s.arg2IntVar(ce[1]);
442 IntVar x2 = s.arg2IntVar(ce[2]);
443 min(s, x0, x1, x2, s.ann2icl(ann));
445 void p_int_max(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
446 IntVar x0 = s.arg2IntVar(ce[0]);
447 IntVar x1 = s.arg2IntVar(ce[1]);
448 IntVar x2 = s.arg2IntVar(ce[2]);
449 max(s, x0, x1, x2, s.ann2icl(ann));
451 void p_int_negate(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
452 IntVar x0 = s.arg2IntVar(ce[0]);
453 IntVar x1 = s.arg2IntVar(ce[1]);
454 rel(s, x0 == -x1, s.ann2icl(ann));
458 void p_bool_CMP(FlatZincSpace& s,
IntRelType irt,
const ConExpr& ce,
460 rel(s, s.arg2BoolVar(ce[0]), irt, s.arg2BoolVar(ce[1]),
463 void p_bool_CMP_reif(FlatZincSpace& s,
IntRelType irt,
const ConExpr& ce,
465 rel(s, s.arg2BoolVar(ce[0]), irt, s.arg2BoolVar(ce[1]),
466 s.arg2BoolVar(ce[2]), s.ann2icl(ann));
468 void p_bool_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
469 p_bool_CMP(s,
IRT_EQ, ce, ann);
471 void p_bool_eq_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
472 p_bool_CMP_reif(s,
IRT_EQ, ce, ann);
474 void p_bool_ne(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
475 p_bool_CMP(s,
IRT_NQ, ce, ann);
477 void p_bool_ne_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
478 p_bool_CMP_reif(s,
IRT_NQ, ce, ann);
480 void p_bool_ge(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
481 p_bool_CMP(s,
IRT_GQ, ce, ann);
483 void p_bool_ge_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
484 p_bool_CMP_reif(s,
IRT_GQ, ce, ann);
486 void p_bool_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
487 p_bool_CMP(s,
IRT_LQ, ce, ann);
489 void p_bool_le_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
490 p_bool_CMP_reif(s,
IRT_LQ, ce, ann);
492 void p_bool_gt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
493 p_bool_CMP(s,
IRT_GR, ce, ann);
495 void p_bool_gt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
496 p_bool_CMP_reif(s,
IRT_GR, ce, ann);
498 void p_bool_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
499 p_bool_CMP(s,
IRT_LE, ce, ann);
501 void p_bool_lt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
502 p_bool_CMP_reif(s,
IRT_LE, ce, ann);
505 #define BOOL_OP(op) \
506 BoolVar b0 = s.arg2BoolVar(ce[0]); \
507 BoolVar b1 = s.arg2BoolVar(ce[1]); \
508 if (ce[2]->isBool()) { \
509 rel(s, b0, op, b1, ce[2]->getBool(), s.ann2icl(ann)); \
511 rel(s, b0, op, b1, s.bv[ce[2]->getBoolVar()], s.ann2icl(ann)); \
514 #define BOOL_ARRAY_OP(op) \
515 BoolVarArgs bv = s.arg2boolvarargs(ce[0]); \
516 if (ce.size()==1) { \
517 rel(s, op, bv, 1, s.ann2icl(ann)); \
518 } else if (ce[1]->isBool()) { \
519 rel(s, op, bv, ce[1]->getBool(), s.ann2icl(ann)); \
521 rel(s, op, bv, s.bv[ce[1]->getBoolVar()], s.ann2icl(ann)); \
524 void p_bool_or(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
527 void p_bool_and(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
530 void p_array_bool_and(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
534 void p_array_bool_or(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
538 void p_array_bool_xor(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann)
542 void p_array_bool_clause(FlatZincSpace& s,
const ConExpr& ce,
544 BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
545 BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
548 void p_array_bool_clause_reif(FlatZincSpace& s,
const ConExpr& ce,
550 BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
551 BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
552 BoolVar b0 = s.arg2BoolVar(ce[2]);
555 void p_bool_xor(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
558 void p_bool_l_imp(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
559 BoolVar b0 = s.arg2BoolVar(ce[0]);
560 BoolVar
b1 = s.arg2BoolVar(ce[1]);
561 if (ce[2]->isBool()) {
562 rel(s, b1,
BOT_IMP, b0, ce[2]->getBool(), s.ann2icl(ann));
564 rel(s, b1,
BOT_IMP, b0, s.bv[ce[2]->getBoolVar()], s.ann2icl(ann));
567 void p_bool_r_imp(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
570 void p_bool_not(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
571 BoolVar x0 = s.arg2BoolVar(ce[0]);
572 BoolVar x1 = s.arg2BoolVar(ce[1]);
577 void p_array_int_element(FlatZincSpace& s,
const ConExpr& ce,
579 bool isConstant =
true;
580 AST::Array*
a = ce[1]->getArray();
581 for (
int i=a->
a.size();
i--;) {
582 if (!a->a[
i]->isInt()) {
587 IntVar selector = s.arg2IntVar(ce[0]);
588 rel(s, selector > 0);
590 IntArgs ia = s.arg2intargs(ce[1], 1);
591 element(s, ia, selector, s.arg2IntVar(ce[2]), s.ann2icl(ann));
593 IntVarArgs iv = s.arg2intvarargs(ce[1], 1);
594 element(s, iv, selector, s.arg2IntVar(ce[2]), s.ann2icl(ann));
597 void p_array_bool_element(FlatZincSpace& s,
const ConExpr& ce,
599 bool isConstant =
true;
600 AST::Array* a = ce[1]->getArray();
601 for (
int i=a->
a.size();
i--;) {
602 if (!a->a[
i]->isBool()) {
607 IntVar selector = s.arg2IntVar(ce[0]);
608 rel(s, selector > 0);
610 IntArgs ia = s.arg2boolargs(ce[1], 1);
611 element(s, ia, selector, s.arg2BoolVar(ce[2]), s.ann2icl(ann));
613 BoolVarArgs iv = s.arg2boolvarargs(ce[1], 1);
614 element(s, iv, selector, s.arg2BoolVar(ce[2]), s.ann2icl(ann));
619 void p_bool2int(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
620 BoolVar x0 = s.arg2BoolVar(ce[0]);
621 IntVar x1 = s.arg2IntVar(ce[1]);
622 if (ce[0]->isBoolVar() && ce[1]->isIntVar()) {
623 s.aliasBool2Int(ce[1]->getIntVar(), ce[0]->getBoolVar());
625 channel(s, x0, x1, s.ann2icl(ann));
628 void p_int_in(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
629 IntSet
d = s.arg2intset(ce[1]);
630 if (ce[0]->isBoolVar()) {
632 Iter::Ranges::Singleton sr(0,1);
633 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton>
i(dr,sr);
635 if (d01.size() == 0) {
638 rel(s, s.arg2BoolVar(ce[0]),
IRT_GQ, d01.min());
639 rel(s, s.arg2BoolVar(ce[0]),
IRT_LQ, d01.max());
642 dom(s, s.arg2IntVar(ce[0]),
d);
645 void p_int_in_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
646 IntSet d = s.arg2intset(ce[1]);
647 if (ce[0]->isBoolVar()) {
649 Iter::Ranges::Singleton sr(0,1);
650 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton>
i(dr,sr);
652 if (d01.size() == 0) {
653 rel(s, s.arg2BoolVar(ce[2]) == 0);
654 }
else if (d01.max() == 0) {
655 rel(s, s.arg2BoolVar(ce[2]) == !s.arg2BoolVar(ce[0]));
656 }
else if (d01.min() == 1) {
657 rel(s, s.arg2BoolVar(ce[2]) == s.arg2BoolVar(ce[0]));
659 rel(s, s.arg2BoolVar(ce[2]) == 1);
662 dom(s, s.arg2IntVar(ce[0]),
d, s.arg2BoolVar(ce[2]));
668 void p_abs(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
669 IntVar x0 = s.arg2IntVar(ce[0]);
670 IntVar x1 = s.arg2IntVar(ce[1]);
671 abs(s, x0, x1, s.ann2icl(ann));
674 void p_array_int_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
675 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
676 IntVarArgs iv1 = s.arg2intvarargs(ce[1]);
677 rel(s, iv0,
IRT_LE, iv1, s.ann2icl(ann));
680 void p_array_int_lq(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
681 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
682 IntVarArgs iv1 = s.arg2intvarargs(ce[1]);
683 rel(s, iv0,
IRT_LQ, iv1, s.ann2icl(ann));
686 void p_array_bool_lt(FlatZincSpace& s,
const ConExpr& ce,
688 BoolVarArgs bv0 = s.arg2boolvarargs(ce[0]);
689 BoolVarArgs bv1 = s.arg2boolvarargs(ce[1]);
690 rel(s, bv0,
IRT_LE, bv1, s.ann2icl(ann));
693 void p_array_bool_lq(FlatZincSpace& s,
const ConExpr& ce,
695 BoolVarArgs bv0 = s.arg2boolvarargs(ce[0]);
696 BoolVarArgs bv1 = s.arg2boolvarargs(ce[1]);
697 rel(s, bv0,
IRT_LQ, bv1, s.ann2icl(ann));
700 void p_count(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
701 IntVarArgs iv = s.arg2intvarargs(ce[0]);
702 if (!ce[1]->isIntVar()) {
703 if (!ce[2]->isIntVar()) {
704 count(s, iv, ce[1]->getInt(),
IRT_EQ, ce[2]->getInt(),
707 count(s, iv, ce[1]->getInt(),
IRT_EQ, s.arg2IntVar(ce[2]),
710 }
else if (!ce[2]->isIntVar()) {
711 count(s, iv, s.arg2IntVar(ce[1]),
IRT_EQ, ce[2]->getInt(),
714 count(s, iv, s.arg2IntVar(ce[1]),
IRT_EQ, s.arg2IntVar(ce[2]),
719 void p_count_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
720 IntVarArgs iv = s.arg2intvarargs(ce[0]);
721 IntVar
x = s.arg2IntVar(ce[1]);
722 IntVar y = s.arg2IntVar(ce[2]);
723 BoolVar
b = s.arg2BoolVar(ce[3]);
730 FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
731 IntVarArgs iv = s.arg2intvarargs(ce[1]);
732 count(s, iv, ce[2]->getInt(), irt, ce[0]->getInt(), s.ann2icl(ann));
735 void p_at_most(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
736 count_rel(
IRT_LQ, s, ce, ann);
739 void p_at_least(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
740 count_rel(
IRT_GQ, s, ce, ann);
743 void p_bin_packing_load(FlatZincSpace& s,
const ConExpr& ce,
745 int minIdx = ce[3]->getInt();
746 IntVarArgs load = s.arg2intvarargs(ce[0]);
748 IntVarArgs bin = s.arg2intvarargs(ce[1]);
749 for (
int i=bin.
size();
i--;)
750 rel(s, bin[
i] >= minIdx);
752 for (
int i=minIdx;
i--;)
754 }
else if (minIdx < 0) {
755 IntVarArgs bin2(bin.size());
756 for (
int i=bin.
size();
i--;)
757 bin2[
i] =
expr(s, bin[
i]-minIdx, s.ann2icl(ann));
761 IntArgs sizes = s.arg2intargs(ce[2]);
765 void p_global_cardinality(FlatZincSpace& s,
const ConExpr& ce,
767 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
768 IntArgs cover = s.arg2intargs(ce[1]);
769 IntVarArgs iv1 = s.arg2intvarargs(ce[2]);
772 IntSet cover_s(cover);
773 IntSetRanges cover_r(cover_s);
774 IntVarRanges* iv0_ri = re.alloc<IntVarRanges>(iv0.size());
775 for (
int i=iv0.
size();
i--;)
776 iv0_ri[
i] = IntVarRanges(iv0[
i]);
777 Iter::Ranges::NaryUnion iv0_r(re,iv0_ri,iv0.size());
778 Iter::Ranges::Diff<Iter::Ranges::NaryUnion,IntSetRanges>
779 extra_r(iv0_r,cover_r);
780 Iter::Ranges::ToValues<Iter::Ranges::Diff<
781 Iter::Ranges::NaryUnion,IntSetRanges> > extra(extra_r);
782 for (; extra(); ++extra) {
783 cover << extra.val();
784 iv1 << IntVar(s,0,iv0.size());
788 IntVarArgs allvars = iv0+iv1;
790 count(s, allvars.slice(0,1,iv0.size()),
791 allvars.slice(iv0.size(),1,iv1.size()),
792 cover, s.ann2icl(ann));
794 count(s, iv0, iv1, cover, s.ann2icl(ann));
798 void p_global_cardinality_closed(FlatZincSpace& s,
const ConExpr& ce,
800 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
801 IntArgs cover = s.arg2intargs(ce[1]);
802 IntVarArgs iv1 = s.arg2intvarargs(ce[2]);
803 count(s, iv0, iv1, cover, s.ann2icl(ann));
806 void p_global_cardinality_low_up(FlatZincSpace& s,
const ConExpr& ce,
808 IntVarArgs x = s.arg2intvarargs(ce[0]);
809 IntArgs cover = s.arg2intargs(ce[1]);
811 IntArgs lbound = s.arg2intargs(ce[2]);
812 IntArgs ubound = s.arg2intargs(ce[3]);
814 for (
int i=cover.size(); i--;)
815 y[i] = IntSet(lbound[i],ubound[i]);
817 IntSet cover_s(cover);
819 IntVarRanges* xrs = re.alloc<IntVarRanges>(x.size());
820 for (
int i=x.size(); i--;)
822 Iter::Ranges::NaryUnion
u(re, xrs, x.size());
823 Iter::Ranges::ToValues<Iter::Ranges::NaryUnion> uv(
u);
825 if (!cover_s.in(uv.val())) {
827 y << IntSet(0,x.size());
831 count(s, x, y, cover, s.ann2icl(ann));
834 void p_global_cardinality_low_up_closed(FlatZincSpace& s,
837 IntVarArgs x = s.arg2intvarargs(ce[0]);
838 IntArgs cover = s.arg2intargs(ce[1]);
840 IntArgs lbound = s.arg2intargs(ce[2]);
841 IntArgs ubound = s.arg2intargs(ce[3]);
843 for (
int i=cover.size(); i--;)
844 y[i] = IntSet(lbound[i],ubound[i]);
846 count(s, x, y, cover, s.ann2icl(ann));
849 void p_minimum(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
850 IntVarArgs iv = s.arg2intvarargs(ce[1]);
851 min(s, iv, s.arg2IntVar(ce[0]), s.ann2icl(ann));
854 void p_maximum(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
855 IntVarArgs iv = s.arg2intvarargs(ce[1]);
856 max(s, iv, s.arg2IntVar(ce[0]), s.ann2icl(ann));
859 void p_regular(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
860 IntVarArgs iv = s.arg2intvarargs(ce[0]);
861 int q = ce[1]->getInt();
862 int symbols = ce[2]->getInt();
863 IntArgs d = s.arg2intargs(ce[3]);
864 int q0 = ce[4]->getInt();
867 for (
int i=1; i<=q; i++) {
868 for (
int j=1; j<=symbols; j++) {
869 if (d[(i-1)*symbols+(j-1)] > 0)
875 DFA::Transition* t = re.alloc<DFA::Transition>(noOfTrans+1);
877 for (
int i=1; i<=q; i++) {
878 for (
int j=1; j<=symbols; j++) {
879 if (d[(i-1)*symbols+(j-1)] > 0) {
880 t[noOfTrans].i_state =
i;
881 t[noOfTrans].symbol = j;
882 t[noOfTrans].o_state = d[(i-1)*symbols+(j-1)];
887 t[noOfTrans].i_state = -1;
890 AST::SetLit* sl = ce[5]->getSet();
893 f =
static_cast<int*
>(malloc(
sizeof(
int)*(sl->max-sl->min+2)));
894 for (
int i=sl->min; i<=sl->
max; i++)
896 f[sl->max-sl->min+1] = -1;
898 f =
static_cast<int*
>(malloc(
sizeof(
int)*(sl->s.size()+1)));
899 for (
int j=sl->s.size(); j--; )
901 f[sl->s.size()] = -1;
910 p_sort(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
911 IntVarArgs x = s.arg2intvarargs(ce[0]);
912 IntVarArgs y = s.arg2intvarargs(ce[1]);
913 IntVarArgs xy(x.size()+y.size());
914 for (
int i=x.size(); i--;)
916 for (
int i=y.size(); i--;)
917 xy[i+x.size()] = y[
i];
919 for (
int i=x.size(); i--;)
921 for (
int i=y.size(); i--;)
922 y[i] = xy[i+x.size()];
923 sorted(s, x, y, s.ann2icl(ann));
927 p_inverse_offsets(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
928 IntVarArgs x = s.arg2intvarargs(ce[0]);
929 int xoff = ce[1]->getInt();
930 IntVarArgs y = s.arg2intvarargs(ce[2]);
931 int yoff = ce[3]->getInt();
932 channel(s, x, xoff, y, yoff, s.ann2icl(ann));
936 p_increasing_int(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
937 IntVarArgs x = s.arg2intvarargs(ce[0]);
942 p_increasing_bool(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
943 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
948 p_decreasing_int(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
949 IntVarArgs x = s.arg2intvarargs(ce[0]);
954 p_decreasing_bool(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
955 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
960 p_table_int(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
961 IntVarArgs x = s.arg2intvarargs(ce[0]);
962 IntArgs tuples = s.arg2intargs(ce[1]);
963 int noOfVars = x.size();
964 int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
966 for (
int i=0; i<noOfTuples; i++) {
968 for (
int j=0; j<x.size(); j++) {
969 t[j] = tuples[i*noOfVars+j];
977 p_table_bool(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
978 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
979 IntArgs tuples = s.arg2boolargs(ce[1]);
980 int noOfVars = x.size();
981 int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
983 for (
int i=0; i<noOfTuples; i++) {
985 for (
int j=0; j<x.size(); j++) {
986 t[j] = tuples[i*noOfVars+j];
994 void p_cumulatives(FlatZincSpace& s,
const ConExpr& ce,
996 IntVarArgs start = s.arg2intvarargs(ce[0]);
997 IntVarArgs duration = s.arg2intvarargs(ce[1]);
998 IntVarArgs height = s.arg2intvarargs(ce[2]);
999 int n = start.size();
1000 IntVar bound = s.arg2IntVar(ce[3]);
1002 int minHeight = INT_MAX;
int minHeight2 = INT_MAX;
1004 if (height[i].
min() < minHeight)
1005 minHeight = height[
i].min();
1006 else if (height[i].
min() < minHeight2)
1007 minHeight2 = height[
i].min();
1009 (minHeight > bound.max()/2) ||
1010 (minHeight2 > bound.max()/2 && minHeight+minHeight2>bound.max());
1012 rel(s, bound >=
max(height));
1014 if (duration.assigned()) {
1015 IntArgs durationI(n);
1017 durationI[i] = duration[i].val();
1018 unary(s,start,durationI);
1022 end[i] =
expr(s,start[i]+duration[i]);
1023 unary(s,start,duration,end);
1025 }
else if (height.assigned()) {
1028 heightI[i] = height[i].val();
1029 if (duration.assigned()) {
1030 IntArgs durationI(n);
1032 durationI[i] = duration[i].val();
1033 cumulative(s, bound, start, durationI, heightI);
1036 for (
int i = n; i--; )
1037 end[i] =
expr(s,start[i]+duration[i]);
1038 cumulative(s, bound, start, duration, end, heightI);
1040 }
else if (bound.assigned()) {
1042 IntArgs limit(1, bound.val());
1045 end[i] =
expr(s,start[i]+duration[i]);
1046 cumulatives(s, machine, start, duration, end, height, limit,
true,
1051 IntVarArgs end(start.size());
1052 for (
int i = start.size(); i--; ) {
1055 end[
i] =
expr(s, start[i] + duration[i]);
1057 for (
int time = min; time <
max; ++time) {
1058 IntVarArgs
x(start.size());
1059 for (
int i = start.size(); i--; ) {
1060 IntVar overlaps =
channel(s,
expr(s, (start[i] <= time) &&
1062 x[
i] =
expr(s, overlaps * height[i]);
1069 void p_among_seq_int(FlatZincSpace& s,
const ConExpr& ce,
1071 IntVarArgs x = s.arg2intvarargs(ce[0]);
1072 IntSet S = s.arg2intset(ce[1]);
1073 int q = ce[2]->getInt();
1074 int l = ce[3]->getInt();
1075 int u = ce[4]->getInt();
1076 sequence(s, x, S, q, l, u, s.ann2icl(ann));
1079 void p_among_seq_bool(FlatZincSpace& s,
const ConExpr& ce,
1081 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1082 bool val = ce[1]->getBool();
1083 int q = ce[2]->getInt();
1084 int l = ce[3]->getInt();
1085 int u = ce[4]->getInt();
1087 sequence(s, x, S, q, l, u, s.ann2icl(ann));
1090 void p_schedule_unary(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1091 IntVarArgs x = s.arg2intvarargs(ce[0]);
1092 IntArgs
p = s.arg2intargs(ce[1]);
1096 void p_schedule_unary_optional(FlatZincSpace& s,
const ConExpr& ce,
1098 IntVarArgs x = s.arg2intvarargs(ce[0]);
1099 IntArgs p = s.arg2intargs(ce[1]);
1100 BoolVarArgs m = s.arg2boolvarargs(ce[2]);
1104 void p_circuit(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1105 int off = ce[0]->getInt();
1106 IntVarArgs xv = s.arg2intvarargs(ce[1]);
1107 circuit(s,off,xv,s.ann2icl(ann));
1109 void p_circuit_cost_array(FlatZincSpace& s,
const ConExpr& ce,
1111 IntArgs
c = s.arg2intargs(ce[0]);
1112 IntVarArgs xv = s.arg2intvarargs(ce[1]);
1113 IntVarArgs yv = s.arg2intvarargs(ce[2]);
1114 IntVar z = s.arg2IntVar(ce[3]);
1115 circuit(s,c,xv,yv,z,s.ann2icl(ann));
1117 void p_circuit_cost(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1118 IntArgs c = s.arg2intargs(ce[0]);
1119 IntVarArgs xv = s.arg2intvarargs(ce[1]);
1120 IntVar z = s.arg2IntVar(ce[2]);
1121 circuit(s,c,xv,z,s.ann2icl(ann));
1124 void p_nooverlap(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1125 IntVarArgs x0 = s.arg2intvarargs(ce[0]);
1126 IntVarArgs w = s.arg2intvarargs(ce[1]);
1127 IntVarArgs y0 = s.arg2intvarargs(ce[2]);
1128 IntVarArgs h = s.arg2intvarargs(ce[3]);
1129 if (w.assigned() && h.assigned()) {
1130 IntArgs iw(w.size());
1131 for (
int i=w.size(); i--;)
1133 IntArgs ih(h.size());
1134 for (
int i=h.size(); i--;)
1136 nooverlap(s,x0,iw,y0,ih,s.ann2icl(ann));
1138 IntVarArgs x1(x0.size()), y1(y0.size());
1139 for (
int i=x0.size(); i--; )
1140 x1[i] =
expr(s, x0[i] + w[i]);
1141 for (
int i=y0.size(); i--; )
1142 y1[i] =
expr(s, y0[i] + h[i]);
1143 nooverlap(s,x0,w,x1,y0,h,y1,s.ann2icl(ann));
1147 void p_precede(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1148 IntVarArgs x = s.arg2intvarargs(ce[0]);
1149 int p_s = ce[1]->getInt();
1150 int p_t = ce[2]->getInt();
1151 precede(s,x,p_s,p_t,s.ann2icl(ann));
1154 void p_nvalue(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1155 IntVarArgs x = s.arg2intvarargs(ce[1]);
1156 if (ce[0]->isIntVar()) {
1157 IntVar y = s.arg2IntVar(ce[0]);
1164 void p_among(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1165 IntVarArgs x = s.arg2intvarargs(ce[1]);
1166 IntSet
v = s.arg2intset(ce[2]);
1167 if (ce[0]->isIntVar()) {
1168 IntVar n = s.arg2IntVar(ce[0]);
1171 count(s,x,v,
IRT_EQ,ce[0]->getInt(),s.ann2icl(ann));
1175 void p_member_int(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1176 IntVarArgs x = s.arg2intvarargs(ce[0]);
1177 IntVar y = s.arg2IntVar(ce[1]);
1178 member(s,x,y,s.ann2icl(ann));
1180 void p_member_int_reif(FlatZincSpace& s,
const ConExpr& ce,
1182 IntVarArgs x = s.arg2intvarargs(ce[0]);
1183 IntVar y = s.arg2IntVar(ce[1]);
1184 BoolVar b = s.arg2BoolVar(ce[2]);
1185 member(s,x,y,b,s.ann2icl(ann));
1187 void p_member_bool(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1188 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1189 BoolVar y = s.arg2BoolVar(ce[1]);
1190 member(s,x,y,s.ann2icl(ann));
1192 void p_member_bool_reif(FlatZincSpace& s,
const ConExpr& ce,
1194 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
1195 BoolVar y = s.arg2BoolVar(ce[1]);
1196 member(s,x,y,s.arg2BoolVar(ce[2]),s.ann2icl(ann));
1203 registry().
add(
"all_different_offset", &p_distinctOffset);
1218 registry().
add(
"int_lin_eq_reif", &p_int_lin_eq_reif);
1220 registry().
add(
"int_lin_ne_reif", &p_int_lin_ne_reif);
1222 registry().
add(
"int_lin_le_reif", &p_int_lin_le_reif);
1224 registry().
add(
"int_lin_lt_reif", &p_int_lin_lt_reif);
1226 registry().
add(
"int_lin_ge_reif", &p_int_lin_ge_reif);
1228 registry().
add(
"int_lin_gt_reif", &p_int_lin_gt_reif);
1253 registry().
add(
"array_bool_and", &p_array_bool_and);
1254 registry().
add(
"array_bool_or", &p_array_bool_or);
1255 registry().
add(
"array_bool_xor", &p_array_bool_xor);
1256 registry().
add(
"bool_clause", &p_array_bool_clause);
1257 registry().
add(
"bool_clause_reif", &p_array_bool_clause_reif);
1261 registry().
add(
"array_int_element", &p_array_int_element);
1262 registry().
add(
"array_var_int_element", &p_array_int_element);
1263 registry().
add(
"array_bool_element", &p_array_bool_element);
1264 registry().
add(
"array_var_bool_element", &p_array_bool_element);
1268 #ifndef GECODE_HAS_SET_VARS
1275 registry().
add(
"array_bool_lt", &p_array_bool_lt);
1276 registry().
add(
"array_bool_lq", &p_array_bool_lq);
1281 registry().
add(
"gecode_bin_packing_load", &p_bin_packing_load);
1282 registry().
add(
"global_cardinality", &p_global_cardinality);
1284 &p_global_cardinality_closed);
1286 &p_global_cardinality_low_up);
1287 registry().
add(
"global_cardinality_low_up_closed",
1288 &p_global_cardinality_low_up_closed);
1293 registry().
add(
"inverse_offsets", &p_inverse_offsets);
1294 registry().
add(
"increasing_int", &p_increasing_int);
1295 registry().
add(
"increasing_bool", &p_increasing_bool);
1296 registry().
add(
"decreasing_int", &p_decreasing_int);
1297 registry().
add(
"decreasing_bool", &p_decreasing_bool);
1301 registry().
add(
"gecode_among_seq_int", &p_among_seq_int);
1302 registry().
add(
"gecode_among_seq_bool", &p_among_seq_bool);
1311 registry().
add(
"bool_lin_eq_reif", &p_bool_lin_eq_reif);
1312 registry().
add(
"bool_lin_ne_reif", &p_bool_lin_ne_reif);
1313 registry().
add(
"bool_lin_le_reif", &p_bool_lin_le_reif);
1314 registry().
add(
"bool_lin_lt_reif", &p_bool_lin_lt_reif);
1315 registry().
add(
"bool_lin_ge_reif", &p_bool_lin_ge_reif);
1316 registry().
add(
"bool_lin_gt_reif", &p_bool_lin_gt_reif);
1318 registry().
add(
"gecode_schedule_unary", &p_schedule_unary);
1319 registry().
add(
"gecode_schedule_unary_optional", &p_schedule_unary_optional);
1322 registry().
add(
"gecode_circuit_cost_array", &p_circuit_cost_array);
1323 registry().
add(
"gecode_circuit_cost", &p_circuit_cost);
1329 registry().
add(
"gecode_member_int_reif",&p_member_int_reif);
1331 registry().
add(
"gecode_member_bool_reif",&p_member_bool_reif);
1334 IntPoster __int_poster;
1336 #ifdef GECODE_HAS_SET_VARS
1337 void p_set_OP(FlatZincSpace& s,
SetOpType op,
1338 const ConExpr& ce, AST::Node *) {
1339 rel(s, s.arg2SetVar(ce[0]), op, s.arg2SetVar(ce[1]),
1340 SRT_EQ, s.arg2SetVar(ce[2]));
1342 void p_set_union(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1345 void p_set_intersect(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1348 void p_set_diff(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1352 void p_set_symdiff(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1353 SetVar x = s.arg2SetVar(ce[0]);
1354 SetVar y = s.arg2SetVar(ce[1]);
1356 SetVarLubRanges xub(x);
1361 SetVarLubRanges yub(y);
1369 void p_array_set_OP(FlatZincSpace& s,
SetOpType op,
1370 const ConExpr& ce, AST::Node *) {
1371 SetVarArgs xs = s.arg2setvarargs(ce[0]);
1372 rel(s, op, xs, s.arg2SetVar(ce[1]));
1374 void p_array_set_union(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1377 void p_array_set_partition(FlatZincSpace& s,
const ConExpr& ce, AST::Node *ann) {
1382 void p_set_rel(FlatZincSpace& s,
SetRelType srt,
const ConExpr& ce) {
1383 rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]));
1386 void p_set_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1387 p_set_rel(s,
SRT_EQ, ce);
1389 void p_set_ne(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1390 p_set_rel(s,
SRT_NQ, ce);
1392 void p_set_subset(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1395 void p_set_superset(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1398 void p_set_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1399 p_set_rel(s,
SRT_LQ, ce);
1401 void p_set_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1402 p_set_rel(s,
SRT_LE, ce);
1404 void p_set_card(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1405 if (!ce[1]->isIntVar()) {
1406 cardinality(s, s.arg2SetVar(ce[0]), ce[1]->getInt(),
1409 cardinality(s, s.arg2SetVar(ce[0]), s.arg2IntVar(ce[1]));
1412 void p_set_in(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1413 if (!ce[1]->isSetVar()) {
1414 IntSet d = s.arg2intset(ce[1]);
1415 if (ce[0]->isBoolVar()) {
1417 Iter::Ranges::Singleton sr(0,1);
1418 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton>
i(dr,sr);
1420 if (d01.size() == 0) {
1423 rel(s, s.arg2BoolVar(ce[0]),
IRT_GQ, d01.min());
1424 rel(s, s.arg2BoolVar(ce[0]),
IRT_LQ, d01.max());
1427 dom(s, s.arg2IntVar(ce[0]),
d);
1430 if (!ce[0]->isIntVar()) {
1431 dom(s, s.arg2SetVar(ce[1]),
SRT_SUP, ce[0]->getInt());
1433 rel(s, s.arg2SetVar(ce[1]),
SRT_SUP, s.arg2IntVar(ce[0]));
1437 void p_set_rel_reif(FlatZincSpace& s,
SetRelType srt,
const ConExpr& ce) {
1438 rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]),
1439 s.arg2BoolVar(ce[2]));
1442 void p_set_eq_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1443 p_set_rel_reif(s,
SRT_EQ,ce);
1445 void p_set_le_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1446 p_set_rel_reif(s,
SRT_LQ,ce);
1448 void p_set_lt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1449 p_set_rel_reif(s,
SRT_LE,ce);
1451 void p_set_ne_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1452 p_set_rel_reif(s,
SRT_NQ,ce);
1454 void p_set_subset_reif(FlatZincSpace& s,
const ConExpr& ce,
1458 void p_set_superset_reif(FlatZincSpace& s,
const ConExpr& ce,
1462 void p_set_in_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1463 if (!ce[1]->isSetVar()) {
1464 IntSet d = s.arg2intset(ce[1]);
1465 if (ce[0]->isBoolVar()) {
1467 Iter::Ranges::Singleton sr(0,1);
1468 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton>
i(dr,sr);
1470 if (d01.size() == 0) {
1471 rel(s, s.arg2BoolVar(ce[2]) == 0);
1472 }
else if (d01.max() == 0) {
1473 rel(s, s.arg2BoolVar(ce[2]) == !s.arg2BoolVar(ce[0]));
1474 }
else if (d01.min() == 1) {
1475 rel(s, s.arg2BoolVar(ce[2]) == s.arg2BoolVar(ce[0]));
1477 rel(s, s.arg2BoolVar(ce[2]) == 1);
1480 dom(s, s.arg2IntVar(ce[0]),
d, s.arg2BoolVar(ce[2]));
1483 if (!ce[0]->isIntVar()) {
1484 dom(s, s.arg2SetVar(ce[1]),
SRT_SUP, ce[0]->getInt(),
1485 s.arg2BoolVar(ce[2]));
1487 rel(s, s.arg2SetVar(ce[1]),
SRT_SUP, s.arg2IntVar(ce[0]),
1488 s.arg2BoolVar(ce[2]));
1492 void p_set_disjoint(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1493 rel(s, s.arg2SetVar(ce[0]),
SRT_DISJ, s.arg2SetVar(ce[1]));
1496 void p_link_set_to_booleans(FlatZincSpace& s,
const ConExpr& ce,
1498 SetVar x = s.arg2SetVar(ce[0]);
1499 int idx = ce[2]->getInt();
1502 BoolVarArgs y = s.arg2boolvarargs(ce[1],idx);
1506 void p_array_set_element(FlatZincSpace& s,
const ConExpr& ce,
1508 bool isConstant =
true;
1509 AST::Array* a = ce[1]->getArray();
1510 for (
int i=a->a.size(); i--;) {
1511 if (a->a[i]->isSetVar()) {
1516 IntVar selector = s.arg2IntVar(ce[0]);
1517 rel(s, selector > 0);
1520 element(s, sv, selector, s.arg2SetVar(ce[2]));
1522 SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
1523 element(s, sv, selector, s.arg2SetVar(ce[2]));
1527 void p_array_set_element_op(FlatZincSpace& s,
const ConExpr& ce,
1529 const IntSet& universe =
1531 bool isConstant =
true;
1532 AST::Array* a = ce[1]->getArray();
1533 for (
int i=a->a.size(); i--;) {
1534 if (a->a[i]->isSetVar()) {
1539 SetVar selector = s.arg2SetVar(ce[0]);
1543 element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
1545 SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
1546 element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
1550 void p_array_set_element_union(FlatZincSpace& s,
const ConExpr& ce,
1552 p_array_set_element_op(s, ce, ann,
SOT_UNION);
1555 void p_array_set_element_intersect(FlatZincSpace& s,
const ConExpr& ce,
1557 p_array_set_element_op(s, ce, ann,
SOT_INTER);
1560 void p_array_set_element_intersect_in(FlatZincSpace& s,
1563 IntSet d = s.arg2intset(ce[3]);
1564 p_array_set_element_op(s, ce, ann,
SOT_INTER, d);
1567 void p_array_set_element_partition(FlatZincSpace& s,
const ConExpr& ce,
1569 p_array_set_element_op(s, ce, ann,
SOT_DUNION);
1572 void p_set_convex(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1573 convex(s, s.arg2SetVar(ce[0]));
1576 void p_array_set_seq(FlatZincSpace& s,
const ConExpr& ce, AST::Node *) {
1577 SetVarArgs sv = s.arg2setvarargs(ce[0]);
1581 void p_array_set_seq_union(FlatZincSpace& s,
const ConExpr& ce,
1583 SetVarArgs sv = s.arg2setvarargs(ce[0]);
1584 sequence(s, sv, s.arg2SetVar(ce[1]));
1587 void p_int_set_channel(FlatZincSpace& s,
const ConExpr& ce,
1589 int xoff=ce[1]->getInt();
1591 int yoff=ce[3]->getInt();
1593 IntVarArgs xv = s.arg2intvarargs(ce[0], xoff);
1594 SetVarArgs yv = s.arg2setvarargs(ce[2], yoff, 1, IntSet(0, xoff-1));
1595 IntSet xd(yoff,yv.size()-1);
1596 for (
int i=xoff; i<xv.size(); i++) {
1599 IntSet yd(xoff,xv.size()-1);
1600 for (
int i=yoff; i<yv.size(); i++) {
1606 void p_range(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1607 int xoff=ce[1]->getInt();
1609 IntVarArgs xv = s.arg2intvarargs(ce[0],xoff);
1613 void p_weights(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1614 IntArgs e = s.arg2intargs(ce[0]);
1615 IntArgs w = s.arg2intargs(ce[1]);
1616 SetVar x = s.arg2SetVar(ce[2]);
1617 IntVar y = s.arg2IntVar(ce[3]);
1621 void p_inverse_set(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1622 int xoff = ce[2]->getInt();
1623 int yoff = ce[3]->getInt();
1624 SetVarArgs x = s.arg2setvarargs(ce[0],xoff);
1625 SetVarArgs y = s.arg2setvarargs(ce[1],yoff);
1629 void p_precede_set(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1630 SetVarArgs x = s.arg2setvarargs(ce[0]);
1631 int p_s = ce[1]->getInt();
1632 int p_t = ce[2]->getInt();
1645 registry().
add(
"array_set_element", &p_array_set_element);
1646 registry().
add(
"array_var_set_element", &p_array_set_element);
1647 registry().
add(
"set_intersect", &p_set_intersect);
1659 registry().
add(
"set_subset_reif", &p_set_subset_reif);
1660 registry().
add(
"set_superset_reif", &p_set_superset_reif);
1664 &p_link_set_to_booleans);
1666 registry().
add(
"array_set_union", &p_array_set_union);
1667 registry().
add(
"array_set_partition", &p_array_set_partition);
1669 registry().
add(
"array_set_seq", &p_array_set_seq);
1670 registry().
add(
"array_set_seq_union", &p_array_set_seq_union);
1672 &p_array_set_element_union);
1673 registry().
add(
"gecode_array_set_element_intersect",
1674 &p_array_set_element_intersect);
1675 registry().
add(
"gecode_array_set_element_intersect_in",
1676 &p_array_set_element_intersect_in);
1677 registry().
add(
"gecode_array_set_element_partition",
1678 &p_array_set_element_partition);
1680 &p_int_set_channel);
1685 registry().
add(
"gecode_inverse_set", &p_inverse_set);
1686 registry().
add(
"gecode_precede_set", &p_precede_set);
1689 SetPoster __set_poster;
1692 #ifdef GECODE_HAS_FLOAT_VARS
1694 void p_int2float(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1695 IntVar x0 = s.arg2IntVar(ce[0]);
1696 FloatVar x1 = s.arg2FloatVar(ce[1]);
1700 void p_float_lin_cmp(FlatZincSpace& s,
FloatRelType frt,
1701 const ConExpr& ce, AST::Node*) {
1702 FloatValArgs fa = s.arg2floatargs(ce[0]);
1703 FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
1704 linear(s, fa, fv, frt, ce[2]->getFloat());
1706 void p_float_lin_cmp_reif(FlatZincSpace& s,
FloatRelType frt,
1707 const ConExpr& ce, AST::Node*) {
1708 FloatValArgs fa = s.arg2floatargs(ce[0]);
1709 FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
1710 linear(s, fa, fv, frt, ce[2]->getFloat(), s.arg2BoolVar(ce[3]));
1712 void p_float_lin_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1713 p_float_lin_cmp(s,
FRT_EQ,ce,ann);
1715 void p_float_lin_eq_reif(FlatZincSpace& s,
const ConExpr& ce,
1717 p_float_lin_cmp_reif(s,
FRT_EQ,ce,ann);
1719 void p_float_lin_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node* ann) {
1720 p_float_lin_cmp(s,
FRT_LQ,ce,ann);
1722 void p_float_lin_le_reif(FlatZincSpace& s,
const ConExpr& ce,
1724 p_float_lin_cmp_reif(s,
FRT_LQ,ce,ann);
1727 void p_float_times(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1728 FloatVar x = s.arg2FloatVar(ce[0]);
1729 FloatVar y = s.arg2FloatVar(ce[1]);
1730 FloatVar z = s.arg2FloatVar(ce[2]);
1734 void p_float_div(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1735 FloatVar x = s.arg2FloatVar(ce[0]);
1736 FloatVar y = s.arg2FloatVar(ce[1]);
1737 FloatVar z = s.arg2FloatVar(ce[2]);
1741 void p_float_plus(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1742 FloatVar x = s.arg2FloatVar(ce[0]);
1743 FloatVar y = s.arg2FloatVar(ce[1]);
1744 FloatVar z = s.arg2FloatVar(ce[2]);
1748 void p_float_sqrt(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1749 FloatVar x = s.arg2FloatVar(ce[0]);
1750 FloatVar y = s.arg2FloatVar(ce[1]);
1754 void p_float_abs(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1755 FloatVar x = s.arg2FloatVar(ce[0]);
1756 FloatVar y = s.arg2FloatVar(ce[1]);
1760 void p_float_eq(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1761 FloatVar x = s.arg2FloatVar(ce[0]);
1762 FloatVar y = s.arg2FloatVar(ce[1]);
1765 void p_float_eq_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1766 FloatVar x = s.arg2FloatVar(ce[0]);
1767 FloatVar y = s.arg2FloatVar(ce[1]);
1768 BoolVar b = s.arg2BoolVar(ce[2]);
1771 void p_float_le(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1772 FloatVar x = s.arg2FloatVar(ce[0]);
1773 FloatVar y = s.arg2FloatVar(ce[1]);
1776 void p_float_le_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1777 FloatVar x = s.arg2FloatVar(ce[0]);
1778 FloatVar y = s.arg2FloatVar(ce[1]);
1779 BoolVar b = s.arg2BoolVar(ce[2]);
1782 void p_float_max(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1783 FloatVar x = s.arg2FloatVar(ce[0]);
1784 FloatVar y = s.arg2FloatVar(ce[1]);
1785 FloatVar z = s.arg2FloatVar(ce[2]);
1788 void p_float_min(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1789 FloatVar x = s.arg2FloatVar(ce[0]);
1790 FloatVar y = s.arg2FloatVar(ce[1]);
1791 FloatVar z = s.arg2FloatVar(ce[2]);
1794 void p_float_lt(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1795 FloatVar x = s.arg2FloatVar(ce[0]);
1796 FloatVar y = s.arg2FloatVar(ce[1]);
1801 void p_float_lt_reif(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1802 FloatVar x = s.arg2FloatVar(ce[0]);
1803 FloatVar y = s.arg2FloatVar(ce[1]);
1804 BoolVar b = s.arg2BoolVar(ce[2]);
1807 rel(s, b == (b0 && !b1));
1812 void p_float_ne(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1813 FloatVar x = s.arg2FloatVar(ce[0]);
1814 FloatVar y = s.arg2FloatVar(ce[1]);
1818 #ifdef GECODE_HAS_MPFR
1819 #define P_FLOAT_OP(Op) \
1820 void p_float_ ## Op (FlatZincSpace& s, const ConExpr& ce, AST::Node*) {\
1821 FloatVar x = s.arg2FloatVar(ce[0]);\
1822 FloatVar y = s.arg2FloatVar(ce[1]);\
1837 void p_float_ln(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1838 FloatVar x = s.arg2FloatVar(ce[0]);
1839 FloatVar y = s.arg2FloatVar(ce[1]);
1842 void p_float_log10(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1843 FloatVar x = s.arg2FloatVar(ce[0]);
1844 FloatVar y = s.arg2FloatVar(ce[1]);
1847 void p_float_log2(FlatZincSpace& s,
const ConExpr& ce, AST::Node*) {
1848 FloatVar x = s.arg2FloatVar(ce[0]);
1849 FloatVar y = s.arg2FloatVar(ce[1]);
1875 registry().
add(
"float_lin_eq_reif",&p_float_lin_eq_reif);
1877 registry().
add(
"float_lin_le_reif",&p_float_lin_le_reif);
1879 #ifdef GECODE_HAS_MPFR