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/minimodel.hh>
00046 #ifdef GECODE_HAS_SET_VARS
00047 #include <gecode/set.hh>
00048 #endif
00049 #include <gecode/flatzinc.hh>
00050
00051 namespace Gecode { namespace FlatZinc {
00052
00053 Registry& registry(void) {
00054 static Registry r;
00055 return r;
00056 }
00057
00058 void
00059 Registry::post(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00060 std::map<std::string,poster>::iterator i = r.find(ce.id);
00061 if (i == r.end()) {
00062 throw FlatZinc::Error("Registry",
00063 std::string("Constraint ")+ce.id+" not found");
00064 }
00065 i->second(s, ce, ann);
00066 }
00067
00068 void
00069 Registry::add(const std::string& id, poster p) {
00070 r[id] = p;
00071 }
00072
00073 namespace {
00074
00075 IntConLevel ann2icl(AST::Node* ann) {
00076 if (ann) {
00077 if (ann->hasAtom("val"))
00078 return ICL_VAL;
00079 if (ann->hasAtom("domain"))
00080 return ICL_DOM;
00081 if (ann->hasAtom("bounds") ||
00082 ann->hasAtom("boundsR") ||
00083 ann->hasAtom("boundsD") ||
00084 ann->hasAtom("boundsZ"))
00085 return ICL_BND;
00086 }
00087 return ICL_DEF;
00088 }
00089
00090 inline IntRelType
00091 swap(IntRelType irt) {
00092 switch (irt) {
00093 case IRT_LQ: return IRT_GQ;
00094 case IRT_LE: return IRT_GR;
00095 case IRT_GQ: return IRT_LQ;
00096 case IRT_GR: return IRT_LE;
00097 default: return irt;
00098 }
00099 }
00100
00101 inline IntRelType
00102 neg(IntRelType irt) {
00103 switch (irt) {
00104 case IRT_EQ: return IRT_NQ;
00105 case IRT_NQ: return IRT_EQ;
00106 case IRT_LQ: return IRT_GR;
00107 case IRT_LE: return IRT_GQ;
00108 case IRT_GQ: return IRT_LE;
00109 case IRT_GR:
00110 default:
00111 assert(irt == IRT_GR);
00112 }
00113 return IRT_LQ;
00114 }
00115
00116 inline IntArgs arg2intargs(AST::Node* arg, int offset = 0) {
00117 AST::Array* a = arg->getArray();
00118 IntArgs ia(a->a.size()+offset);
00119 for (int i=offset; i--;)
00120 ia[i] = 0;
00121 for (int i=a->a.size(); i--;)
00122 ia[i+offset] = a->a[i]->getInt();
00123 return ia;
00124 }
00125
00126 inline IntArgs arg2boolargs(AST::Node* arg, int offset = 0) {
00127 AST::Array* a = arg->getArray();
00128 IntArgs ia(a->a.size()+offset);
00129 for (int i=offset; i--;)
00130 ia[i] = 0;
00131 for (int i=a->a.size(); i--;)
00132 ia[i+offset] = a->a[i]->getBool();
00133 return ia;
00134 }
00135
00136 inline IntSet arg2intset(FlatZincSpace& s, AST::Node* n) {
00137 AST::SetLit* sl = n->getSet();
00138 IntSet d;
00139 if (sl->interval) {
00140 d = IntSet(sl->min, sl->max);
00141 } else {
00142 Region re(s);
00143 int* is = re.alloc<int>(static_cast<unsigned long int>(sl->s.size()));
00144 for (int i=sl->s.size(); i--; )
00145 is[i] = sl->s[i];
00146 d = IntSet(is, sl->s.size());
00147 }
00148 return d;
00149 }
00150
00151 inline IntSetArgs arg2intsetargs(FlatZincSpace& s,
00152 AST::Node* arg, int offset = 0) {
00153 AST::Array* a = arg->getArray();
00154 if (a->a.size() == 0) {
00155 IntSetArgs emptyIa(0);
00156 return emptyIa;
00157 }
00158 IntSetArgs ia(a->a.size()+offset);
00159 for (int i=offset; i--;)
00160 ia[i] = IntSet::empty;
00161 for (int i=a->a.size(); i--;) {
00162 ia[i+offset] = arg2intset(s, a->a[i]);
00163 }
00164 return ia;
00165 }
00166
00167 inline IntVarArgs arg2intvarargs(FlatZincSpace& s, AST::Node* arg,
00168 int offset = 0) {
00169 AST::Array* a = arg->getArray();
00170 if (a->a.size() == 0) {
00171 IntVarArgs emptyIa(0);
00172 return emptyIa;
00173 }
00174 IntVarArgs ia(a->a.size()+offset);
00175 for (int i=offset; i--;)
00176 ia[i] = IntVar(s, 0, 0);
00177 for (int i=a->a.size(); i--;) {
00178 if (a->a[i]->isIntVar()) {
00179 ia[i+offset] = s.iv[a->a[i]->getIntVar()];
00180 } else {
00181 int value = a->a[i]->getInt();
00182 IntVar iv(s, value, value);
00183 ia[i+offset] = iv;
00184 }
00185 }
00186 return ia;
00187 }
00188
00189 inline BoolVarArgs arg2boolvarargs(FlatZincSpace& s, AST::Node* arg,
00190 int offset = 0, int siv=-1) {
00191 AST::Array* a = arg->getArray();
00192 if (a->a.size() == 0) {
00193 BoolVarArgs emptyIa(0);
00194 return emptyIa;
00195 }
00196 BoolVarArgs ia(a->a.size()+offset-(siv==-1?0:1));
00197 for (int i=offset; i--;)
00198 ia[i] = BoolVar(s, 0, 0);
00199 for (int i=0; i<static_cast<int>(a->a.size()); i++) {
00200 if (i==siv)
00201 continue;
00202 if (a->a[i]->isBool()) {
00203 bool value = a->a[i]->getBool();
00204 BoolVar iv(s, value, value);
00205 ia[offset++] = iv;
00206 } else if (a->a[i]->isIntVar() &&
00207 s.aliasBool2Int(a->a[i]->getIntVar()) != -1) {
00208 ia[offset++] = s.bv[s.aliasBool2Int(a->a[i]->getIntVar())];
00209 } else {
00210 ia[offset++] = s.bv[a->a[i]->getBoolVar()];
00211 }
00212 }
00213 return ia;
00214 }
00215
00216 #ifdef GECODE_HAS_SET_VARS
00217 SetVar getSetVar(FlatZincSpace& s, AST::Node* n) {
00218 SetVar x0;
00219 if (!n->isSetVar()) {
00220 IntSet d = arg2intset(s,n);
00221 x0 = SetVar(s, d, d);
00222 } else {
00223 x0 = s.sv[n->getSetVar()];
00224 }
00225 return x0;
00226 }
00227
00228 inline SetVarArgs arg2setvarargs(FlatZincSpace& s, AST::Node* arg,
00229 int offset = 0, int doffset = 0,
00230 const IntSet& od=IntSet::empty) {
00231 AST::Array* a = arg->getArray();
00232 SetVarArgs ia(a->a.size()+offset);
00233 for (int i=offset; i--;) {
00234 IntSet d = i<doffset ? od : IntSet::empty;
00235 ia[i] = SetVar(s, d, d);
00236 }
00237 for (int i=a->a.size(); i--;) {
00238 ia[i+offset] = getSetVar(s, a->a[i]);
00239 }
00240 return ia;
00241 }
00242 #endif
00243
00244 BoolVar getBoolVar(FlatZincSpace& s, AST::Node* n) {
00245 BoolVar x0;
00246 if (n->isBool()) {
00247 x0 = BoolVar(s, n->getBool(), n->getBool());
00248 }
00249 else {
00250 x0 = s.bv[n->getBoolVar()];
00251 }
00252 return x0;
00253 }
00254
00255 IntVar getIntVar(FlatZincSpace& s, AST::Node* n) {
00256 IntVar x0;
00257 if (n->isIntVar()) {
00258 x0 = s.iv[n->getIntVar()];
00259 } else {
00260 x0 = IntVar(s, n->getInt(), n->getInt());
00261 }
00262 return x0;
00263 }
00264
00265 bool isBoolArray(FlatZincSpace& s, AST::Node* b, int& singleInt) {
00266 AST::Array* a = b->getArray();
00267 singleInt = -1;
00268 if (a->a.size() == 0)
00269 return true;
00270 for (int i=a->a.size(); i--;) {
00271 if (a->a[i]->isBoolVar() || a->a[i]->isBool()) {
00272 } else if (a->a[i]->isIntVar()) {
00273 if (s.aliasBool2Int(a->a[i]->getIntVar()) == -1) {
00274 if (singleInt != -1) {
00275 return false;
00276 }
00277 singleInt = i;
00278 }
00279 } else {
00280 return false;
00281 }
00282 }
00283 return singleInt==-1 || a->a.size() > 1;
00284 }
00285
00286 void p_distinct(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00287 IntVarArgs va = arg2intvarargs(s, ce[0]);
00288 IntConLevel icl = ann2icl(ann);
00289 distinct(s, va, icl == ICL_DEF ? ICL_BND : icl);
00290 }
00291 void p_distinctOffset(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00292 IntVarArgs va = arg2intvarargs(s, ce[1]);
00293 AST::Array* offs = ce.args->a[0]->getArray();
00294 IntArgs oa(offs->a.size());
00295 for (int i=offs->a.size(); i--; ) {
00296 oa[i] = offs->a[i]->getInt();
00297 }
00298 IntConLevel icl = ann2icl(ann);
00299 distinct(s, oa, va, icl == ICL_DEF ? ICL_BND : icl);
00300 }
00301
00302 void p_all_equal(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00303 IntVarArgs va = arg2intvarargs(s, ce[0]);
00304 rel(s, va, IRT_EQ, ann2icl(ann));
00305 }
00306
00307 void p_int_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00308 AST::Node* ann) {
00309 if (ce[0]->isIntVar()) {
00310 if (ce[1]->isIntVar()) {
00311 rel(s, getIntVar(s, ce[0]), irt, getIntVar(s, ce[1]),
00312 ann2icl(ann));
00313 } else {
00314 rel(s, getIntVar(s, ce[0]), irt, ce[1]->getInt(), ann2icl(ann));
00315 }
00316 } else {
00317 rel(s, getIntVar(s, ce[1]), swap(irt), ce[0]->getInt(),
00318 ann2icl(ann));
00319 }
00320 }
00321 void p_int_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00322 p_int_CMP(s, IRT_EQ, ce, ann);
00323 }
00324 void p_int_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00325 p_int_CMP(s, IRT_NQ, ce, ann);
00326 }
00327 void p_int_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00328 p_int_CMP(s, IRT_GQ, ce, ann);
00329 }
00330 void p_int_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00331 p_int_CMP(s, IRT_GR, ce, ann);
00332 }
00333 void p_int_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00334 p_int_CMP(s, IRT_LQ, ce, ann);
00335 }
00336 void p_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00337 p_int_CMP(s, IRT_LE, ce, ann);
00338 }
00339 void p_int_CMP_reif(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00340 AST::Node* ann) {
00341 if (ce[2]->isBool()) {
00342 if (ce[2]->getBool()) {
00343 p_int_CMP(s, irt, ce, ann);
00344 } else {
00345 p_int_CMP(s, neg(irt), ce, ann);
00346 }
00347 return;
00348 }
00349 if (ce[0]->isIntVar()) {
00350 if (ce[1]->isIntVar()) {
00351 rel(s, getIntVar(s, ce[0]), irt, getIntVar(s, ce[1]),
00352 getBoolVar(s, ce[2]), ann2icl(ann));
00353 } else {
00354 rel(s, getIntVar(s, ce[0]), irt, ce[1]->getInt(),
00355 getBoolVar(s, ce[2]), ann2icl(ann));
00356 }
00357 } else {
00358 rel(s, getIntVar(s, ce[1]), swap(irt), ce[0]->getInt(),
00359 getBoolVar(s, ce[2]), ann2icl(ann));
00360 }
00361 }
00362
00363
00364 void p_int_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00365 p_int_CMP_reif(s, IRT_EQ, ce, ann);
00366 }
00367 void p_int_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00368 p_int_CMP_reif(s, IRT_NQ, ce, ann);
00369 }
00370 void p_int_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00371 p_int_CMP_reif(s, IRT_GQ, ce, ann);
00372 }
00373 void p_int_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00374 p_int_CMP_reif(s, IRT_GR, ce, ann);
00375 }
00376 void p_int_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00377 p_int_CMP_reif(s, IRT_LQ, ce, ann);
00378 }
00379 void p_int_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00380 p_int_CMP_reif(s, IRT_LE, ce, ann);
00381 }
00382
00383
00384 void p_int_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00385 AST::Node* ann) {
00386 IntArgs ia = arg2intargs(ce[0]);
00387 int singleIntVar;
00388 if (isBoolArray(s,ce[1],singleIntVar)) {
00389 if (singleIntVar != -1) {
00390 if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
00391 IntVar siv = getIntVar(s, ce[1]->getArray()->a[singleIntVar]);
00392 BoolVarArgs iv = arg2boolvarargs(s, ce[1], 0, singleIntVar);
00393 IntArgs ia_tmp(ia.size()-1);
00394 int count = 0;
00395 for (int i=0; i<ia.size(); i++) {
00396 if (i != singleIntVar)
00397 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
00398 }
00399 IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
00400 linear(s, ia_tmp, iv, t, siv, ann2icl(ann));
00401 } else {
00402 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00403 linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00404 }
00405 } else {
00406 BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00407 linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00408 }
00409 } else {
00410 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00411 linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00412 }
00413 }
00414 void p_int_lin_CMP_reif(FlatZincSpace& s, IntRelType irt,
00415 const ConExpr& ce, AST::Node* ann) {
00416 if (ce[2]->isBool()) {
00417 if (ce[2]->getBool()) {
00418 p_int_lin_CMP(s, irt, ce, ann);
00419 } else {
00420 p_int_lin_CMP(s, neg(irt), ce, ann);
00421 }
00422 return;
00423 }
00424 IntArgs ia = arg2intargs(ce[0]);
00425 int singleIntVar;
00426 if (isBoolArray(s,ce[1],singleIntVar)) {
00427 if (singleIntVar != -1) {
00428 if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
00429 IntVar siv = getIntVar(s, ce[1]->getArray()->a[singleIntVar]);
00430 BoolVarArgs iv = arg2boolvarargs(s, ce[1], 0, singleIntVar);
00431 IntArgs ia_tmp(ia.size()-1);
00432 int count = 0;
00433 for (int i=0; i<ia.size(); i++) {
00434 if (i != singleIntVar)
00435 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
00436 }
00437 IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
00438 linear(s, ia_tmp, iv, t, siv, getBoolVar(s, ce[3]),
00439 ann2icl(ann));
00440 } else {
00441 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00442 linear(s, ia, iv, irt, ce[2]->getInt(),
00443 getBoolVar(s, ce[3]), ann2icl(ann));
00444 }
00445 } else {
00446 BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00447 linear(s, ia, iv, irt, ce[2]->getInt(),
00448 getBoolVar(s, ce[3]), ann2icl(ann));
00449 }
00450 } else {
00451 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00452 linear(s, ia, iv, irt, ce[2]->getInt(), getBoolVar(s, ce[3]),
00453 ann2icl(ann));
00454 }
00455 }
00456 void p_int_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00457 p_int_lin_CMP(s, IRT_EQ, ce, ann);
00458 }
00459 void p_int_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00460 p_int_lin_CMP_reif(s, IRT_EQ, ce, ann);
00461 }
00462 void p_int_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00463 p_int_lin_CMP(s, IRT_NQ, ce, ann);
00464 }
00465 void p_int_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00466 p_int_lin_CMP_reif(s, IRT_NQ, ce, ann);
00467 }
00468 void p_int_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00469 p_int_lin_CMP(s, IRT_LQ, ce, ann);
00470 }
00471 void p_int_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00472 p_int_lin_CMP_reif(s, IRT_LQ, ce, ann);
00473 }
00474 void p_int_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00475 p_int_lin_CMP(s, IRT_LE, ce, ann);
00476 }
00477 void p_int_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00478 p_int_lin_CMP_reif(s, IRT_LE, ce, ann);
00479 }
00480 void p_int_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00481 p_int_lin_CMP(s, IRT_GQ, ce, ann);
00482 }
00483 void p_int_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00484 p_int_lin_CMP_reif(s, IRT_GQ, ce, ann);
00485 }
00486 void p_int_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00487 p_int_lin_CMP(s, IRT_GR, ce, ann);
00488 }
00489 void p_int_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00490 p_int_lin_CMP_reif(s, IRT_GR, ce, ann);
00491 }
00492
00493 void p_bool_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00494 AST::Node* ann) {
00495 IntArgs ia = arg2intargs(ce[0]);
00496 BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00497 if (ce[2]->isIntVar())
00498 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], ann2icl(ann));
00499 else
00500 linear(s, ia, iv, irt, ce[2]->getInt(), ann2icl(ann));
00501 }
00502 void p_bool_lin_CMP_reif(FlatZincSpace& s, IntRelType irt,
00503 const ConExpr& ce, AST::Node* ann) {
00504 if (ce[2]->isBool()) {
00505 if (ce[2]->getBool()) {
00506 p_bool_lin_CMP(s, irt, ce, ann);
00507 } else {
00508 p_bool_lin_CMP(s, neg(irt), ce, ann);
00509 }
00510 return;
00511 }
00512 IntArgs ia = arg2intargs(ce[0]);
00513 BoolVarArgs iv = arg2boolvarargs(s, ce[1]);
00514 if (ce[2]->isIntVar())
00515 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], getBoolVar(s, ce[3]),
00516 ann2icl(ann));
00517 else
00518 linear(s, ia, iv, irt, ce[2]->getInt(), getBoolVar(s, ce[3]),
00519 ann2icl(ann));
00520 }
00521 void p_bool_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00522 p_bool_lin_CMP(s, IRT_EQ, ce, ann);
00523 }
00524 void p_bool_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00525 {
00526 p_bool_lin_CMP_reif(s, IRT_EQ, ce, ann);
00527 }
00528 void p_bool_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00529 p_bool_lin_CMP(s, IRT_NQ, ce, ann);
00530 }
00531 void p_bool_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00532 {
00533 p_bool_lin_CMP_reif(s, IRT_NQ, ce, ann);
00534 }
00535 void p_bool_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00536 p_bool_lin_CMP(s, IRT_LQ, ce, ann);
00537 }
00538 void p_bool_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00539 {
00540 p_bool_lin_CMP_reif(s, IRT_LQ, ce, ann);
00541 }
00542 void p_bool_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00543 {
00544 p_bool_lin_CMP(s, IRT_LE, ce, ann);
00545 }
00546 void p_bool_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00547 {
00548 p_bool_lin_CMP_reif(s, IRT_LE, ce, ann);
00549 }
00550 void p_bool_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00551 p_bool_lin_CMP(s, IRT_GQ, ce, ann);
00552 }
00553 void p_bool_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00554 {
00555 p_bool_lin_CMP_reif(s, IRT_GQ, ce, ann);
00556 }
00557 void p_bool_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00558 p_bool_lin_CMP(s, IRT_GR, ce, ann);
00559 }
00560 void p_bool_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00561 {
00562 p_bool_lin_CMP_reif(s, IRT_GR, ce, ann);
00563 }
00564
00565
00566
00567 void p_int_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00568 if (!ce[0]->isIntVar()) {
00569 rel(s, ce[0]->getInt() + getIntVar(s, ce[1])
00570 == getIntVar(s,ce[2]), ann2icl(ann));
00571 } else if (!ce[1]->isIntVar()) {
00572 rel(s, getIntVar(s,ce[0]) + ce[1]->getInt()
00573 == getIntVar(s,ce[2]), ann2icl(ann));
00574 } else if (!ce[2]->isIntVar()) {
00575 rel(s, getIntVar(s,ce[0]) + getIntVar(s,ce[1])
00576 == ce[2]->getInt(), ann2icl(ann));
00577 } else {
00578 rel(s, getIntVar(s,ce[0]) + getIntVar(s,ce[1])
00579 == getIntVar(s,ce[2]), ann2icl(ann));
00580 }
00581 }
00582
00583 void p_int_minus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00584 if (!ce[0]->isIntVar()) {
00585 rel(s, ce[0]->getInt() - getIntVar(s, ce[1])
00586 == getIntVar(s,ce[2]), ann2icl(ann));
00587 } else if (!ce[1]->isIntVar()) {
00588 rel(s, getIntVar(s,ce[0]) - ce[1]->getInt()
00589 == getIntVar(s,ce[2]), ann2icl(ann));
00590 } else if (!ce[2]->isIntVar()) {
00591 rel(s, getIntVar(s,ce[0]) - getIntVar(s,ce[1])
00592 == ce[2]->getInt(), ann2icl(ann));
00593 } else {
00594 rel(s, getIntVar(s,ce[0]) - getIntVar(s,ce[1])
00595 == getIntVar(s,ce[2]), ann2icl(ann));
00596 }
00597 }
00598
00599 void p_int_times(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00600 IntVar x0 = getIntVar(s, ce[0]);
00601 IntVar x1 = getIntVar(s, ce[1]);
00602 IntVar x2 = getIntVar(s, ce[2]);
00603 mult(s, x0, x1, x2, ann2icl(ann));
00604 }
00605 void p_int_div(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00606 IntVar x0 = getIntVar(s, ce[0]);
00607 IntVar x1 = getIntVar(s, ce[1]);
00608 IntVar x2 = getIntVar(s, ce[2]);
00609 div(s,x0,x1,x2, ann2icl(ann));
00610 }
00611 void p_int_mod(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00612 IntVar x0 = getIntVar(s, ce[0]);
00613 IntVar x1 = getIntVar(s, ce[1]);
00614 IntVar x2 = getIntVar(s, ce[2]);
00615 mod(s,x0,x1,x2, ann2icl(ann));
00616 }
00617
00618 void p_int_min(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00619 IntVar x0 = getIntVar(s, ce[0]);
00620 IntVar x1 = getIntVar(s, ce[1]);
00621 IntVar x2 = getIntVar(s, ce[2]);
00622 min(s, x0, x1, x2, ann2icl(ann));
00623 }
00624 void p_int_max(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00625 IntVar x0 = getIntVar(s, ce[0]);
00626 IntVar x1 = getIntVar(s, ce[1]);
00627 IntVar x2 = getIntVar(s, ce[2]);
00628 max(s, x0, x1, x2, ann2icl(ann));
00629 }
00630 void p_int_negate(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00631 IntVar x0 = getIntVar(s, ce[0]);
00632 IntVar x1 = getIntVar(s, ce[1]);
00633 rel(s, x0 == -x1, ann2icl(ann));
00634 }
00635
00636
00637 void p_bool_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00638 AST::Node* ann) {
00639 rel(s, getBoolVar(s, ce[0]), irt, getBoolVar(s, ce[1]),
00640 ann2icl(ann));
00641 }
00642 void p_bool_CMP_reif(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00643 AST::Node* ann) {
00644 rel(s, getBoolVar(s, ce[0]), irt, getBoolVar(s, ce[1]),
00645 getBoolVar(s, ce[2]), ann2icl(ann));
00646 }
00647 void p_bool_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00648 p_bool_CMP(s, IRT_EQ, ce, ann);
00649 }
00650 void p_bool_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00651 p_bool_CMP_reif(s, IRT_EQ, ce, ann);
00652 }
00653 void p_bool_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00654 p_bool_CMP(s, IRT_NQ, ce, ann);
00655 }
00656 void p_bool_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00657 p_bool_CMP_reif(s, IRT_NQ, ce, ann);
00658 }
00659 void p_bool_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00660 p_bool_CMP(s, IRT_GQ, ce, ann);
00661 }
00662 void p_bool_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00663 p_bool_CMP_reif(s, IRT_GQ, ce, ann);
00664 }
00665 void p_bool_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00666 p_bool_CMP(s, IRT_LQ, ce, ann);
00667 }
00668 void p_bool_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00669 p_bool_CMP_reif(s, IRT_LQ, ce, ann);
00670 }
00671 void p_bool_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00672 p_bool_CMP(s, IRT_GR, ce, ann);
00673 }
00674 void p_bool_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00675 p_bool_CMP_reif(s, IRT_GR, ce, ann);
00676 }
00677 void p_bool_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00678 p_bool_CMP(s, IRT_LE, ce, ann);
00679 }
00680 void p_bool_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00681 p_bool_CMP_reif(s, IRT_LE, ce, ann);
00682 }
00683
00684 #define BOOL_OP(op) \
00685 BoolVar b0 = getBoolVar(s, ce[0]); \
00686 BoolVar b1 = getBoolVar(s, ce[1]); \
00687 if (ce[2]->isBool()) { \
00688 rel(s, b0, op, b1, ce[2]->getBool(), ann2icl(ann)); \
00689 } else { \
00690 rel(s, b0, op, b1, s.bv[ce[2]->getBoolVar()], ann2icl(ann)); \
00691 }
00692
00693 #define BOOL_ARRAY_OP(op) \
00694 BoolVarArgs bv = arg2boolvarargs(s, ce[0]); \
00695 if (ce.size()==1) { \
00696 rel(s, op, bv, 1, ann2icl(ann)); \
00697 } else if (ce[1]->isBool()) { \
00698 rel(s, op, bv, ce[1]->getBool(), ann2icl(ann)); \
00699 } else { \
00700 rel(s, op, bv, s.bv[ce[1]->getBoolVar()], ann2icl(ann)); \
00701 }
00702
00703 void p_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00704 BOOL_OP(BOT_OR);
00705 }
00706 void p_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00707 BOOL_OP(BOT_AND);
00708 }
00709 void p_array_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00710 {
00711 BOOL_ARRAY_OP(BOT_AND);
00712 }
00713 void p_array_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00714 {
00715 BOOL_ARRAY_OP(BOT_OR);
00716 }
00717 void p_array_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00718 {
00719 BOOL_ARRAY_OP(BOT_XOR);
00720 }
00721 void p_array_bool_clause(FlatZincSpace& s, const ConExpr& ce,
00722 AST::Node* ann) {
00723 BoolVarArgs bvp = arg2boolvarargs(s, ce[0]);
00724 BoolVarArgs bvn = arg2boolvarargs(s, ce[1]);
00725 clause(s, BOT_OR, bvp, bvn, 1, ann2icl(ann));
00726 }
00727 void p_array_bool_clause_reif(FlatZincSpace& s, const ConExpr& ce,
00728 AST::Node* ann) {
00729 BoolVarArgs bvp = arg2boolvarargs(s, ce[0]);
00730 BoolVarArgs bvn = arg2boolvarargs(s, ce[1]);
00731 BoolVar b0 = getBoolVar(s, ce[2]);
00732 clause(s, BOT_OR, bvp, bvn, b0, ann2icl(ann));
00733 }
00734 void p_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00735 BOOL_OP(BOT_XOR);
00736 }
00737 void p_bool_l_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00738 BoolVar b0 = getBoolVar(s, ce[0]);
00739 BoolVar b1 = getBoolVar(s, ce[1]);
00740 if (ce[2]->isBool()) {
00741 rel(s, b1, BOT_IMP, b0, ce[2]->getBool(), ann2icl(ann));
00742 } else {
00743 rel(s, b1, BOT_IMP, b0, s.bv[ce[2]->getBoolVar()], ann2icl(ann));
00744 }
00745 }
00746 void p_bool_r_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00747 BOOL_OP(BOT_IMP);
00748 }
00749 void p_bool_not(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00750 BoolVar x0 = getBoolVar(s, ce[0]);
00751 BoolVar x1 = getBoolVar(s, ce[1]);
00752 rel(s, x0, BOT_XOR, x1, 1, ann2icl(ann));
00753 }
00754
00755
00756 void p_array_int_element(FlatZincSpace& s, const ConExpr& ce,
00757 AST::Node* ann) {
00758 bool isConstant = true;
00759 AST::Array* a = ce[1]->getArray();
00760 for (int i=a->a.size(); i--;) {
00761 if (!a->a[i]->isInt()) {
00762 isConstant = false;
00763 break;
00764 }
00765 }
00766 IntVar selector = getIntVar(s, ce[0]);
00767 rel(s, selector > 0);
00768 if (isConstant) {
00769 IntArgs ia = arg2intargs(ce[1], 1);
00770 element(s, ia, selector, getIntVar(s, ce[2]), ann2icl(ann));
00771 } else {
00772 IntVarArgs iv = arg2intvarargs(s, ce[1], 1);
00773 element(s, iv, selector, getIntVar(s, ce[2]), ann2icl(ann));
00774 }
00775 }
00776 void p_array_bool_element(FlatZincSpace& s, const ConExpr& ce,
00777 AST::Node* ann) {
00778 bool isConstant = true;
00779 AST::Array* a = ce[1]->getArray();
00780 for (int i=a->a.size(); i--;) {
00781 if (!a->a[i]->isBool()) {
00782 isConstant = false;
00783 break;
00784 }
00785 }
00786 IntVar selector = getIntVar(s, ce[0]);
00787 rel(s, selector > 0);
00788 if (isConstant) {
00789 IntArgs ia = arg2boolargs(ce[1], 1);
00790 element(s, ia, selector, getBoolVar(s, ce[2]), ann2icl(ann));
00791 } else {
00792 BoolVarArgs iv = arg2boolvarargs(s, ce[1], 1);
00793 element(s, iv, selector, getBoolVar(s, ce[2]), ann2icl(ann));
00794 }
00795 }
00796
00797
00798 void p_bool2int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00799 BoolVar x0 = getBoolVar(s, ce[0]);
00800 IntVar x1 = getIntVar(s, ce[1]);
00801 if (ce[0]->isBoolVar() && ce[1]->isIntVar()) {
00802 s.aliasBool2Int(ce[1]->getIntVar(), ce[0]->getBoolVar());
00803 }
00804 channel(s, x0, x1, ann2icl(ann));
00805 }
00806
00807 void p_int_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
00808 IntSet d = arg2intset(s,ce[1]);
00809 if (ce[0]->isBoolVar()) {
00810 IntSetRanges dr(d);
00811 Iter::Ranges::Singleton sr(0,1);
00812 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
00813 IntSet d01(i);
00814 if (d01.size() == 0) {
00815 s.fail();
00816 } else {
00817 rel(s, getBoolVar(s, ce[0]), IRT_GQ, d01.min());
00818 rel(s, getBoolVar(s, ce[0]), IRT_LQ, d01.max());
00819 }
00820 } else {
00821 dom(s, getIntVar(s, ce[0]), d);
00822 }
00823 }
00824 void p_int_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
00825 IntSet d = arg2intset(s,ce[1]);
00826 if (ce[0]->isBoolVar()) {
00827 IntSetRanges dr(d);
00828 Iter::Ranges::Singleton sr(0,1);
00829 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
00830 IntSet d01(i);
00831 if (d01.size() == 0) {
00832 rel(s, getBoolVar(s, ce[2]) == 0);
00833 } else if (d01.max() == 0) {
00834 rel(s, getBoolVar(s, ce[2]) == !getBoolVar(s, ce[0]));
00835 } else if (d01.min() == 1) {
00836 rel(s, getBoolVar(s, ce[2]) == getBoolVar(s, ce[0]));
00837 } else {
00838 rel(s, getBoolVar(s, ce[2]) == 1);
00839 }
00840 } else {
00841 std::cerr << "in_in_reif("<<getIntVar(s, ce[0])<<","<<d<<","<<getBoolVar(s, ce[2])<<")\n";
00842 dom(s, getIntVar(s, ce[0]), d, getBoolVar(s, ce[2]));
00843 }
00844 }
00845
00846
00847
00848 void p_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00849 IntVar x0 = getIntVar(s, ce[0]);
00850 IntVar x1 = getIntVar(s, ce[1]);
00851 abs(s, x0, x1, ann2icl(ann));
00852 }
00853
00854 void p_array_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00855 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00856 IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00857 rel(s, iv0, IRT_LE, iv1, ann2icl(ann));
00858 }
00859
00860 void p_array_int_lq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00861 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00862 IntVarArgs iv1 = arg2intvarargs(s, ce[1]);
00863 rel(s, iv0, IRT_LQ, iv1, ann2icl(ann));
00864 }
00865
00866 void p_count(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00867 IntVarArgs iv = arg2intvarargs(s, ce[0]);
00868 if (!ce[1]->isIntVar()) {
00869 if (!ce[2]->isIntVar()) {
00870 count(s, iv, ce[1]->getInt(), IRT_EQ, ce[2]->getInt(),
00871 ann2icl(ann));
00872 } else {
00873 count(s, iv, ce[1]->getInt(), IRT_EQ, getIntVar(s, ce[2]),
00874 ann2icl(ann));
00875 }
00876 } else if (!ce[2]->isIntVar()) {
00877 count(s, iv, getIntVar(s, ce[1]), IRT_EQ, ce[2]->getInt(),
00878 ann2icl(ann));
00879 } else {
00880 count(s, iv, getIntVar(s, ce[1]), IRT_EQ, getIntVar(s, ce[2]),
00881 ann2icl(ann));
00882 }
00883 }
00884
00885 void count_rel(IntRelType irt,
00886 FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00887 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00888 count(s, iv, ce[2]->getInt(), irt, ce[0]->getInt(), ann2icl(ann));
00889 }
00890
00891 void p_at_most(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00892 count_rel(IRT_LQ, s, ce, ann);
00893 }
00894
00895 void p_at_least(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00896 count_rel(IRT_GQ, s, ce, ann);
00897 }
00898
00899 void p_bin_packing_load(FlatZincSpace& s, const ConExpr& ce,
00900 AST::Node* ann) {
00901 int minIdx = ce[3]->getInt();
00902 IntVarArgs load = arg2intvarargs(s, ce[0]);
00903 IntVarArgs l;
00904 IntVarArgs bin = arg2intvarargs(s, ce[1]);
00905 for (int i=bin.size(); i--;)
00906 rel(s, bin[i] >= minIdx);
00907 if (minIdx > 0) {
00908 for (int i=minIdx; i--;)
00909 l << IntVar(s,0,0);
00910 } else if (minIdx < 0) {
00911 IntVarArgs bin2(bin.size());
00912 for (int i=bin.size(); i--;)
00913 bin2[i] = expr(s, bin[i]-minIdx, ann2icl(ann));
00914 bin = bin2;
00915 }
00916 l << load;
00917 IntArgs sizes = arg2intargs(ce[2]);
00918 binpacking(s, l, bin, sizes, ann2icl(ann));
00919 }
00920
00921 void p_global_cardinality(FlatZincSpace& s, const ConExpr& ce,
00922 AST::Node* ann) {
00923 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00924 IntArgs cover = arg2intargs(ce[1]);
00925 IntVarArgs iv1 = arg2intvarargs(s, ce[2]);
00926
00927 Region re(s);
00928 IntSet cover_s(cover);
00929 IntSetRanges cover_r(cover_s);
00930 IntVarRanges* iv0_ri = re.alloc<IntVarRanges>(iv0.size());
00931 for (int i=iv0.size(); i--;)
00932 iv0_ri[i] = IntVarRanges(iv0[i]);
00933 Iter::Ranges::NaryUnion iv0_r(re,iv0_ri,iv0.size());
00934 Iter::Ranges::Diff<Iter::Ranges::NaryUnion,IntSetRanges>
00935 extra_r(iv0_r,cover_r);
00936 Iter::Ranges::ToValues<Iter::Ranges::Diff<
00937 Iter::Ranges::NaryUnion,IntSetRanges> > extra(extra_r);
00938 for (; extra(); ++extra) {
00939 cover << extra.val();
00940 iv1 << IntVar(s,0,iv0.size());
00941 }
00942 count(s, iv0, iv1, cover, ann2icl(ann));
00943 }
00944
00945 void p_global_cardinality_closed(FlatZincSpace& s, const ConExpr& ce,
00946 AST::Node* ann) {
00947 IntVarArgs iv0 = arg2intvarargs(s, ce[0]);
00948 IntArgs cover = arg2intargs(ce[1]);
00949 IntVarArgs iv1 = arg2intvarargs(s, ce[2]);
00950 count(s, iv0, iv1, cover, ann2icl(ann));
00951 }
00952
00953 void p_global_cardinality_low_up(FlatZincSpace& s, const ConExpr& ce,
00954 AST::Node* ann) {
00955 IntVarArgs x = arg2intvarargs(s, ce[0]);
00956 IntArgs cover = arg2intargs(ce[1]);
00957
00958 IntArgs lbound = arg2intargs(ce[2]);
00959 IntArgs ubound = arg2intargs(ce[3]);
00960 IntSetArgs y(cover.size());
00961 for (int i=cover.size(); i--;)
00962 y[i] = IntSet(lbound[i],ubound[i]);
00963
00964 IntSet cover_s(cover);
00965 Region re(s);
00966 IntVarRanges* xrs = re.alloc<IntVarRanges>(x.size());
00967 for (int i=x.size(); i--;)
00968 xrs[i].init(x[i]);
00969 Iter::Ranges::NaryUnion u(re, xrs, x.size());
00970 Iter::Ranges::ToValues<Iter::Ranges::NaryUnion> uv(u);
00971 for (; uv(); ++uv) {
00972 if (!cover_s.in(uv.val())) {
00973 cover << uv.val();
00974 y << IntSet(0,x.size());
00975 }
00976 }
00977
00978 count(s, x, y, cover, ann2icl(ann));
00979 }
00980
00981 void p_global_cardinality_low_up_closed(FlatZincSpace& s,
00982 const ConExpr& ce,
00983 AST::Node* ann) {
00984 IntVarArgs x = arg2intvarargs(s, ce[0]);
00985 IntArgs cover = arg2intargs(ce[1]);
00986
00987 IntArgs lbound = arg2intargs(ce[2]);
00988 IntArgs ubound = arg2intargs(ce[3]);
00989 IntSetArgs y(cover.size());
00990 for (int i=cover.size(); i--;)
00991 y[i] = IntSet(lbound[i],ubound[i]);
00992
00993 count(s, x, y, cover, ann2icl(ann));
00994 }
00995
00996 void p_minimum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00997 IntVarArgs iv = arg2intvarargs(s, ce[1]);
00998 min(s, iv, getIntVar(s, ce[0]), ann2icl(ann));
00999 }
01000
01001 void p_maximum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01002 IntVarArgs iv = arg2intvarargs(s, ce[1]);
01003 max(s, iv, getIntVar(s, ce[0]), ann2icl(ann));
01004 }
01005
01006 void p_regular(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01007 IntVarArgs iv = arg2intvarargs(s, ce[0]);
01008 int q = ce[1]->getInt();
01009 int symbols = ce[2]->getInt();
01010 IntArgs d = arg2intargs(ce[3]);
01011 int q0 = ce[4]->getInt();
01012
01013 int noOfTrans = 0;
01014 for (int i=1; i<=q; i++) {
01015 for (int j=1; j<=symbols; j++) {
01016 if (d[(i-1)*symbols+(j-1)] > 0)
01017 noOfTrans++;
01018 }
01019 }
01020
01021 Region re(s);
01022 DFA::Transition* t = re.alloc<DFA::Transition>(noOfTrans+1);
01023 noOfTrans = 0;
01024 for (int i=1; i<=q; i++) {
01025 for (int j=1; j<=symbols; j++) {
01026 if (d[(i-1)*symbols+(j-1)] > 0) {
01027 t[noOfTrans].i_state = i;
01028 t[noOfTrans].symbol = j;
01029 t[noOfTrans].o_state = d[(i-1)*symbols+(j-1)];
01030 noOfTrans++;
01031 }
01032 }
01033 }
01034 t[noOfTrans].i_state = -1;
01035
01036
01037 AST::SetLit* sl = ce[5]->getSet();
01038 int* f;
01039 if (sl->interval) {
01040 f = static_cast<int*>(malloc(sizeof(int)*(sl->max-sl->min+2)));
01041 for (int i=sl->min; i<=sl->max; i++)
01042 f[i-sl->min] = i;
01043 f[sl->max-sl->min+1] = -1;
01044 } else {
01045 f = static_cast<int*>(malloc(sizeof(int)*(sl->s.size()+1)));
01046 for (int j=sl->s.size(); j--; )
01047 f[j] = sl->s[j];
01048 f[sl->s.size()] = -1;
01049 }
01050
01051 DFA dfa(q0,t,f);
01052 free(f);
01053 extensional(s, iv, dfa, ann2icl(ann));
01054 }
01055
01056 void
01057 p_sort(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01058 IntVarArgs x = arg2intvarargs(s, ce[0]);
01059 IntVarArgs y = arg2intvarargs(s, ce[1]);
01060 IntVarArgs xy(x.size()+y.size());
01061 for (int i=x.size(); i--;)
01062 xy[i] = x[i];
01063 for (int i=y.size(); i--;)
01064 xy[i+x.size()] = y[i];
01065 unshare(s, xy);
01066 for (int i=x.size(); i--;)
01067 x[i] = xy[i];
01068 for (int i=y.size(); i--;)
01069 y[i] = xy[i+x.size()];
01070 sorted(s, x, y, ann2icl(ann));
01071 }
01072
01073 void
01074 p_inverse_offsets(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01075 IntVarArgs x = arg2intvarargs(s, ce[0]);
01076 int xoff = ce[1]->getInt();
01077 IntVarArgs y = arg2intvarargs(s, ce[2]);
01078 int yoff = ce[3]->getInt();
01079 channel(s, x, xoff, y, yoff, ann2icl(ann));
01080 }
01081
01082 void
01083 p_increasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01084 IntVarArgs x = arg2intvarargs(s, ce[0]);
01085 rel(s,x,IRT_LQ,ann2icl(ann));
01086 }
01087
01088 void
01089 p_increasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01090 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01091 rel(s,x,IRT_LQ,ann2icl(ann));
01092 }
01093
01094 void
01095 p_decreasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01096 IntVarArgs x = arg2intvarargs(s, ce[0]);
01097 rel(s,x,IRT_GQ,ann2icl(ann));
01098 }
01099
01100 void
01101 p_decreasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01102 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01103 rel(s,x,IRT_GQ,ann2icl(ann));
01104 }
01105
01106 void
01107 p_table_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01108 IntVarArgs x = arg2intvarargs(s, ce[0]);
01109 IntArgs tuples = arg2intargs(ce[1]);
01110 int noOfVars = x.size();
01111 int noOfTuples = tuples.size()/noOfVars;
01112 TupleSet ts;
01113 for (int i=0; i<noOfTuples; i++) {
01114 IntArgs t(noOfVars);
01115 for (int j=0; j<x.size(); j++) {
01116 t[j] = tuples[i*noOfVars+j];
01117 }
01118 ts.add(t);
01119 }
01120 ts.finalize();
01121 extensional(s,x,ts,EPK_DEF,ann2icl(ann));
01122 }
01123 void
01124 p_table_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01125 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01126 IntArgs tuples = arg2boolargs(ce[1]);
01127 int noOfVars = x.size();
01128 int noOfTuples = tuples.size()/noOfVars;
01129 TupleSet ts;
01130 for (int i=0; i<noOfTuples; i++) {
01131 IntArgs t(noOfVars);
01132 for (int j=0; j<x.size(); j++) {
01133 t[j] = tuples[i*noOfVars+j];
01134 }
01135 ts.add(t);
01136 }
01137 ts.finalize();
01138 extensional(s,x,ts,EPK_DEF,ann2icl(ann));
01139 }
01140
01141 void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
01142 AST::Node* ann) {
01143 IntVarArgs start = arg2intvarargs(s, ce[0]);
01144 IntVarArgs duration = arg2intvarargs(s, ce[1]);
01145 IntVarArgs height = arg2intvarargs(s, ce[2]);
01146 int n = start.size();
01147 IntVar bound = getIntVar(s, ce[3]);
01148
01149 int minHeight = INT_MAX; int minHeight2 = INT_MAX;
01150 for (int i=n; i--;)
01151 if (height[i].min() < minHeight)
01152 minHeight = height[i].min();
01153 else if (height[i].min() < minHeight2)
01154 minHeight2 = height[i].min();
01155 bool disjunctive =
01156 (minHeight > bound.max()/2) ||
01157 (minHeight2 > bound.max()/2 && minHeight+minHeight2>bound.max());
01158 if (disjunctive) {
01159 rel(s, bound >= max(height));
01160
01161 if (duration.assigned()) {
01162 IntArgs durationI(n);
01163 for (int i=n; i--;)
01164 durationI[i] = duration[i].val();
01165 unary(s,start,durationI);
01166 } else {
01167 IntVarArgs end(n);
01168 for (int i=n; i--;)
01169 end[i] = expr(s,start[i]+duration[i]);
01170 unary(s,start,duration,end);
01171 }
01172 } else if (height.assigned()) {
01173 IntArgs heightI(n);
01174 for (int i=n; i--;)
01175 heightI[i] = height[i].val();
01176 if (duration.assigned()) {
01177 IntArgs durationI(n);
01178 for (int i=n; i--;)
01179 durationI[i] = duration[i].val();
01180 cumulative(s, bound, start, durationI, heightI);
01181 } else {
01182 IntVarArgs end(n);
01183 for (int i = n; i--; )
01184 end[i] = expr(s,start[i]+duration[i]);
01185 cumulative(s, bound, start, duration, end, heightI);
01186 }
01187 } else if (bound.assigned()) {
01188 IntArgs machine = IntArgs::create(n,0,0);
01189 IntArgs limit(1, bound.val());
01190 IntVarArgs end(n);
01191 for (int i=n; i--;)
01192 end[i] = expr(s,start[i]+duration[i]);
01193 cumulatives(s, machine, start, duration, end, height, limit, true,
01194 ann2icl(ann));
01195 } else {
01196 int min = Gecode::Int::Limits::max;
01197 int max = Gecode::Int::Limits::min;
01198 IntVarArgs end(start.size());
01199 for (int i = start.size(); i--; ) {
01200 min = std::min(min, start[i].min());
01201 max = std::max(max, start[i].max() + duration[i].max());
01202 end[i] = expr(s, start[i] + duration[i]);
01203 }
01204 for (int time = min; time < max; ++time) {
01205 IntVarArgs x(start.size());
01206 for (int i = start.size(); i--; ) {
01207 IntVar overlaps = channel(s, expr(s, (start[i] <= time) &&
01208 (time < end[i])));
01209 x[i] = expr(s, overlaps * height[i]);
01210 }
01211 linear(s, x, IRT_LQ, bound);
01212 }
01213 }
01214 }
01215
01216 void p_among_seq_int(FlatZincSpace& s, const ConExpr& ce,
01217 AST::Node* ann) {
01218 IntVarArgs x = arg2intvarargs(s, ce[0]);
01219 IntSet S = arg2intset(s, ce[1]);
01220 int q = ce[2]->getInt();
01221 int l = ce[3]->getInt();
01222 int u = ce[4]->getInt();
01223 sequence(s, x, S, q, l, u, ann2icl(ann));
01224 }
01225
01226 void p_among_seq_bool(FlatZincSpace& s, const ConExpr& ce,
01227 AST::Node* ann) {
01228 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01229 bool val = ce[1]->getBool();
01230 int q = ce[2]->getInt();
01231 int l = ce[3]->getInt();
01232 int u = ce[4]->getInt();
01233 IntSet S(val, val);
01234 sequence(s, x, S, q, l, u, ann2icl(ann));
01235 }
01236
01237 void p_schedule_unary(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01238 IntVarArgs x = arg2intvarargs(s, ce[0]);
01239 IntArgs p = arg2intargs(ce[1]);
01240 unary(s, x, p);
01241 }
01242
01243 void p_schedule_unary_optional(FlatZincSpace& s, const ConExpr& ce,
01244 AST::Node*) {
01245 IntVarArgs x = arg2intvarargs(s, ce[0]);
01246 IntArgs p = arg2intargs(ce[1]);
01247 BoolVarArgs m = arg2boolvarargs(s, ce[2]);
01248 unary(s, x, p, m);
01249 }
01250
01251 void p_circuit(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01252 IntVarArgs xv = arg2intvarargs(s, ce[0]);
01253 circuit(s,xv,ann2icl(ann));
01254 }
01255 void p_circuit_cost_array(FlatZincSpace& s, const ConExpr& ce,
01256 AST::Node *ann) {
01257 IntArgs c = arg2intargs(ce[0]);
01258 IntVarArgs xv = arg2intvarargs(s, ce[1]);
01259 IntVarArgs yv = arg2intvarargs(s, ce[2]);
01260 IntVar z = getIntVar(s, ce[3]);
01261 circuit(s,c,xv,yv,z,ann2icl(ann));
01262 }
01263 void p_circuit_cost(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01264 IntArgs c = arg2intargs(ce[0]);
01265 IntVarArgs xv = arg2intvarargs(s, ce[1]);
01266 IntVar z = getIntVar(s, ce[2]);
01267 circuit(s,c,xv,z,ann2icl(ann));
01268 }
01269
01270 void p_nooverlap(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01271 IntVarArgs x0 = arg2intvarargs(s, ce[0]);
01272 IntVarArgs w = arg2intvarargs(s, ce[1]);
01273 IntVarArgs y0 = arg2intvarargs(s, ce[2]);
01274 IntVarArgs h = arg2intvarargs(s, ce[3]);
01275 IntVarArgs x1(x0.size()), y1(y0.size());
01276 for (int i=x0.size(); i--; )
01277 x1[i] = expr(s, x0[i] + w[i]);
01278 for (int i=y0.size(); i--; )
01279 y1[i] = expr(s, y0[i] + h[i]);
01280 nooverlap(s,x0,w,x1,y0,h,y1,ann2icl(ann));
01281 }
01282
01283 void p_precede(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01284 IntVarArgs x = arg2intvarargs(s, ce[0]);
01285 IntArgs c = arg2intargs(ce[1]);
01286 precede(s,x,c,ann2icl(ann));
01287 }
01288
01289 void p_nvalue(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01290 IntVarArgs x = arg2intvarargs(s, ce[1]);
01291 if (ce[0]->isIntVar()) {
01292 IntVar y = getIntVar(s,ce[0]);
01293 nvalues(s,x,IRT_EQ,y,ann2icl(ann));
01294 } else {
01295 nvalues(s,x,IRT_EQ,ce[0]->getInt(),ann2icl(ann));
01296 }
01297 }
01298
01299 void p_among(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01300 IntVarArgs x = arg2intvarargs(s, ce[1]);
01301 IntSet v = arg2intset(s, ce[2]);
01302 if (ce[0]->isIntVar()) {
01303 IntVar n = getIntVar(s,ce[0]);
01304 std::cerr << "count " << n << std::endl;
01305 count(s,x,v,IRT_EQ,n,ann2icl(ann));
01306 } else {
01307 std::cerr << "count i " << x << " " << v << " " << ce[0]->getInt() << std::endl;
01308 count(s,x,v,IRT_EQ,ce[0]->getInt(),ann2icl(ann));
01309 }
01310 }
01311
01312 void p_member_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01313 IntVarArgs x = arg2intvarargs(s, ce[0]);
01314 IntVar y = getIntVar(s, ce[1]);
01315 member(s,x,y,ann2icl(ann));
01316 }
01317 void p_member_int_reif(FlatZincSpace& s, const ConExpr& ce,
01318 AST::Node* ann) {
01319 IntVarArgs x = arg2intvarargs(s, ce[0]);
01320 IntVar y = getIntVar(s, ce[1]);
01321 BoolVar b = getBoolVar(s, ce[2]);
01322 member(s,x,y,b,ann2icl(ann));
01323 }
01324 void p_member_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01325 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01326 BoolVar y = getBoolVar(s, ce[1]);
01327 member(s,x,y,ann2icl(ann));
01328 }
01329 void p_member_bool_reif(FlatZincSpace& s, const ConExpr& ce,
01330 AST::Node* ann) {
01331 BoolVarArgs x = arg2boolvarargs(s, ce[0]);
01332 BoolVar y = getBoolVar(s, ce[1]);
01333 member(s,x,y,getBoolVar(s, ce[2]),ann2icl(ann));
01334 }
01335
01336 class IntPoster {
01337 public:
01338 IntPoster(void) {
01339 registry().add("all_different_int", &p_distinct);
01340 registry().add("all_different_offset", &p_distinctOffset);
01341 registry().add("all_equal_int", &p_all_equal);
01342 registry().add("int_eq", &p_int_eq);
01343 registry().add("int_ne", &p_int_ne);
01344 registry().add("int_ge", &p_int_ge);
01345 registry().add("int_gt", &p_int_gt);
01346 registry().add("int_le", &p_int_le);
01347 registry().add("int_lt", &p_int_lt);
01348 registry().add("int_eq_reif", &p_int_eq_reif);
01349 registry().add("int_ne_reif", &p_int_ne_reif);
01350 registry().add("int_ge_reif", &p_int_ge_reif);
01351 registry().add("int_gt_reif", &p_int_gt_reif);
01352 registry().add("int_le_reif", &p_int_le_reif);
01353 registry().add("int_lt_reif", &p_int_lt_reif);
01354 registry().add("int_lin_eq", &p_int_lin_eq);
01355 registry().add("int_lin_eq_reif", &p_int_lin_eq_reif);
01356 registry().add("int_lin_ne", &p_int_lin_ne);
01357 registry().add("int_lin_ne_reif", &p_int_lin_ne_reif);
01358 registry().add("int_lin_le", &p_int_lin_le);
01359 registry().add("int_lin_le_reif", &p_int_lin_le_reif);
01360 registry().add("int_lin_lt", &p_int_lin_lt);
01361 registry().add("int_lin_lt_reif", &p_int_lin_lt_reif);
01362 registry().add("int_lin_ge", &p_int_lin_ge);
01363 registry().add("int_lin_ge_reif", &p_int_lin_ge_reif);
01364 registry().add("int_lin_gt", &p_int_lin_gt);
01365 registry().add("int_lin_gt_reif", &p_int_lin_gt_reif);
01366 registry().add("int_plus", &p_int_plus);
01367 registry().add("int_minus", &p_int_minus);
01368 registry().add("int_times", &p_int_times);
01369 registry().add("int_div", &p_int_div);
01370 registry().add("int_mod", &p_int_mod);
01371 registry().add("int_min", &p_int_min);
01372 registry().add("int_max", &p_int_max);
01373 registry().add("int_abs", &p_abs);
01374 registry().add("int_negate", &p_int_negate);
01375 registry().add("bool_eq", &p_bool_eq);
01376 registry().add("bool_eq_reif", &p_bool_eq_reif);
01377 registry().add("bool_ne", &p_bool_ne);
01378 registry().add("bool_ne_reif", &p_bool_ne_reif);
01379 registry().add("bool_ge", &p_bool_ge);
01380 registry().add("bool_ge_reif", &p_bool_ge_reif);
01381 registry().add("bool_le", &p_bool_le);
01382 registry().add("bool_le_reif", &p_bool_le_reif);
01383 registry().add("bool_gt", &p_bool_gt);
01384 registry().add("bool_gt_reif", &p_bool_gt_reif);
01385 registry().add("bool_lt", &p_bool_lt);
01386 registry().add("bool_lt_reif", &p_bool_lt_reif);
01387 registry().add("bool_or", &p_bool_or);
01388 registry().add("bool_and", &p_bool_and);
01389 registry().add("bool_xor", &p_bool_xor);
01390 registry().add("array_bool_and", &p_array_bool_and);
01391 registry().add("array_bool_or", &p_array_bool_or);
01392 registry().add("array_bool_xor", &p_array_bool_xor);
01393 registry().add("bool_clause", &p_array_bool_clause);
01394 registry().add("bool_clause_reif", &p_array_bool_clause_reif);
01395 registry().add("bool_left_imp", &p_bool_l_imp);
01396 registry().add("bool_right_imp", &p_bool_r_imp);
01397 registry().add("bool_not", &p_bool_not);
01398 registry().add("array_int_element", &p_array_int_element);
01399 registry().add("array_var_int_element", &p_array_int_element);
01400 registry().add("array_bool_element", &p_array_bool_element);
01401 registry().add("array_var_bool_element", &p_array_bool_element);
01402 registry().add("bool2int", &p_bool2int);
01403 registry().add("int_in", &p_int_in);
01404 registry().add("int_in_reif", &p_int_in_reif);
01405 #ifndef GECODE_HAS_SET_VARS
01406 registry().add("set_in", &p_int_in);
01407 registry().add("set_in_reif", &p_int_in_reif);
01408 #endif
01409
01410 registry().add("array_int_lt", &p_array_int_lt);
01411 registry().add("array_int_lq", &p_array_int_lq);
01412 registry().add("count", &p_count);
01413 registry().add("at_least_int", &p_at_least);
01414 registry().add("at_most_int", &p_at_most);
01415 registry().add("gecode_bin_packing_load", &p_bin_packing_load);
01416 registry().add("global_cardinality", &p_global_cardinality);
01417 registry().add("global_cardinality_closed",
01418 &p_global_cardinality_closed);
01419 registry().add("global_cardinality_low_up",
01420 &p_global_cardinality_low_up);
01421 registry().add("global_cardinality_low_up_closed",
01422 &p_global_cardinality_low_up_closed);
01423 registry().add("minimum_int", &p_minimum);
01424 registry().add("maximum_int", &p_maximum);
01425 registry().add("regular", &p_regular);
01426 registry().add("sort", &p_sort);
01427 registry().add("inverse_offsets", &p_inverse_offsets);
01428 registry().add("increasing_int", &p_increasing_int);
01429 registry().add("increasing_bool", &p_increasing_bool);
01430 registry().add("decreasing_int", &p_decreasing_int);
01431 registry().add("decreasing_bool", &p_decreasing_bool);
01432 registry().add("table_int", &p_table_int);
01433 registry().add("table_bool", &p_table_bool);
01434 registry().add("cumulatives", &p_cumulatives);
01435 registry().add("gecode_among_seq_int", &p_among_seq_int);
01436 registry().add("gecode_among_seq_bool", &p_among_seq_bool);
01437
01438 registry().add("bool_lin_eq", &p_bool_lin_eq);
01439 registry().add("bool_lin_ne", &p_bool_lin_ne);
01440 registry().add("bool_lin_le", &p_bool_lin_le);
01441 registry().add("bool_lin_lt", &p_bool_lin_lt);
01442 registry().add("bool_lin_ge", &p_bool_lin_ge);
01443 registry().add("bool_lin_gt", &p_bool_lin_gt);
01444
01445 registry().add("bool_lin_eq_reif", &p_bool_lin_eq_reif);
01446 registry().add("bool_lin_ne_reif", &p_bool_lin_ne_reif);
01447 registry().add("bool_lin_le_reif", &p_bool_lin_le_reif);
01448 registry().add("bool_lin_lt_reif", &p_bool_lin_lt_reif);
01449 registry().add("bool_lin_ge_reif", &p_bool_lin_ge_reif);
01450 registry().add("bool_lin_gt_reif", &p_bool_lin_gt_reif);
01451
01452 registry().add("gecode_schedule_unary", &p_schedule_unary);
01453 registry().add("gecode_schedule_unary_optional", &p_schedule_unary_optional);
01454
01455 registry().add("gecode_circuit", &p_circuit);
01456 registry().add("gecode_circuit_cost_array", &p_circuit_cost_array);
01457 registry().add("gecode_circuit_cost", &p_circuit_cost);
01458 registry().add("gecode_nooverlap", &p_nooverlap);
01459 registry().add("gecode_precede", &p_precede);
01460 registry().add("nvalue",&p_nvalue);
01461 registry().add("among",&p_among);
01462 registry().add("member_int",&p_member_int);
01463 registry().add("gecode_member_int_reif",&p_member_int_reif);
01464 registry().add("member_bool",&p_member_bool);
01465 registry().add("gecode_member_bool_reif",&p_member_bool_reif);
01466 }
01467 };
01468 IntPoster __int_poster;
01469
01470 #ifdef GECODE_HAS_SET_VARS
01471 void p_set_OP(FlatZincSpace& s, SetOpType op,
01472 const ConExpr& ce, AST::Node *) {
01473 rel(s, getSetVar(s, ce[0]), op, getSetVar(s, ce[1]),
01474 SRT_EQ, getSetVar(s, ce[2]));
01475 }
01476 void p_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01477 p_set_OP(s, SOT_UNION, ce, ann);
01478 }
01479 void p_set_intersect(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01480 p_set_OP(s, SOT_INTER, ce, ann);
01481 }
01482 void p_set_diff(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01483 p_set_OP(s, SOT_MINUS, ce, ann);
01484 }
01485
01486 void p_set_symdiff(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01487 SetVar x = getSetVar(s, ce[0]);
01488 SetVar y = getSetVar(s, ce[1]);
01489
01490 SetVarLubRanges xub(x);
01491 IntSet xubs(xub);
01492 SetVar x_y(s,IntSet::empty,xubs);
01493 rel(s, x, SOT_MINUS, y, SRT_EQ, x_y);
01494
01495 SetVarLubRanges yub(y);
01496 IntSet yubs(yub);
01497 SetVar y_x(s,IntSet::empty,yubs);
01498 rel(s, y, SOT_MINUS, x, SRT_EQ, y_x);
01499
01500 rel(s, x_y, SOT_UNION, y_x, SRT_EQ, getSetVar(s, ce[2]));
01501 }
01502
01503 void p_array_set_OP(FlatZincSpace& s, SetOpType op,
01504 const ConExpr& ce, AST::Node *) {
01505 SetVarArgs xs = arg2setvarargs(s, ce[0]);
01506 rel(s, op, xs, getSetVar(s, ce[1]));
01507 }
01508 void p_array_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01509 p_array_set_OP(s, SOT_UNION, ce, ann);
01510 }
01511 void p_array_set_partition(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01512 p_array_set_OP(s, SOT_DUNION, ce, ann);
01513 }
01514
01515
01516 void p_set_rel(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
01517 rel(s, getSetVar(s, ce[0]), srt, getSetVar(s, ce[1]));
01518 }
01519
01520 void p_set_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01521 p_set_rel(s, SRT_EQ, ce);
01522 }
01523 void p_set_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01524 p_set_rel(s, SRT_NQ, ce);
01525 }
01526 void p_set_subset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01527 p_set_rel(s, SRT_SUB, ce);
01528 }
01529 void p_set_superset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01530 p_set_rel(s, SRT_SUP, ce);
01531 }
01532 void p_set_le(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01533 p_set_rel(s, SRT_LQ, ce);
01534 }
01535 void p_set_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01536 p_set_rel(s, SRT_LE, ce);
01537 }
01538 void p_set_card(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01539 if (!ce[1]->isIntVar()) {
01540 cardinality(s, getSetVar(s, ce[0]), ce[1]->getInt(),
01541 ce[1]->getInt());
01542 } else {
01543 cardinality(s, getSetVar(s, ce[0]), getIntVar(s, ce[1]));
01544 }
01545 }
01546 void p_set_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01547 if (!ce[1]->isSetVar()) {
01548 IntSet d = arg2intset(s,ce[1]);
01549 if (ce[0]->isBoolVar()) {
01550 IntSetRanges dr(d);
01551 Iter::Ranges::Singleton sr(0,1);
01552 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01553 IntSet d01(i);
01554 if (d01.size() == 0) {
01555 s.fail();
01556 } else {
01557 rel(s, getBoolVar(s, ce[0]), IRT_GQ, d01.min());
01558 rel(s, getBoolVar(s, ce[0]), IRT_LQ, d01.max());
01559 }
01560 } else {
01561 dom(s, getIntVar(s, ce[0]), d);
01562 }
01563 } else {
01564 if (!ce[0]->isIntVar()) {
01565 dom(s, getSetVar(s, ce[1]), SRT_SUP, ce[0]->getInt());
01566 } else {
01567 rel(s, getSetVar(s, ce[1]), SRT_SUP, getIntVar(s, ce[0]));
01568 }
01569 }
01570 }
01571 void p_set_rel_reif(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
01572 rel(s, getSetVar(s, ce[0]), srt, getSetVar(s, ce[1]),
01573 getBoolVar(s, ce[2]));
01574 }
01575
01576 void p_set_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01577 p_set_rel_reif(s,SRT_EQ,ce);
01578 }
01579 void p_set_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01580 p_set_rel_reif(s,SRT_LQ,ce);
01581 }
01582 void p_set_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01583 p_set_rel_reif(s,SRT_LE,ce);
01584 }
01585 void p_set_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01586 p_set_rel_reif(s,SRT_NQ,ce);
01587 }
01588 void p_set_subset_reif(FlatZincSpace& s, const ConExpr& ce,
01589 AST::Node *) {
01590 p_set_rel_reif(s,SRT_SUB,ce);
01591 }
01592 void p_set_superset_reif(FlatZincSpace& s, const ConExpr& ce,
01593 AST::Node *) {
01594 p_set_rel_reif(s,SRT_SUP,ce);
01595 }
01596 void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01597 if (!ce[1]->isSetVar()) {
01598 IntSet d = arg2intset(s,ce[1]);
01599 if (ce[0]->isBoolVar()) {
01600 IntSetRanges dr(d);
01601 Iter::Ranges::Singleton sr(0,1);
01602 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01603 IntSet d01(i);
01604 if (d01.size() == 0) {
01605 rel(s, getBoolVar(s, ce[2]) == 0);
01606 } else if (d01.max() == 0) {
01607 rel(s, getBoolVar(s, ce[2]) == !getBoolVar(s, ce[0]));
01608 } else if (d01.min() == 1) {
01609 rel(s, getBoolVar(s, ce[2]) == getBoolVar(s, ce[0]));
01610 } else {
01611 rel(s, getBoolVar(s, ce[2]) == 1);
01612 }
01613 } else {
01614 dom(s, getIntVar(s, ce[0]), d, getBoolVar(s, ce[2]));
01615 }
01616 } else {
01617 if (!ce[0]->isIntVar()) {
01618 dom(s, getSetVar(s, ce[1]), SRT_SUP, ce[0]->getInt(),
01619 getBoolVar(s, ce[2]));
01620 } else {
01621 rel(s, getSetVar(s, ce[1]), SRT_SUP, getIntVar(s, ce[0]),
01622 getBoolVar(s, ce[2]));
01623 }
01624 }
01625 }
01626 void p_set_disjoint(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01627 rel(s, getSetVar(s, ce[0]), SRT_DISJ, getSetVar(s, ce[1]));
01628 }
01629
01630 void p_link_set_to_booleans(FlatZincSpace& s, const ConExpr& ce,
01631 AST::Node *) {
01632 SetVar x = getSetVar(s, ce[0]);
01633 int idx = ce[2]->getInt();
01634 assert(idx >= 0);
01635 rel(s, x || IntSet(Set::Limits::min,idx-1));
01636 BoolVarArgs y = arg2boolvarargs(s,ce[1],idx);
01637 channel(s, y, x);
01638 }
01639
01640 void p_array_set_element(FlatZincSpace& s, const ConExpr& ce,
01641 AST::Node*) {
01642 bool isConstant = true;
01643 AST::Array* a = ce[1]->getArray();
01644 for (int i=a->a.size(); i--;) {
01645 if (a->a[i]->isSetVar()) {
01646 isConstant = false;
01647 break;
01648 }
01649 }
01650 IntVar selector = getIntVar(s, ce[0]);
01651 rel(s, selector > 0);
01652 if (isConstant) {
01653 IntSetArgs sv = arg2intsetargs(s,ce[1],1);
01654 element(s, sv, selector, getSetVar(s, ce[2]));
01655 } else {
01656 SetVarArgs sv = arg2setvarargs(s, ce[1], 1);
01657 element(s, sv, selector, getSetVar(s, ce[2]));
01658 }
01659 }
01660
01661 void p_array_set_element_op(FlatZincSpace& s, const ConExpr& ce,
01662 AST::Node*, SetOpType op,
01663 const IntSet& universe =
01664 IntSet(Set::Limits::min,Set::Limits::max)) {
01665 bool isConstant = true;
01666 AST::Array* a = ce[1]->getArray();
01667 for (int i=a->a.size(); i--;) {
01668 if (a->a[i]->isSetVar()) {
01669 isConstant = false;
01670 break;
01671 }
01672 }
01673 SetVar selector = getSetVar(s, ce[0]);
01674 dom(s, selector, SRT_DISJ, 0);
01675 if (isConstant) {
01676 IntSetArgs sv = arg2intsetargs(s,ce[1], 1);
01677 element(s, op, sv, selector, getSetVar(s, ce[2]), universe);
01678 } else {
01679 SetVarArgs sv = arg2setvarargs(s, ce[1], 1);
01680 element(s, op, sv, selector, getSetVar(s, ce[2]), universe);
01681 }
01682 }
01683
01684 void p_array_set_element_union(FlatZincSpace& s, const ConExpr& ce,
01685 AST::Node* ann) {
01686 p_array_set_element_op(s, ce, ann, SOT_UNION);
01687 }
01688
01689 void p_array_set_element_intersect(FlatZincSpace& s, const ConExpr& ce,
01690 AST::Node* ann) {
01691 p_array_set_element_op(s, ce, ann, SOT_INTER);
01692 }
01693
01694 void p_array_set_element_intersect_in(FlatZincSpace& s,
01695 const ConExpr& ce,
01696 AST::Node* ann) {
01697 IntSet d = arg2intset(s, ce[3]);
01698 p_array_set_element_op(s, ce, ann, SOT_INTER, d);
01699 }
01700
01701 void p_array_set_element_partition(FlatZincSpace& s, const ConExpr& ce,
01702 AST::Node* ann) {
01703 p_array_set_element_op(s, ce, ann, SOT_DUNION);
01704 }
01705
01706 void p_set_convex(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01707 convex(s, getSetVar(s, ce[0]));
01708 }
01709
01710 void p_array_set_seq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01711 SetVarArgs sv = arg2setvarargs(s, ce[0]);
01712 sequence(s, sv);
01713 }
01714
01715 void p_array_set_seq_union(FlatZincSpace& s, const ConExpr& ce,
01716 AST::Node *) {
01717 SetVarArgs sv = arg2setvarargs(s, ce[0]);
01718 sequence(s, sv, getSetVar(s, ce[1]));
01719 }
01720
01721 void p_int_set_channel(FlatZincSpace& s, const ConExpr& ce,
01722 AST::Node *) {
01723 int xoff=ce[1]->getInt();
01724 assert(xoff >= 0);
01725 int yoff=ce[3]->getInt();
01726 assert(yoff >= 0);
01727 IntVarArgs xv = arg2intvarargs(s, ce[0], xoff);
01728 SetVarArgs yv = arg2setvarargs(s, ce[2], yoff, 1, IntSet(0, xoff-1));
01729 IntSet xd(yoff,yv.size()-1);
01730 for (int i=xoff; i<xv.size(); i++) {
01731 dom(s, xv[i], xd);
01732 }
01733 IntSet yd(xoff,xv.size()-1);
01734 for (int i=yoff; i<yv.size(); i++) {
01735 dom(s, yv[i], SRT_SUB, yd);
01736 }
01737 channel(s,xv,yv);
01738 }
01739
01740 void p_range(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01741 int xoff=ce[1]->getInt();
01742 assert(xoff >= 0);
01743 IntVarArgs xv = arg2intvarargs(s,ce[0],xoff);
01744 element(s, SOT_UNION, xv, getSetVar(s,ce[2]), getSetVar(s,ce[3]));
01745 }
01746
01747 void p_weights(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01748 IntArgs e = arg2intargs(ce[0]);
01749 IntArgs w = arg2intargs(ce[1]);
01750 SetVar x = getSetVar(s,ce[2]);
01751 IntVar y = getIntVar(s,ce[3]);
01752 weights(s,e,w,x,y);
01753 }
01754
01755 class SetPoster {
01756 public:
01757 SetPoster(void) {
01758 registry().add("set_eq", &p_set_eq);
01759 registry().add("set_le", &p_set_le);
01760 registry().add("set_lt", &p_set_lt);
01761 registry().add("equal", &p_set_eq);
01762 registry().add("set_ne", &p_set_ne);
01763 registry().add("set_union", &p_set_union);
01764 registry().add("array_set_element", &p_array_set_element);
01765 registry().add("array_var_set_element", &p_array_set_element);
01766 registry().add("set_intersect", &p_set_intersect);
01767 registry().add("set_diff", &p_set_diff);
01768 registry().add("set_symdiff", &p_set_symdiff);
01769 registry().add("set_subset", &p_set_subset);
01770 registry().add("set_superset", &p_set_superset);
01771 registry().add("set_card", &p_set_card);
01772 registry().add("set_in", &p_set_in);
01773 registry().add("set_eq_reif", &p_set_eq_reif);
01774 registry().add("set_le_reif", &p_set_le_reif);
01775 registry().add("set_lt_reif", &p_set_lt_reif);
01776 registry().add("equal_reif", &p_set_eq_reif);
01777 registry().add("set_ne_reif", &p_set_ne_reif);
01778 registry().add("set_subset_reif", &p_set_subset_reif);
01779 registry().add("set_superset_reif", &p_set_superset_reif);
01780 registry().add("set_in_reif", &p_set_in_reif);
01781 registry().add("disjoint", &p_set_disjoint);
01782 registry().add("gecode_link_set_to_booleans",
01783 &p_link_set_to_booleans);
01784
01785 registry().add("array_set_union", &p_array_set_union);
01786 registry().add("array_set_partition", &p_array_set_partition);
01787 registry().add("set_convex", &p_set_convex);
01788 registry().add("array_set_seq", &p_array_set_seq);
01789 registry().add("array_set_seq_union", &p_array_set_seq_union);
01790 registry().add("gecode_array_set_element_union",
01791 &p_array_set_element_union);
01792 registry().add("gecode_array_set_element_intersect",
01793 &p_array_set_element_intersect);
01794 registry().add("gecode_array_set_element_intersect_in",
01795 &p_array_set_element_intersect_in);
01796 registry().add("gecode_array_set_element_partition",
01797 &p_array_set_element_partition);
01798 registry().add("gecode_int_set_channel",
01799 &p_int_set_channel);
01800 registry().add("gecode_range",
01801 &p_range);
01802 registry().add("gecode_set_weights",
01803 &p_weights);
01804 }
01805 };
01806 SetPoster __set_poster;
01807 #endif
01808
01809 }
01810 }}
01811
01812