00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <gecode/flatzinc/registry.hh>
00043 #include <gecode/kernel.hh>
00044 #include <gecode/int.hh>
00045 #include <gecode/scheduling.hh>
00046 #include <gecode/minimodel.hh>
00047 #ifdef GECODE_HAS_SET_VARS
00048 #include <gecode/set.hh>
00049 #endif
00050 #include <gecode/flatzinc.hh>
00051
00052 namespace Gecode { namespace FlatZinc {
00053
00054 Registry& registry(void) {
00055 static Registry r;
00056 return r;
00057 }
00058
00059 void
00060 Registry::post(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00061 std::map<std::string,poster>::iterator i = r.find(ce.id);
00062 if (i == r.end()) {
00063 throw FlatZinc::Error("Registry",
00064 std::string("Constraint ")+ce.id+" not found");
00065 }
00066 i->second(s, ce, ann);
00067 }
00068
00069 void
00070 Registry::add(const std::string& id, poster p) {
00071 r[id] = p;
00072 }
00073
00074 namespace {
00075
00076 IntConLevel ann2icl(AST::Node* ann) {
00077 if (ann) {
00078 if (ann->hasAtom("val"))
00079 return ICL_VAL;
00080 if (ann->hasAtom("domain"))
00081 return ICL_DOM;
00082 if (ann->hasAtom("bounds") ||
00083 ann->hasAtom("boundsR") ||
00084 ann->hasAtom("boundsD") ||
00085 ann->hasAtom("boundsZ"))
00086 return ICL_BND;
00087 }
00088 return ICL_DEF;
00089 }
00090
00091 inline IntRelType
00092 swap(IntRelType irt) {
00093 switch (irt) {
00094 case IRT_LQ: return IRT_GQ;
00095 case IRT_LE: return IRT_GR;
00096 case IRT_GQ: return IRT_LQ;
00097 case IRT_GR: return IRT_LE;
00098 default: return irt;
00099 }
00100 }
00101
00102 inline IntRelType
00103 neg(IntRelType irt) {
00104 switch (irt) {
00105 case IRT_EQ: return IRT_NQ;
00106 case IRT_NQ: return IRT_EQ;
00107 case IRT_LQ: return IRT_GR;
00108 case IRT_LE: return IRT_GQ;
00109 case IRT_GQ: return IRT_LE;
00110 case IRT_GR:
00111 default:
00112 assert(irt == IRT_GR);
00113 }
00114 return IRT_LQ;
00115 }
00116
00117 inline IntArgs arg2intargs(AST::Node* arg, int offset = 0) {
00118 AST::Array* a = arg->getArray();
00119 IntArgs ia(a->a.size()+offset);
00120 for (int i=offset; i--;)
00121 ia[i] = 0;
00122 for (int i=a->a.size(); i--;)
00123 ia[i+offset] = a->a[i]->getInt();
00124 return ia;
00125 }
00126
00127 inline IntArgs arg2boolargs(AST::Node* arg, int offset = 0) {
00128 AST::Array* a = arg->getArray();
00129 IntArgs ia(a->a.size()+offset);
00130 for (int i=offset; i--;)
00131 ia[i] = 0;
00132 for (int i=a->a.size(); i--;)
00133 ia[i+offset] = a->a[i]->getBool();
00134 return ia;
00135 }
00136
00137 inline IntSet arg2intset(FlatZincSpace& s, AST::Node* n) {
00138 AST::SetLit* sl = n->getSet();
00139 IntSet d;
00140 if (sl->interval) {
00141 d = IntSet(sl->min, sl->max);
00142 } else {
00143 Region re(s);
00144 int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
00145 for (int i=sl->s.size(); i--; )
00146 is[i] = sl->s[i];
00147 d = IntSet(is, sl->s.size());
00148 }
00149 return d;
00150 }
00151
00152 inline IntSetArgs arg2intsetargs(FlatZincSpace& s,
00153 AST::Node* arg, int offset = 0) {
00154 AST::Array* a = arg->getArray();
00155 if (a->a.size() == 0) {
00156 IntSetArgs emptyIa(0);
00157 return emptyIa;
00158 }
00159 IntSetArgs ia(a->a.size()+offset);
00160 for (int i=offset; i--;)
00161 ia[i] = IntSet::empty;
00162 for (int i=a->a.size(); i--;) {
00163 ia[i+offset] = arg2intset(s, a->a[i]);
00164 }
00165 return ia;
00166 }
00167
00168 inline IntVarArgs arg2intvarargs(FlatZincSpace& s, AST::Node* arg,
00169 int offset = 0) {
00170 AST::Array* a = arg->getArray();
00171 if (a->a.size() == 0) {
00172 IntVarArgs emptyIa(0);
00173 return emptyIa;
00174 }
00175 IntVarArgs ia(a->a.size()+offset);
00176 for (int i=offset; i--;)
00177 ia[i] = IntVar(s, 0, 0);
00178 for (int i=a->a.size(); i--;) {
00179 if (a->a[i]->isIntVar()) {
00180 ia[i+offset] = s.iv[a->a[i]->getIntVar()];
00181 } else {
00182 int value = a->a[i]->getInt();
00183 IntVar iv(s, value, value);
00184 ia[i+offset] = iv;
00185 }
00186 }
00187 return ia;
00188 }
00189
00190 inline BoolVarArgs arg2boolvarargs(FlatZincSpace& s, AST::Node* arg,
00191 int offset = 0) {
00192 AST::Array* a = arg->getArray();
00193 if (a->a.size() == 0) {
00194 BoolVarArgs emptyIa(0);
00195 return emptyIa;
00196 }
00197 BoolVarArgs ia(a->a.size()+offset);
00198 for (int i=offset; i--;)
00199 ia[i] = BoolVar(s, 0, 0);
00200 for (int i=a->a.size(); i--;) {
00201 if (a->a[i]->isBool()) {
00202 bool value = a->a[i]->getBool();
00203 BoolVar iv(s, value, value);
00204 ia[i+offset] = iv;
00205 } else {
00206 ia[i+offset] = s.bv[a->a[i]->getBoolVar()];
00207 }
00208 }
00209 return ia;
00210 }
00211
00212 #ifdef GECODE_HAS_SET_VARS
00213 SetVar getSetVar(FlatZincSpace& s, AST::Node* n) {
00214 SetVar x0;
00215 if (!n->isSetVar()) {
00216 IntSet d = arg2intset(s,n);
00217 x0 = SetVar(s, d, d);
00218 } else {
00219 x0 = s.sv[n->getSetVar()];
00220 }
00221 return x0;
00222 }
00223
00224 inline SetVarArgs arg2setvarargs(FlatZincSpace& s, AST::Node* arg,
00225 int offset = 0) {
00226 AST::Array* a = arg->getArray();
00227 if (a->a.size() == 0) {
00228 SetVarArgs emptyIa(0);
00229 return emptyIa;
00230 }
00231 SetVarArgs ia(a->a.size()+offset);
00232 for (int i=offset; i--;)
00233 ia[i] = SetVar(s, IntSet::empty, IntSet::empty);
00234 for (int i=a->a.size(); i--;) {
00235 ia[i+offset] = getSetVar(s, a->a[i]);
00236 }
00237 return ia;
00238 }
00239 #endif
00240
00241 BoolVar getBoolVar(FlatZincSpace& s, AST::Node* n) {
00242 BoolVar x0;
00243 if (n->isBool()) {
00244 x0 = BoolVar(s, n->getBool(), n->getBool());
00245 }
00246 else {
00247 x0 = s.bv[n->getBoolVar()];
00248 }
00249 return x0;
00250 }
00251
00252 IntVar getIntVar(FlatZincSpace& s, AST::Node* n) {
00253 IntVar x0;
00254 if (n->isIntVar()) {
00255 x0 = s.iv[n->getIntVar()];
00256 } else {
00257 x0 = IntVar(s, n->getInt(), n->getInt());
00258 }
00259 return x0;
00260 }
00261
00262 void p_distinct(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00263 IntVarArgs va = arg2intvarargs(s, ce[0]);
00264 distinct(s, va, ann2icl(ann));
00265 }
00266 void p_distinctOffset(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00267 IntVarArgs va = arg2intvarargs(s, ce[1]);
00268 AST::Array* offs = ce.args->a[0]->getArray();
00269 IntArgs oa(offs->a.size());
00270 for (int i=offs->a.size(); i--; ) {
00271 oa[i] = offs->a[i]->getInt();
00272 }
00273 distinct(s, oa, va, ann2icl(ann));
00274 }
00275
00276 void p_int_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00277 AST::Node* ann) {
00278 if (ce[0]->isIntVar()) {
00279 if (ce[1]->isIntVar()) {
00280 rel(s, getIntVar(s, ce[0]), irt, getIntVar(s, ce[1]),
00281 ann2icl(ann));
00282 } else {
00283 rel(s, getIntVar(s, ce[0]), irt, ce[1]->getInt(), ann2icl(ann));
00284 }
00285 } else {
00286 rel(s, getIntVar(s, ce[1]), swap(irt), ce[0]->getInt(),
00287 ann2icl(ann));
00288 }
00289 }
00290 void p_int_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00291 p_int_CMP(s, IRT_EQ, ce, ann);
00292 }
00293 void p_int_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00294 p_int_CMP(s, IRT_NQ, ce, ann);
00295 }
00296 void p_int_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00297 p_int_CMP(s, IRT_GQ, ce, ann);
00298 }
00299 void p_int_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00300 p_int_CMP(s, IRT_GR, ce, ann);
00301 }
00302 void p_int_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00303 p_int_CMP(s, IRT_LQ, ce, ann);
00304 }
00305 void p_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00306 p_int_CMP(s, IRT_LE, ce, ann);
00307 }
00308 void p_int_CMP_reif(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00309 AST::Node* ann) {
00310 if (ce[2]->isBool()) {
00311 if (ce[2]->getBool()) {
00312 p_int_CMP(s, irt, ce, ann);
00313 } else {
00314 p_int_CMP(s, neg(irt), ce, ann);
00315 }
00316 return;
00317 }
00318 if (ce[0]->isIntVar()) {
00319 if (ce[1]->isIntVar()) {
00320 rel(s, getIntVar(s, ce[0]), irt, getIntVar(s, ce[1]),
00321 getBoolVar(s, ce[2]), ann2icl(ann));
00322 } else {
00323 rel(s, getIntVar(s, ce[0]), irt, ce[1]->getInt(),
00324 getBoolVar(s, ce[2]), ann2icl(ann));
00325 }
00326 } else {
00327 rel(s, getIntVar(s, ce[1]), swap(irt), ce[0]->getInt(),
00328 getBoolVar(s, ce[2]), ann2icl(ann));
00329 }
00330 }
00331
00332
00333 void p_int_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00334 p_int_CMP_reif(s, IRT_EQ, ce, ann);
00335 }
00336 void p_int_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00337 p_int_CMP_reif(s, IRT_NQ, ce, ann);
00338 }
00339 void p_int_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00340 p_int_CMP_reif(s, IRT_GQ, ce, ann);
00341 }
00342 void p_int_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00343 p_int_CMP_reif(s, IRT_GR, ce, ann);
00344 }
00345 void p_int_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00346 p_int_CMP_reif(s, IRT_LQ, ce, ann);
00347 }
00348 void p_int_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00349 p_int_CMP_reif(s, IRT_LE, ce, ann);
00350 }
00351
00352
00353 void p_int_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00354 AST::Node* ann) {
00355 IntArgs ia = arg2intargs(ce[0]);
00356 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00357 linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00358 }
00359 void p_int_lin_CMP_reif(FlatZincSpace& s, IntRelType irt,
00360 const ConExpr& ce, AST::Node* ann) {
00361 if (ce[2]->isBool()) {
00362 if (ce[2]->getBool()) {
00363 p_int_lin_CMP(s, irt, ce, ann);
00364 } else {
00365 p_int_lin_CMP(s, neg(irt), ce, ann);
00366 }
00367 return;
00368 }
00369 IntArgs ia = arg2intargs(ce[0]);
00370 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00371 linear(s, ia, iv, irt, ce[2]->getInt(), getBoolVar(s, ce[3]),
00372 ann2icl(ann));
00373 }
00374 void p_int_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00375 p_int_lin_CMP(s, IRT_EQ, ce, ann);
00376 }
00377 void p_int_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00378 p_int_lin_CMP_reif(s, IRT_EQ, ce, ann);
00379 }
00380 void p_int_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00381 p_int_lin_CMP(s, IRT_NQ, ce, ann);
00382 }
00383 void p_int_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00384 p_int_lin_CMP_reif(s, IRT_NQ, ce, ann);
00385 }
00386 void p_int_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00387 p_int_lin_CMP(s, IRT_LQ, ce, ann);
00388 }
00389 void p_int_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00390 p_int_lin_CMP_reif(s, IRT_LQ, ce, ann);
00391 }
00392 void p_int_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00393 p_int_lin_CMP(s, IRT_LE, ce, ann);
00394 }
00395 void p_int_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00396 p_int_lin_CMP_reif(s, IRT_LE, ce, ann);
00397 }
00398 void p_int_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00399 p_int_lin_CMP(s, IRT_GQ, ce, ann);
00400 }
00401 void p_int_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00402 p_int_lin_CMP_reif(s, IRT_GQ, ce, ann);
00403 }
00404 void p_int_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00405 p_int_lin_CMP(s, IRT_GR, ce, ann);
00406 }
00407 void p_int_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00408 p_int_lin_CMP_reif(s, IRT_GR, ce, ann);
00409 }
00410
00411 void p_bool_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00412 AST::Node* ann) {
00413 IntArgs ia = arg2intargs(ce[0]);
00414 BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00415 if (ce[2]->isIntVar())
00416 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], ann2icl(ann));
00417 else
00418 linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00419 }
00420 void p_bool_lin_CMP_reif(FlatZincSpace& s, IntRelType irt,
00421 const ConExpr& ce, AST::Node* ann) {
00422 if (ce[2]->isBool()) {
00423 if (ce[2]->getBool()) {
00424 p_bool_lin_CMP(s, irt, ce, ann);
00425 } else {
00426 p_bool_lin_CMP(s, neg(irt), ce, ann);
00427 }
00428 return;
00429 }
00430 IntArgs ia = arg2intargs(ce[0]);
00431 BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00432 if (ce[2]->isIntVar())
00433 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], getBoolVar(s, ce[3]),
00434 ann2icl(ann));
00435 else
00436 linear(s, ia, iv, irt, ce[2]->getInt(), getBoolVar(s, ce[3]),
00437 ann2icl(ann));
00438 }
00439 void p_bool_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00440 p_bool_lin_CMP(s, IRT_EQ, ce, ann);
00441 }
00442 void p_bool_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00443 {
00444 p_bool_lin_CMP_reif(s, IRT_EQ, ce, ann);
00445 }
00446 void p_bool_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00447 p_bool_lin_CMP(s, IRT_NQ, ce, ann);
00448 }
00449 void p_bool_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00450 {
00451 p_bool_lin_CMP_reif(s, IRT_NQ, ce, ann);
00452 }
00453 void p_bool_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00454 p_bool_lin_CMP(s, IRT_LQ, ce, ann);
00455 }
00456 void p_bool_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00457 {
00458 p_bool_lin_CMP_reif(s, IRT_LQ, ce, ann);
00459 }
00460 void p_bool_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00461 {
00462 p_bool_lin_CMP(s, IRT_LE, ce, ann);
00463 }
00464 void p_bool_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00465 {
00466 p_bool_lin_CMP_reif(s, IRT_LE, ce, ann);
00467 }
00468 void p_bool_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00469 p_bool_lin_CMP(s, IRT_GQ, ce, ann);
00470 }
00471 void p_bool_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00472 {
00473 p_bool_lin_CMP_reif(s, IRT_GQ, ce, ann);
00474 }
00475 void p_bool_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00476 p_bool_lin_CMP(s, IRT_GR, ce, ann);
00477 }
00478 void p_bool_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00479 {
00480 p_bool_lin_CMP_reif(s, IRT_GR, ce, ann);
00481 }
00482
00483
00484
00485 void p_int_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00486 if (!ce[0]->isIntVar()) {
00487 post(s, ce[0]->getInt() + getIntVar(s, ce[1])
00488 == getIntVar(s,ce[2]), ann2icl(ann));
00489 } else if (!ce[1]->isIntVar()) {
00490 post(s, getIntVar(s,ce[0]) + ce[1]->getInt()
00491 == getIntVar(s,ce[2]), ann2icl(ann));
00492 } else if (!ce[2]->isIntVar()) {
00493 post(s, getIntVar(s,ce[0]) + getIntVar(s,ce[1])
00494 == ce[2]->getInt(), ann2icl(ann));
00495 } else {
00496 post(s, getIntVar(s,ce[0]) + getIntVar(s,ce[1])
00497 == getIntVar(s,ce[2]), ann2icl(ann));
00498 }
00499 }
00500
00501 void p_int_minus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00502 if (!ce[0]->isIntVar()) {
00503 post(s, ce[0]->getInt() - getIntVar(s, ce[1])
00504 == getIntVar(s,ce[2]), ann2icl(ann));
00505 } else if (!ce[1]->isIntVar()) {
00506 post(s, getIntVar(s,ce[0]) - ce[1]->getInt()
00507 == getIntVar(s,ce[2]), ann2icl(ann));
00508 } else if (!ce[2]->isIntVar()) {
00509 post(s, getIntVar(s,ce[0]) - getIntVar(s,ce[1])
00510 == ce[2]->getInt(), ann2icl(ann));
00511 } else {
00512 post(s, getIntVar(s,ce[0]) - getIntVar(s,ce[1])
00513 == getIntVar(s,ce[2]), ann2icl(ann));
00514 }
00515 }
00516
00517 void p_int_times(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00518 IntVar x0 = getIntVar(s, ce[0]);
00519 IntVar x1 = getIntVar(s, ce[1]);
00520 IntVar x2 = getIntVar(s, ce[2]);
00521 mult(s, x0, x1, x2, ann2icl(ann));
00522 }
00523 void p_int_div(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00524 IntVar x0 = getIntVar(s, ce[0]);
00525 IntVar x1 = getIntVar(s, ce[1]);
00526 IntVar x2 = getIntVar(s, ce[2]);
00527 div(s,x0,x1,x2, ann2icl(ann));
00528 }
00529 void p_int_mod(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00530 IntVar x0 = getIntVar(s, ce[0]);
00531 IntVar x1 = getIntVar(s, ce[1]);
00532 IntVar x2 = getIntVar(s, ce[2]);
00533 mod(s,x0,x1,x2, ann2icl(ann));
00534 }
00535
00536 void p_int_min(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00537 IntVar x0 = getIntVar(s, ce[0]);
00538 IntVar x1 = getIntVar(s, ce[1]);
00539 IntVar x2 = getIntVar(s, ce[2]);
00540 min(s, x0, x1, x2, ann2icl(ann));
00541 }
00542 void p_int_max(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00543 IntVar x0 = getIntVar(s, ce[0]);
00544 IntVar x1 = getIntVar(s, ce[1]);
00545 IntVar x2 = getIntVar(s, ce[2]);
00546 max(s, x0, x1, x2, ann2icl(ann));
00547 }
00548 void p_int_negate(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00549 IntVar x0 = getIntVar(s, ce[0]);
00550 IntVar x1 = getIntVar(s, ce[1]);
00551 post(s, x0 == -x1, ann2icl(ann));
00552 }
00553
00554
00555 void p_bool_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00556 AST::Node* ann) {
00557 if (ce[0]->isBoolVar()) {
00558 if (ce[1]->isBoolVar()) {
00559 rel(s, getBoolVar(s, ce[0]), irt, getBoolVar(s, ce[1]),
00560 ann2icl(ann));
00561 } else {
00562 rel(s, getBoolVar(s, ce[0]), irt, ce[1]->getBool(), ann2icl(ann));
00563 }
00564 } else {
00565 rel(s, getBoolVar(s, ce[1]), swap(irt), ce[0]->getBool(),
00566 ann2icl(ann));
00567 }
00568 }
00569 void p_bool_CMP_reif(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00570 AST::Node* ann) {
00571 rel(s, getBoolVar(s, ce[0]), irt, getBoolVar(s, ce[1]),
00572 getBoolVar(s, ce[2]), ann2icl(ann));
00573 }
00574 void p_bool_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00575 p_bool_CMP(s, IRT_EQ, ce, ann);
00576 }
00577 void p_bool_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00578 p_bool_CMP_reif(s, IRT_EQ, ce, ann);
00579 }
00580 void p_bool_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00581 p_bool_CMP(s, IRT_NQ, ce, ann);
00582 }
00583 void p_bool_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00584 p_bool_CMP_reif(s, IRT_NQ, ce, ann);
00585 }
00586 void p_bool_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00587 p_bool_CMP(s, IRT_GQ, ce, ann);
00588 }
00589 void p_bool_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00590 p_bool_CMP_reif(s, IRT_GQ, ce, ann);
00591 }
00592 void p_bool_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00593 p_bool_CMP(s, IRT_LQ, ce, ann);
00594 }
00595 void p_bool_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00596 p_bool_CMP_reif(s, IRT_LQ, ce, ann);
00597 }
00598 void p_bool_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00599 p_bool_CMP(s, IRT_GR, ce, ann);
00600 }
00601 void p_bool_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00602 p_bool_CMP_reif(s, IRT_GR, ce, ann);
00603 }
00604 void p_bool_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00605 p_bool_CMP(s, IRT_LE, ce, ann);
00606 }
00607 void p_bool_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00608 p_bool_CMP_reif(s, IRT_LE, ce, ann);
00609 }
00610
00611 #define BOOL_OP(op) \
00612 BoolVar b0 = getBoolVar(s, ce[0]); \
00613 BoolVar b1 = getBoolVar(s, ce[1]); \
00614 if (ce[2]->isBool()) { \
00615 rel(s, b0, op, b1, ce[2]->getBool(), ann2icl(ann)); \
00616 } else { \
00617 rel(s, b0, op, b1, s.bv[ce[2]->getBoolVar()], ann2icl(ann)); \
00618 }
00619
00620 #define BOOL_ARRAY_OP(op) \
00621 BoolVarArgs bv = arg2boolvarargs(s, ce[0]); \
00622 if (ce[1]->isBool()) { \
00623 rel(s, op, bv, ce[1]->getBool(), ann2icl(ann)); \
00624 } else { \
00625 rel(s, op, bv, s.bv[ce[1]->getBoolVar()], ann2icl(ann)); \
00626 }
00627
00628 void p_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00629 BOOL_OP(BOT_OR);
00630 }
00631 void p_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00632 BOOL_OP(BOT_AND);
00633 }
00634 void p_array_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00635 {
00636 BOOL_ARRAY_OP(BOT_AND);
00637 }
00638 void p_array_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00639 {
00640 BOOL_ARRAY_OP(BOT_OR);
00641 }
00642 void p_array_bool_clause(FlatZincSpace& s, const ConExpr& ce,
00643 AST::Node* ann) {
00644 BoolVarArgs bvp = arg2boolvarargs(s, ce[0]);
00645 BoolVarArgs bvn = arg2boolvarargs(s, ce[1]);
00646 clause(s, BOT_OR, bvp, bvn, 1, ann2icl(ann));
00647 }
00648 void p_array_bool_clause_reif(FlatZincSpace& s, const ConExpr& ce,
00649 AST::Node* ann) {
00650 BoolVarArgs bvp = arg2boolvarargs(s, ce[0]);
00651 BoolVarArgs bvn = arg2boolvarargs(s, ce[1]);
00652 BoolVar b0 = getBoolVar(s, ce[2]);
00653 clause(s, BOT_OR, bvp, bvn, b0, ann2icl(ann));
00654 }
00655 void p_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00656 BOOL_OP(BOT_XOR);
00657 }
00658 void p_bool_l_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00659 BoolVar b0 = getBoolVar(s, ce[0]);
00660 BoolVar b1 = getBoolVar(s, ce[1]);
00661 if (ce[2]->isBool()) {
00662 rel(s, b1, BOT_IMP, b0, ce[2]->getBool(), ann2icl(ann));
00663 } else {
00664 rel(s, b1, BOT_IMP, b0, s.bv[ce[2]->getBoolVar()], ann2icl(ann));
00665 }
00666 }
00667 void p_bool_r_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00668 BOOL_OP(BOT_IMP);
00669 }
00670 void p_bool_not(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00671 BoolVar x0 = getBoolVar(s, ce[0]);
00672 BoolVar x1 = getBoolVar(s, ce[1]);
00673 rel(s, x0, BOT_XOR, x1, 1, ann2icl(ann));
00674 }
00675
00676
00677 void p_array_int_element(FlatZincSpace& s, const ConExpr& ce,
00678 AST::Node* ann) {
00679 bool isConstant = true;
00680 AST::Array* a = ce[1]->getArray();
00681 for (int i=a->a.size(); i--;) {
00682 if (!a->a[i]->isInt()) {
00683 isConstant = false;
00684 break;
00685 }
00686 }
00687 IntVar selector = getIntVar(s, ce[0]);
00688 post(s, selector > 0);
00689 if (isConstant) {
00690 IntArgs ia = arg2intargs(ce[1], 1);
00691 element(s, ia, selector, getIntVar(s, ce[2]), ann2icl(ann));
00692 } else {
00693 IntVarArgs iv = arg2intvarargs(s, ce[1], 1);
00694 element(s, iv, selector, getIntVar(s, ce[2]), ann2icl(ann));
00695 }
00696 }
00697 void p_array_bool_element(FlatZincSpace& s, const ConExpr& ce,
00698 AST::Node* ann) {
00699 bool isConstant = true;
00700 AST::Array* a = ce[1]->getArray();
00701 for (int i=a->a.size(); i--;) {
00702 if (!a->a[i]->isBool()) {
00703 isConstant = false;
00704 break;
00705 }
00706 }
00707 IntVar selector = getIntVar(s, ce[0]);
00708 post(s, selector > 0);
00709 if (isConstant) {
00710 IntArgs ia = arg2boolargs(ce[1], 1);
00711 element(s, ia, selector, getBoolVar(s, ce[2]), ann2icl(ann));
00712 } else {
00713 BoolVarArgs iv = arg2boolvarargs(s, ce[1], 1);
00714 element(s, iv, selector, getBoolVar(s, ce[2]), ann2icl(ann));
00715 }
00716 }
00717
00718
00719 void p_bool2int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00720 BoolVar x0 = getBoolVar(s, ce[0]);
00721 IntVar x1 = getIntVar(s, ce[1]);
00722 channel(s, x0, x1, ann2icl(ann));
00723 }
00724
00725
00726
00727 void p_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00728 IntVar x0 = getIntVar(s, ce[0]);
00729 IntVar x1 = getIntVar(s, ce[1]);
00730 abs(s, x0, x1, ann2icl(ann));
00731 }
00732
00733 void p_array_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00734 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00735 IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00736 rel(s, iv0, IRT_LE, iv1, ann2icl(ann));
00737 }
00738
00739 void p_array_int_lq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00740 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00741 IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00742 rel(s, iv0, IRT_LQ, iv1, ann2icl(ann));
00743 }
00744
00745 void p_count(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00746 IntVarArgs iv = arg2intvarargs(s, ce[0]);
00747 if (!ce[1]->isIntVar()) {
00748 if (!ce[2]->isIntVar()) {
00749 count(s, iv, ce[1]->getInt(), IRT_EQ, ce[2]->getInt(),
00750 ann2icl(ann));
00751 } else {
00752 count(s, iv, ce[1]->getInt(), IRT_EQ, getIntVar(s, ce[2]),
00753 ann2icl(ann));
00754 }
00755 } else if (!ce[2]->isIntVar()) {
00756 count(s, iv, getIntVar(s, ce[1]), IRT_EQ, ce[2]->getInt(),
00757 ann2icl(ann));
00758 } else {
00759 count(s, iv, getIntVar(s, ce[1]), IRT_EQ, getIntVar(s, ce[2]),
00760 ann2icl(ann));
00761 }
00762 }
00763
00764 void count_rel(IntRelType irt,
00765 FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00766 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00767 count(s, iv, ce[2]->getInt(), irt, ce[0]->getInt(), ann2icl(ann));
00768 }
00769
00770 void p_at_most(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00771 count_rel(IRT_LQ, s, ce, ann);
00772 }
00773
00774 void p_at_least(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00775 count_rel(IRT_GQ, s, ce, ann);
00776 }
00777
00778 void p_global_cardinality(FlatZincSpace& s, const ConExpr& ce,
00779 AST::Node* ann) {
00780 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00781 IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00782 int cmin = ce[2]->getInt();
00783
00784 int smallest = cmin;
00785 int largest = iv1.size()-1;
00786 for (int i=iv0.size(); i--;) {
00787 smallest = std::min(smallest, iv0[i].min());
00788 largest = std::max(largest, iv0[i].max());
00789 }
00790
00791
00792 if (cmin == 0 && smallest == 0 && largest == iv1.size()-1) {
00793 count(s, iv0, iv1, ann2icl(ann));
00794 } else {
00795 IntArgs values(largest - smallest + 1);
00796 for (int i=largest-smallest+1; i--;)
00797 values[i] = i+smallest;
00798 IntVarArgs iv1tmp(largest-smallest+1);
00799 int k = 0;
00800 for (int i=cmin-smallest; i--;) {
00801 iv1tmp[k++] = IntVar(s, 0, iv0.size());
00802 }
00803 for (int i=0; i<iv1.size(); i++)
00804 iv1tmp[k++] = iv1[i];
00805 for (int i=k; i<iv1tmp.size(); i++) {
00806 iv1tmp[i] = IntVar(s, 0, iv0.size());
00807 }
00808 count(s, iv0, iv1tmp, values, ann2icl(ann));
00809 }
00810 }
00811
00812 void p_minimum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00813 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00814 min(s, iv, getIntVar(s, ce[0]), ann2icl(ann));
00815 }
00816
00817 void p_maximum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00818 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00819 max(s, iv, getIntVar(s, ce[0]), ann2icl(ann));
00820 }
00821
00822 void p_regular(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00823 IntVarArgs iv = arg2intvarargs(s, ce[0]);
00824 int q = ce[1]->getInt();
00825 int symbols = ce[2]->getInt();
00826 IntArgs d = arg2intargs(ce[3]);
00827 int q0 = ce[4]->getInt();
00828
00829 int noOfTrans = 0;
00830 for (int i=1; i<=q; i++) {
00831 for (int j=1; j<=symbols; j++) {
00832 if (d[(i-1)*symbols+(j-1)] > 0)
00833 noOfTrans++;
00834 }
00835 }
00836
00837 Region re(s);
00838 DFA::Transition* t = re.alloc<DFA::Transition>(noOfTrans+1);
00839 noOfTrans = 0;
00840 for (int i=1; i<=q; i++) {
00841 for (int j=1; j<=symbols; j++) {
00842 if (d[(i-1)*symbols+(j-1)] > 0) {
00843 t[noOfTrans].i_state = i;
00844 t[noOfTrans].symbol = j;
00845 t[noOfTrans].o_state = d[(i-1)*symbols+(j-1)];
00846 noOfTrans++;
00847 }
00848 }
00849 }
00850 t[noOfTrans].i_state = -1;
00851
00852
00853 AST::SetLit* sl = ce[5]->getSet();
00854 int* f;
00855 if (sl->interval) {
00856 f = static_cast<int*>(malloc(sizeof(int)*(sl->max-sl->min+2)));
00857 for (int i=sl->min; i<=sl->max; i++)
00858 f[i-sl->min] = i;
00859 f[sl->max-sl->min+1] = -1;
00860 } else {
00861 f = static_cast<int*>(malloc(sizeof(int)*(sl->s.size()+1)));
00862 for (int j=sl->s.size(); j--; )
00863 f[j] = sl->s[j];
00864 f[sl->s.size()] = -1;
00865 }
00866
00867 DFA dfa(q0,t,f);
00868 free(f);
00869 extensional(s, iv, dfa, ann2icl(ann));
00870 }
00871
00872 void
00873 p_sort(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00874 IntVarArgs x = arg2intvarargs(s, ce[0]);
00875 IntVarArgs y = arg2intvarargs(s, ce[1]);
00876 IntVarArgs xy(x.size()+y.size());
00877 for (int i=x.size(); i--;)
00878 xy[i] = x[i];
00879 for (int i=y.size(); i--;)
00880 xy[i+x.size()] = y[i];
00881 unshare(s, xy);
00882 for (int i=x.size(); i--;)
00883 x[i] = xy[i];
00884 for (int i=y.size(); i--;)
00885 y[i] = xy[i+x.size()];
00886 sorted(s, x, y, ann2icl(ann));
00887 }
00888
00889 void
00890 p_inverse_offsets(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00891 IntVarArgs x = arg2intvarargs(s, ce[0]);
00892 int xoff = ce[1]->getInt();
00893 IntVarArgs y = arg2intvarargs(s, ce[2]);
00894 int yoff = ce[3]->getInt();
00895 channel(s, x, xoff, y, yoff, ann2icl(ann));
00896 }
00897
00898 void
00899 p_increasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00900 IntVarArgs x = arg2intvarargs(s, ce[0]);
00901 rel(s,x,IRT_LQ,ann2icl(ann));
00902 }
00903
00904 void
00905 p_increasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00906 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
00907 rel(s,x,IRT_LQ,ann2icl(ann));
00908 }
00909
00910 void
00911 p_table_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00912 IntVarArgs x = arg2intvarargs(s, ce[0]);
00913 IntArgs tuples = arg2intargs(ce[1]);
00914 int noOfVars = x.size();
00915 int noOfTuples = tuples.size()/noOfVars;
00916 TupleSet ts;
00917 for (int i=0; i<noOfTuples; i++) {
00918 IntArgs t(noOfVars);
00919 for (int j=0; j<x.size(); j++) {
00920 t[j] = tuples[i*noOfVars+j];
00921 }
00922 ts.add(t);
00923 }
00924 ts.finalize();
00925 extensional(s,x,ts,EPK_DEF,ann2icl(ann));
00926 }
00927 void
00928 p_table_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00929 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
00930 IntArgs tuples = arg2boolargs(ce[1]);
00931 int noOfVars = x.size();
00932 int noOfTuples = tuples.size()/noOfVars;
00933 TupleSet ts;
00934 for (int i=0; i<noOfTuples; i++) {
00935 IntArgs t(noOfVars);
00936 for (int j=0; j<x.size(); j++) {
00937 t[j] = tuples[i*noOfVars+j];
00938 }
00939 ts.add(t);
00940 }
00941 ts.finalize();
00942 extensional(s,x,ts,EPK_DEF,ann2icl(ann));
00943 }
00944
00945 void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
00946 AST::Node* ann) {
00947 IntVarArgs start = arg2intvarargs(s, ce[0]);
00948 IntVarArgs duration = arg2intvarargs(s, ce[1]);
00949 IntVarArgs height = arg2intvarargs(s, ce[2]);
00950 int n = start.size();
00951 IntVar bound = getIntVar(s, ce[3]);
00952
00953 if (bound.assigned()) {
00954 IntArgs machine(n);
00955 for (int i = n; i--; ) machine[i] = 0;
00956 IntArgs limit(1, bound.val());
00957 IntVarArgs end(n);
00958 for (int i = n; i--; ) end[i] = IntVar(s, 0, Int::Limits::max);
00959 cumulatives(s, machine, start, duration, end, height, limit, true,
00960 ann2icl(ann));
00961 } else {
00962 int min = Gecode::Int::Limits::max;
00963 int max = Gecode::Int::Limits::min;
00964 IntVarArgs end(start.size());
00965 for (int i = start.size(); i--; ) {
00966 min = std::min(min, start[i].min());
00967 max = std::max(max, start[i].max() + duration[i].max());
00968 end[i] = post(s, start[i] + duration[i]);
00969 }
00970 for (int time = min; time < max; ++time) {
00971 IntVarArgs x(start.size());
00972 for (int i = start.size(); i--; ) {
00973 IntVar overlaps = channel(s, post(s, (~(start[i] <= time) &&
00974 ~(time < end[i]))));
00975 x[i] = mult(s, overlaps, height[i]);
00976 }
00977 linear(s, x, IRT_LQ, bound);
00978 }
00979 }
00980 }
00981
00982 void p_among_seq_int(FlatZincSpace& s, const ConExpr& ce,
00983 AST::Node* ann) {
00984 IntVarArgs x = arg2intvarargs(s, ce[0]);
00985 IntSet S = arg2intset(s, ce[1]);
00986 int q = ce[2]->getInt();
00987 int l = ce[3]->getInt();
00988 int u = ce[4]->getInt();
00989 sequence(s, x, S, q, l, u, ann2icl(ann));
00990 }
00991
00992 void p_among_seq_bool(FlatZincSpace& s, const ConExpr& ce,
00993 AST::Node* ann) {
00994 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
00995 bool val = ce[1]->getBool();
00996 int q = ce[2]->getInt();
00997 int l = ce[3]->getInt();
00998 int u = ce[4]->getInt();
00999 IntSet S(val, val);
01000 sequence(s, x, S, q, l, u, ann2icl(ann));
01001 }
01002
01003 class IntPoster {
01004 public:
01005 IntPoster(void) {
01006 registry().add("all_different_int", &p_distinct);
01007 registry().add("all_different_offset", &p_distinctOffset);
01008 registry().add("int_eq", &p_int_eq);
01009 registry().add("int_ne", &p_int_ne);
01010 registry().add("int_ge", &p_int_ge);
01011 registry().add("int_gt", &p_int_gt);
01012 registry().add("int_le", &p_int_le);
01013 registry().add("int_lt", &p_int_lt);
01014 registry().add("int_eq_reif", &p_int_eq_reif);
01015 registry().add("int_ne_reif", &p_int_ne_reif);
01016 registry().add("int_ge_reif", &p_int_ge_reif);
01017 registry().add("int_gt_reif", &p_int_gt_reif);
01018 registry().add("int_le_reif", &p_int_le_reif);
01019 registry().add("int_lt_reif", &p_int_lt_reif);
01020 registry().add("int_lin_eq", &p_int_lin_eq);
01021 registry().add("int_lin_eq_reif", &p_int_lin_eq_reif);
01022 registry().add("int_lin_ne", &p_int_lin_ne);
01023 registry().add("int_lin_ne_reif", &p_int_lin_ne_reif);
01024 registry().add("int_lin_le", &p_int_lin_le);
01025 registry().add("int_lin_le_reif", &p_int_lin_le_reif);
01026 registry().add("int_lin_lt", &p_int_lin_lt);
01027 registry().add("int_lin_lt_reif", &p_int_lin_lt_reif);
01028 registry().add("int_lin_ge", &p_int_lin_ge);
01029 registry().add("int_lin_ge_reif", &p_int_lin_ge_reif);
01030 registry().add("int_lin_gt", &p_int_lin_gt);
01031 registry().add("int_lin_gt_reif", &p_int_lin_gt_reif);
01032 registry().add("int_plus", &p_int_plus);
01033 registry().add("int_minus", &p_int_minus);
01034 registry().add("int_times", &p_int_times);
01035 registry().add("int_div", &p_int_div);
01036 registry().add("int_mod", &p_int_mod);
01037 registry().add("int_min", &p_int_min);
01038 registry().add("int_max", &p_int_max);
01039 registry().add("int_abs", &p_abs);
01040 registry().add("int_negate", &p_int_negate);
01041 registry().add("bool_eq", &p_bool_eq);
01042 registry().add("bool_eq_reif", &p_bool_eq_reif);
01043 registry().add("bool_ne", &p_bool_ne);
01044 registry().add("bool_ne_reif", &p_bool_ne_reif);
01045 registry().add("bool_ge", &p_bool_ge);
01046 registry().add("bool_ge_reif", &p_bool_ge_reif);
01047 registry().add("bool_le", &p_bool_le);
01048 registry().add("bool_le_reif", &p_bool_le_reif);
01049 registry().add("bool_gt", &p_bool_gt);
01050 registry().add("bool_gt_reif", &p_bool_gt_reif);
01051 registry().add("bool_lt", &p_bool_lt);
01052 registry().add("bool_lt_reif", &p_bool_lt_reif);
01053 registry().add("bool_or", &p_bool_or);
01054 registry().add("bool_and", &p_bool_and);
01055 registry().add("bool_xor", &p_bool_xor);
01056 registry().add("array_bool_and", &p_array_bool_and);
01057 registry().add("array_bool_or", &p_array_bool_or);
01058 registry().add("bool_clause", &p_array_bool_clause);
01059 registry().add("bool_clause_reif", &p_array_bool_clause_reif);
01060 registry().add("bool_left_imp", &p_bool_l_imp);
01061 registry().add("bool_right_imp", &p_bool_r_imp);
01062 registry().add("bool_not", &p_bool_not);
01063 registry().add("array_int_element", &p_array_int_element);
01064 registry().add("array_var_int_element", &p_array_int_element);
01065 registry().add("array_bool_element", &p_array_bool_element);
01066 registry().add("array_var_bool_element", &p_array_bool_element);
01067 registry().add("bool2int", &p_bool2int);
01068
01069 registry().add("array_int_lt", &p_array_int_lt);
01070 registry().add("array_int_lq", &p_array_int_lq);
01071 registry().add("count", &p_count);
01072 registry().add("at_least_int", &p_at_least);
01073 registry().add("at_most_int", &p_at_most);
01074 registry().add("global_cardinality_gecode", &p_global_cardinality);
01075 registry().add("minimum_int", &p_minimum);
01076 registry().add("maximum_int", &p_maximum);
01077 registry().add("regular", &p_regular);
01078 registry().add("sort", &p_sort);
01079 registry().add("inverse_offsets", &p_inverse_offsets);
01080 registry().add("increasing_int", &p_increasing_int);
01081 registry().add("increasing_bool", &p_increasing_bool);
01082 registry().add("table_int", &p_table_int);
01083 registry().add("table_bool", &p_table_bool);
01084 registry().add("cumulatives", &p_cumulatives);
01085 registry().add("among_seq_int", &p_among_seq_int);
01086 registry().add("among_seq_bool", &p_among_seq_bool);
01087
01088 registry().add("bool_lin_eq", &p_bool_lin_eq);
01089 registry().add("bool_lin_ne", &p_bool_lin_ne);
01090 registry().add("bool_lin_le", &p_bool_lin_le);
01091 registry().add("bool_lin_lt", &p_bool_lin_lt);
01092 registry().add("bool_lin_ge", &p_bool_lin_ge);
01093 registry().add("bool_lin_gt", &p_bool_lin_gt);
01094
01095 registry().add("bool_lin_eq_reif", &p_bool_lin_eq_reif);
01096 registry().add("bool_lin_ne_reif", &p_bool_lin_ne_reif);
01097 registry().add("bool_lin_le_reif", &p_bool_lin_le_reif);
01098 registry().add("bool_lin_lt_reif", &p_bool_lin_lt_reif);
01099 registry().add("bool_lin_ge_reif", &p_bool_lin_ge_reif);
01100 registry().add("bool_lin_gt_reif", &p_bool_lin_gt_reif);
01101 }
01102 };
01103 IntPoster __int_poster;
01104
01105 #ifdef GECODE_HAS_SET_VARS
01106 void p_set_OP(FlatZincSpace& s, SetOpType op,
01107 const ConExpr& ce, AST::Node *) {
01108 rel(s, getSetVar(s, ce[0]), op, getSetVar(s, ce[1]),
01109 SRT_EQ, getSetVar(s, ce[2]));
01110 }
01111 void p_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01112 p_set_OP(s, SOT_UNION, ce, ann);
01113 }
01114 void p_set_intersect(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01115 p_set_OP(s, SOT_INTER, ce, ann);
01116 }
01117 void p_set_diff(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01118 p_set_OP(s, SOT_MINUS, ce, ann);
01119 }
01120
01121 void p_set_symdiff(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01122 SetVar x = getSetVar(s, ce[0]);
01123 SetVar y = getSetVar(s, ce[1]);
01124
01125 SetVarLubRanges xub(x);
01126 IntSet xubs(xub);
01127 SetVar x_y(s,IntSet::empty,xubs);
01128 rel(s, x, SOT_MINUS, y, SRT_EQ, x_y);
01129
01130 SetVarLubRanges yub(y);
01131 IntSet yubs(yub);
01132 SetVar y_x(s,IntSet::empty,yubs);
01133 rel(s, y, SOT_MINUS, x, SRT_EQ, y_x);
01134
01135 rel(s, x_y, SOT_UNION, y_x, SRT_EQ, getSetVar(s, ce[2]));
01136 }
01137
01138 void p_array_set_OP(FlatZincSpace& s, SetOpType op,
01139 const ConExpr& ce, AST::Node *) {
01140 SetVarArgs xs = arg2setvarargs(s, ce[0]);
01141 rel(s, op, xs, getSetVar(s, ce[1]));
01142 }
01143 void p_array_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01144 p_array_set_OP(s, SOT_UNION, ce, ann);
01145 }
01146 void p_array_set_partition(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01147 p_array_set_OP(s, SOT_DUNION, ce, ann);
01148 }
01149
01150
01151 void p_set_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01152 rel(s, getSetVar(s, ce[0]), SRT_EQ, getSetVar(s, ce[1]));
01153 }
01154 void p_set_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01155 rel(s, getSetVar(s, ce[0]), SRT_NQ, getSetVar(s, ce[1]));
01156 }
01157 void p_set_subset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01158 rel(s, getSetVar(s, ce[0]), SRT_SUB, getSetVar(s, ce[1]));
01159 }
01160 void p_set_superset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01161 rel(s, getSetVar(s, ce[0]), SRT_SUP, getSetVar(s, ce[1]));
01162 }
01163 void p_set_card(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01164 if (!ce[1]->isIntVar()) {
01165 cardinality(s, getSetVar(s, ce[0]), ce[1]->getInt(),
01166 ce[1]->getInt());
01167 } else {
01168 cardinality(s, getSetVar(s, ce[0]), getIntVar(s, ce[1]));
01169 }
01170 }
01171 void p_set_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01172 if (!ce[1]->isSetVar()) {
01173 IntSet d = arg2intset(s,ce[1]);
01174 if (ce[0]->isBoolVar()) {
01175 IntSetRanges dr(d);
01176 Iter::Ranges::Singleton sr(0,1);
01177 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01178 IntSet d01(i);
01179 if (d01.size() == 0) {
01180 s.fail();
01181 } else {
01182 rel(s, getBoolVar(s, ce[0]), IRT_GQ, d01.min());
01183 rel(s, getBoolVar(s, ce[0]), IRT_LQ, d01.max());
01184 }
01185 } else {
01186 dom(s, getIntVar(s, ce[0]), d);
01187 }
01188 } else {
01189 if (!ce[0]->isIntVar()) {
01190 dom(s, getSetVar(s, ce[1]), SRT_SUP, ce[0]->getInt());
01191 } else {
01192 rel(s, getSetVar(s, ce[1]), SRT_SUP, getIntVar(s, ce[0]));
01193 }
01194 }
01195 }
01196 void p_set_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01197 rel(s, getSetVar(s, ce[0]), SRT_EQ, getSetVar(s, ce[1]),
01198 getBoolVar(s, ce[2]));
01199 }
01200 void p_set_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01201 rel(s, getSetVar(s, ce[0]), SRT_NQ, getSetVar(s, ce[1]),
01202 getBoolVar(s, ce[2]));
01203 }
01204 void p_set_subset_reif(FlatZincSpace& s, const ConExpr& ce,
01205 AST::Node *) {
01206 rel(s, getSetVar(s, ce[0]), SRT_SUB, getSetVar(s, ce[1]),
01207 getBoolVar(s, ce[2]));
01208 }
01209 void p_set_superset_reif(FlatZincSpace& s, const ConExpr& ce,
01210 AST::Node *) {
01211 rel(s, getSetVar(s, ce[0]), SRT_SUP, getSetVar(s, ce[1]),
01212 getBoolVar(s, ce[2]));
01213 }
01214 void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01215 if (!ce[1]->isSetVar()) {
01216 IntSet d = arg2intset(s,ce[1]);
01217 if (ce[0]->isBoolVar()) {
01218 IntSetRanges dr(d);
01219 Iter::Ranges::Singleton sr(0,1);
01220 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01221 IntSet d01(i);
01222 if (d01.size() == 0) {
01223 post(s, getBoolVar(s, ce[2]) == 0);
01224 } else if (d01.max() == 0) {
01225 post(s, tt(eqv(getBoolVar(s, ce[2]), !getBoolVar(s, ce[0]))));
01226 } else if (d01.min() == 1) {
01227 post(s, getBoolVar(s, ce[2]) == getBoolVar(s, ce[0]));
01228 } else {
01229 post(s, getBoolVar(s, ce[2]) == 1);
01230 }
01231 } else {
01232 dom(s, getIntVar(s, ce[0]), d, getBoolVar(s, ce[2]));
01233 }
01234 } else {
01235 if (!ce[0]->isIntVar()) {
01236 dom(s, getSetVar(s, ce[1]), SRT_SUP, ce[0]->getInt(),
01237 getBoolVar(s, ce[2]));
01238 } else {
01239 rel(s, getSetVar(s, ce[1]), SRT_SUP, getIntVar(s, ce[0]),
01240 getBoolVar(s, ce[2]));
01241 }
01242 }
01243 }
01244 void p_set_disjoint(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01245 rel(s, getSetVar(s, ce[0]), SRT_DISJ, getSetVar(s, ce[1]));
01246 }
01247
01248 void p_array_set_element(FlatZincSpace& s, const ConExpr& ce,
01249 AST::Node*) {
01250 bool isConstant = true;
01251 AST::Array* a = ce[1]->getArray();
01252 for (int i=a->a.size(); i--;) {
01253 if (a->a[i]->isSetVar()) {
01254 isConstant = false;
01255 break;
01256 }
01257 }
01258 IntVar selector = getIntVar(s, ce[0]);
01259 post(s, selector > 0);
01260 if (isConstant) {
01261 IntSetArgs sv = arg2intsetargs(s,ce[1],1);
01262 element(s, sv, selector, getSetVar(s, ce[2]));
01263 } else {
01264 SetVarArgs sv = arg2setvarargs(s, ce[1], 1);
01265 element(s, sv, selector, getSetVar(s, ce[2]));
01266 }
01267 }
01268
01269 void p_array_set_element_op(FlatZincSpace& s, const ConExpr& ce,
01270 AST::Node*, SetOpType op,
01271 const IntSet& universe =
01272 IntSet(Set::Limits::min,Set::Limits::max)) {
01273 bool isConstant = true;
01274 AST::Array* a = ce[1]->getArray();
01275 for (int i=a->a.size(); i--;) {
01276 if (a->a[i]->isSetVar()) {
01277 isConstant = false;
01278 break;
01279 }
01280 }
01281 SetVar selector = getSetVar(s, ce[0]);
01282 dom(s, selector, SRT_DISJ, 0);
01283 if (isConstant) {
01284 IntSetArgs sv = arg2intsetargs(s,ce[1], 1);
01285 element(s, op, sv, selector, getSetVar(s, ce[2]), universe);
01286 } else {
01287 SetVarArgs sv = arg2setvarargs(s, ce[1], 1);
01288 element(s, op, sv, selector, getSetVar(s, ce[2]), universe);
01289 }
01290 }
01291
01292 void p_array_set_element_union(FlatZincSpace& s, const ConExpr& ce,
01293 AST::Node* ann) {
01294 p_array_set_element_op(s, ce, ann, SOT_UNION);
01295 }
01296
01297 void p_array_set_element_intersect(FlatZincSpace& s, const ConExpr& ce,
01298 AST::Node* ann) {
01299 p_array_set_element_op(s, ce, ann, SOT_INTER);
01300 }
01301
01302 void p_array_set_element_intersect_in(FlatZincSpace& s,
01303 const ConExpr& ce,
01304 AST::Node* ann) {
01305 IntSet d = arg2intset(s, ce[3]);
01306 p_array_set_element_op(s, ce, ann, SOT_INTER, d);
01307 }
01308
01309 void p_array_set_element_partition(FlatZincSpace& s, const ConExpr& ce,
01310 AST::Node* ann) {
01311 p_array_set_element_op(s, ce, ann, SOT_DUNION);
01312 }
01313
01314 void p_set_convex(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01315 convex(s, getSetVar(s, ce[0]));
01316 }
01317
01318 void p_array_set_seq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01319 SetVarArgs sv = arg2setvarargs(s, ce[0]);
01320 sequence(s, sv);
01321 }
01322
01323 void p_array_set_seq_union(FlatZincSpace& s, const ConExpr& ce,
01324 AST::Node *) {
01325 SetVarArgs sv = arg2setvarargs(s, ce[0]);
01326 sequence(s, sv, getSetVar(s, ce[1]));
01327 }
01328
01329 class SetPoster {
01330 public:
01331 SetPoster(void) {
01332 registry().add("set_eq", &p_set_eq);
01333 registry().add("equal", &p_set_eq);
01334 registry().add("set_ne", &p_set_ne);
01335 registry().add("set_union", &p_set_union);
01336 registry().add("array_set_element", &p_array_set_element);
01337 registry().add("array_var_set_element", &p_array_set_element);
01338 registry().add("set_intersect", &p_set_intersect);
01339 registry().add("set_diff", &p_set_diff);
01340 registry().add("set_symdiff", &p_set_symdiff);
01341 registry().add("set_subset", &p_set_subset);
01342 registry().add("set_superset", &p_set_superset);
01343 registry().add("set_card", &p_set_card);
01344 registry().add("set_in", &p_set_in);
01345 registry().add("set_eq_reif", &p_set_eq_reif);
01346 registry().add("equal_reif", &p_set_eq_reif);
01347 registry().add("set_ne_reif", &p_set_ne_reif);
01348 registry().add("set_subset_reif", &p_set_subset_reif);
01349 registry().add("set_superset_reif", &p_set_superset_reif);
01350 registry().add("set_in_reif", &p_set_in_reif);
01351 registry().add("disjoint", &p_set_disjoint);
01352
01353 registry().add("array_set_union", &p_array_set_union);
01354 registry().add("array_set_partition", &p_array_set_partition);
01355 registry().add("set_convex", &p_set_convex);
01356 registry().add("array_set_seq", &p_array_set_seq);
01357 registry().add("array_set_seq_union", &p_array_set_seq_union);
01358 registry().add("array_set_element_union",
01359 &p_array_set_element_union);
01360 registry().add("array_set_element_intersect",
01361 &p_array_set_element_intersect);
01362 registry().add("array_set_element_intersect_in",
01363 &p_array_set_element_intersect_in);
01364 registry().add("array_set_element_partition",
01365 &p_array_set_element_partition);
01366 }
01367 };
01368 SetPoster __set_poster;
01369 #endif
01370
01371 }
01372 }}
01373
01374