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
00047 #ifdef GECODE_HAS_SET_VARS
00048 #include <gecode/set.hh>
00049 #endif
00050 #ifdef GECODE_HAS_FLOAT_VARS
00051 #include <gecode/float.hh>
00052 #endif
00053 #include <gecode/flatzinc.hh>
00054
00055 namespace Gecode { namespace FlatZinc {
00056
00057 Registry& registry(void) {
00058 static Registry r;
00059 return r;
00060 }
00061
00062 void
00063 Registry::post(FlatZincSpace& s, const ConExpr& ce) {
00064 std::map<std::string,poster>::iterator i = r.find(ce.id);
00065 if (i == r.end()) {
00066 throw FlatZinc::Error("Registry",
00067 std::string("Constraint ")+ce.id+" not found");
00068 }
00069 i->second(s, ce, ce.ann);
00070 }
00071
00072 void
00073 Registry::add(const std::string& id, poster p) {
00074 r[id] = p;
00075 }
00076
00077 namespace {
00078
00079 inline IntRelType
00080 swap(IntRelType irt) {
00081 switch (irt) {
00082 case IRT_LQ: return IRT_GQ;
00083 case IRT_LE: return IRT_GR;
00084 case IRT_GQ: return IRT_LQ;
00085 case IRT_GR: return IRT_LE;
00086 default: return irt;
00087 }
00088 }
00089
00090 inline IntRelType
00091 neg(IntRelType irt) {
00092 switch (irt) {
00093 case IRT_EQ: return IRT_NQ;
00094 case IRT_NQ: return IRT_EQ;
00095 case IRT_LQ: return IRT_GR;
00096 case IRT_LE: return IRT_GQ;
00097 case IRT_GQ: return IRT_LE;
00098 case IRT_GR:
00099 default:
00100 assert(irt == IRT_GR);
00101 }
00102 return IRT_LQ;
00103 }
00104
00105
00106
00107 void p_distinct(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00108 IntVarArgs va = s.arg2intvarargs(ce[0]);
00109 IntConLevel icl = s.ann2icl(ann);
00110 unshare(s, va);
00111 distinct(s, va, icl == ICL_DEF ? ICL_BND : icl);
00112 }
00113 void p_distinctOffset(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00114 IntVarArgs va = s.arg2intvarargs(ce[1]);
00115 unshare(s, va);
00116 AST::Array* offs = ce.args->a[0]->getArray();
00117 IntArgs oa(offs->a.size());
00118 for (int i=offs->a.size(); i--; ) {
00119 oa[i] = offs->a[i]->getInt();
00120 }
00121 IntConLevel icl = s.ann2icl(ann);
00122 distinct(s, oa, va, icl == ICL_DEF ? ICL_BND : icl);
00123 }
00124
00125 void p_all_equal(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00126 IntVarArgs va = s.arg2intvarargs(ce[0]);
00127 rel(s, va, IRT_EQ, s.ann2icl(ann));
00128 }
00129
00130 void p_int_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00131 AST::Node* ann) {
00132 if (ce[0]->isIntVar()) {
00133 if (ce[1]->isIntVar()) {
00134 rel(s, s.arg2IntVar(ce[0]), irt, s.arg2IntVar(ce[1]),
00135 s.ann2icl(ann));
00136 } else {
00137 rel(s, s.arg2IntVar(ce[0]), irt, ce[1]->getInt(), s.ann2icl(ann));
00138 }
00139 } else {
00140 rel(s, s.arg2IntVar(ce[1]), swap(irt), ce[0]->getInt(),
00141 s.ann2icl(ann));
00142 }
00143 }
00144 void p_int_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00145 p_int_CMP(s, IRT_EQ, ce, ann);
00146 }
00147 void p_int_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00148 p_int_CMP(s, IRT_NQ, ce, ann);
00149 }
00150 void p_int_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00151 p_int_CMP(s, IRT_GQ, ce, ann);
00152 }
00153 void p_int_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00154 p_int_CMP(s, IRT_GR, ce, ann);
00155 }
00156 void p_int_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00157 p_int_CMP(s, IRT_LQ, ce, ann);
00158 }
00159 void p_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00160 p_int_CMP(s, IRT_LE, ce, ann);
00161 }
00162 void p_int_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
00163 const ConExpr& ce, AST::Node* ann) {
00164 if (rm == RM_EQV && ce[2]->isBool()) {
00165 if (ce[2]->getBool()) {
00166 p_int_CMP(s, irt, ce, ann);
00167 } else {
00168 p_int_CMP(s, neg(irt), ce, ann);
00169 }
00170 return;
00171 }
00172 if (ce[0]->isIntVar()) {
00173 if (ce[1]->isIntVar()) {
00174 rel(s, s.arg2IntVar(ce[0]), irt, s.arg2IntVar(ce[1]),
00175 Reify(s.arg2BoolVar(ce[2]), rm), s.ann2icl(ann));
00176 } else {
00177 rel(s, s.arg2IntVar(ce[0]), irt, ce[1]->getInt(),
00178 Reify(s.arg2BoolVar(ce[2]), rm), s.ann2icl(ann));
00179 }
00180 } else {
00181 rel(s, s.arg2IntVar(ce[1]), swap(irt), ce[0]->getInt(),
00182 Reify(s.arg2BoolVar(ce[2]), rm), s.ann2icl(ann));
00183 }
00184 }
00185
00186
00187 void p_int_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00188 p_int_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
00189 }
00190 void p_int_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00191 p_int_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
00192 }
00193 void p_int_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00194 p_int_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
00195 }
00196 void p_int_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00197 p_int_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
00198 }
00199 void p_int_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00200 p_int_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
00201 }
00202 void p_int_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00203 p_int_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
00204 }
00205
00206 void p_int_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00207 p_int_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
00208 }
00209 void p_int_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00210 p_int_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
00211 }
00212 void p_int_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00213 p_int_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
00214 }
00215 void p_int_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00216 p_int_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
00217 }
00218 void p_int_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00219 p_int_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
00220 }
00221 void p_int_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00222 p_int_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
00223 }
00224
00225
00226 void p_int_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00227 AST::Node* ann) {
00228 IntArgs ia = s.arg2intargs(ce[0]);
00229 int singleIntVar;
00230 if (s.isBoolArray(ce[1],singleIntVar)) {
00231 if (singleIntVar != -1) {
00232 if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
00233 IntVar siv = s.arg2IntVar(ce[1]->getArray()->a[singleIntVar]);
00234 BoolVarArgs iv = s.arg2boolvarargs(ce[1], 0, singleIntVar);
00235 IntArgs ia_tmp(ia.size()-1);
00236 int count = 0;
00237 for (int i=0; i<ia.size(); i++) {
00238 if (i != singleIntVar)
00239 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
00240 }
00241 IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
00242 linear(s, ia_tmp, iv, t, siv, s.ann2icl(ann));
00243 } else {
00244 IntVarArgs iv = s.arg2intvarargs(ce[1]);
00245 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
00246 }
00247 } else {
00248 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
00249 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
00250 }
00251 } else {
00252 IntVarArgs iv = s.arg2intvarargs(ce[1]);
00253 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
00254 }
00255 }
00256 void p_int_lin_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
00257 const ConExpr& ce, AST::Node* ann) {
00258 if (rm == RM_EQV && ce[2]->isBool()) {
00259 if (ce[2]->getBool()) {
00260 p_int_lin_CMP(s, irt, ce, ann);
00261 } else {
00262 p_int_lin_CMP(s, neg(irt), ce, ann);
00263 }
00264 return;
00265 }
00266 IntArgs ia = s.arg2intargs(ce[0]);
00267 int singleIntVar;
00268 if (s.isBoolArray(ce[1],singleIntVar)) {
00269 if (singleIntVar != -1) {
00270 if (std::abs(ia[singleIntVar]) == 1 && ce[2]->getInt() == 0) {
00271 IntVar siv = s.arg2IntVar(ce[1]->getArray()->a[singleIntVar]);
00272 BoolVarArgs iv = s.arg2boolvarargs(ce[1], 0, singleIntVar);
00273 IntArgs ia_tmp(ia.size()-1);
00274 int count = 0;
00275 for (int i=0; i<ia.size(); i++) {
00276 if (i != singleIntVar)
00277 ia_tmp[count++] = ia[singleIntVar] == -1 ? ia[i] : -ia[i];
00278 }
00279 IntRelType t = (ia[singleIntVar] == -1 ? irt : swap(irt));
00280 linear(s, ia_tmp, iv, t, siv, Reify(s.arg2BoolVar(ce[3]), rm),
00281 s.ann2icl(ann));
00282 } else {
00283 IntVarArgs iv = s.arg2intvarargs(ce[1]);
00284 linear(s, ia, iv, irt, ce[2]->getInt(),
00285 Reify(s.arg2BoolVar(ce[3]), rm), s.ann2icl(ann));
00286 }
00287 } else {
00288 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
00289 linear(s, ia, iv, irt, ce[2]->getInt(),
00290 Reify(s.arg2BoolVar(ce[3]), rm), s.ann2icl(ann));
00291 }
00292 } else {
00293 IntVarArgs iv = s.arg2intvarargs(ce[1]);
00294 linear(s, ia, iv, irt, ce[2]->getInt(),
00295 Reify(s.arg2BoolVar(ce[3]), rm),
00296 s.ann2icl(ann));
00297 }
00298 }
00299 void p_int_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00300 p_int_lin_CMP(s, IRT_EQ, ce, ann);
00301 }
00302 void p_int_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00303 p_int_lin_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
00304 }
00305 void p_int_lin_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00306 p_int_lin_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
00307 }
00308 void p_int_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00309 p_int_lin_CMP(s, IRT_NQ, ce, ann);
00310 }
00311 void p_int_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00312 p_int_lin_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
00313 }
00314 void p_int_lin_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00315 p_int_lin_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
00316 }
00317 void p_int_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00318 p_int_lin_CMP(s, IRT_LQ, ce, ann);
00319 }
00320 void p_int_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00321 p_int_lin_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
00322 }
00323 void p_int_lin_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00324 p_int_lin_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
00325 }
00326 void p_int_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00327 p_int_lin_CMP(s, IRT_LE, ce, ann);
00328 }
00329 void p_int_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00330 p_int_lin_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
00331 }
00332 void p_int_lin_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00333 p_int_lin_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
00334 }
00335 void p_int_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00336 p_int_lin_CMP(s, IRT_GQ, ce, ann);
00337 }
00338 void p_int_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00339 p_int_lin_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
00340 }
00341 void p_int_lin_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00342 p_int_lin_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
00343 }
00344 void p_int_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00345 p_int_lin_CMP(s, IRT_GR, ce, ann);
00346 }
00347 void p_int_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00348 p_int_lin_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
00349 }
00350 void p_int_lin_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00351 p_int_lin_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
00352 }
00353
00354 void p_bool_lin_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00355 AST::Node* ann) {
00356 IntArgs ia = s.arg2intargs(ce[0]);
00357 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
00358 if (ce[2]->isIntVar())
00359 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()], s.ann2icl(ann));
00360 else
00361 linear(s, ia, iv, irt, ce[2]->getInt(), s.ann2icl(ann));
00362 }
00363 void p_bool_lin_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
00364 const ConExpr& ce, AST::Node* ann) {
00365 if (rm == RM_EQV && ce[2]->isBool()) {
00366 if (ce[2]->getBool()) {
00367 p_bool_lin_CMP(s, irt, ce, ann);
00368 } else {
00369 p_bool_lin_CMP(s, neg(irt), ce, ann);
00370 }
00371 return;
00372 }
00373 IntArgs ia = s.arg2intargs(ce[0]);
00374 BoolVarArgs iv = s.arg2boolvarargs(ce[1]);
00375 if (ce[2]->isIntVar())
00376 linear(s, ia, iv, irt, s.iv[ce[2]->getIntVar()],
00377 Reify(s.arg2BoolVar(ce[3]), rm),
00378 s.ann2icl(ann));
00379 else
00380 linear(s, ia, iv, irt, ce[2]->getInt(),
00381 Reify(s.arg2BoolVar(ce[3]), rm),
00382 s.ann2icl(ann));
00383 }
00384 void p_bool_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00385 p_bool_lin_CMP(s, IRT_EQ, ce, ann);
00386 }
00387 void p_bool_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00388 {
00389 p_bool_lin_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
00390 }
00391 void p_bool_lin_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00392 {
00393 p_bool_lin_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
00394 }
00395 void p_bool_lin_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00396 p_bool_lin_CMP(s, IRT_NQ, ce, ann);
00397 }
00398 void p_bool_lin_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00399 {
00400 p_bool_lin_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
00401 }
00402 void p_bool_lin_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00403 {
00404 p_bool_lin_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
00405 }
00406 void p_bool_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00407 p_bool_lin_CMP(s, IRT_LQ, ce, ann);
00408 }
00409 void p_bool_lin_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00410 {
00411 p_bool_lin_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
00412 }
00413 void p_bool_lin_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00414 {
00415 p_bool_lin_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
00416 }
00417 void p_bool_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00418 {
00419 p_bool_lin_CMP(s, IRT_LE, ce, ann);
00420 }
00421 void p_bool_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00422 {
00423 p_bool_lin_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
00424 }
00425 void p_bool_lin_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00426 {
00427 p_bool_lin_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
00428 }
00429 void p_bool_lin_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00430 p_bool_lin_CMP(s, IRT_GQ, ce, ann);
00431 }
00432 void p_bool_lin_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00433 {
00434 p_bool_lin_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
00435 }
00436 void p_bool_lin_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00437 {
00438 p_bool_lin_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
00439 }
00440 void p_bool_lin_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00441 p_bool_lin_CMP(s, IRT_GR, ce, ann);
00442 }
00443 void p_bool_lin_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00444 {
00445 p_bool_lin_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
00446 }
00447 void p_bool_lin_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00448 {
00449 p_bool_lin_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
00450 }
00451
00452
00453
00454 void p_int_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00455 if (!ce[0]->isIntVar()) {
00456 rel(s, ce[0]->getInt() + s.arg2IntVar(ce[1])
00457 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
00458 } else if (!ce[1]->isIntVar()) {
00459 rel(s, s.arg2IntVar(ce[0]) + ce[1]->getInt()
00460 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
00461 } else if (!ce[2]->isIntVar()) {
00462 rel(s, s.arg2IntVar(ce[0]) + s.arg2IntVar(ce[1])
00463 == ce[2]->getInt(), s.ann2icl(ann));
00464 } else {
00465 rel(s, s.arg2IntVar(ce[0]) + s.arg2IntVar(ce[1])
00466 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
00467 }
00468 }
00469
00470 void p_int_minus(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00471 if (!ce[0]->isIntVar()) {
00472 rel(s, ce[0]->getInt() - s.arg2IntVar(ce[1])
00473 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
00474 } else if (!ce[1]->isIntVar()) {
00475 rel(s, s.arg2IntVar(ce[0]) - ce[1]->getInt()
00476 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
00477 } else if (!ce[2]->isIntVar()) {
00478 rel(s, s.arg2IntVar(ce[0]) - s.arg2IntVar(ce[1])
00479 == ce[2]->getInt(), s.ann2icl(ann));
00480 } else {
00481 rel(s, s.arg2IntVar(ce[0]) - s.arg2IntVar(ce[1])
00482 == s.arg2IntVar(ce[2]), s.ann2icl(ann));
00483 }
00484 }
00485
00486 void p_int_times(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00487 IntVar x0 = s.arg2IntVar(ce[0]);
00488 IntVar x1 = s.arg2IntVar(ce[1]);
00489 IntVar x2 = s.arg2IntVar(ce[2]);
00490 mult(s, x0, x1, x2, s.ann2icl(ann));
00491 }
00492 void p_int_div(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00493 IntVar x0 = s.arg2IntVar(ce[0]);
00494 IntVar x1 = s.arg2IntVar(ce[1]);
00495 IntVar x2 = s.arg2IntVar(ce[2]);
00496 div(s,x0,x1,x2, s.ann2icl(ann));
00497 }
00498 void p_int_mod(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00499 IntVar x0 = s.arg2IntVar(ce[0]);
00500 IntVar x1 = s.arg2IntVar(ce[1]);
00501 IntVar x2 = s.arg2IntVar(ce[2]);
00502 mod(s,x0,x1,x2, s.ann2icl(ann));
00503 }
00504
00505 void p_int_min(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00506 IntVar x0 = s.arg2IntVar(ce[0]);
00507 IntVar x1 = s.arg2IntVar(ce[1]);
00508 IntVar x2 = s.arg2IntVar(ce[2]);
00509 min(s, x0, x1, x2, s.ann2icl(ann));
00510 }
00511 void p_int_max(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00512 IntVar x0 = s.arg2IntVar(ce[0]);
00513 IntVar x1 = s.arg2IntVar(ce[1]);
00514 IntVar x2 = s.arg2IntVar(ce[2]);
00515 max(s, x0, x1, x2, s.ann2icl(ann));
00516 }
00517 void p_int_negate(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00518 IntVar x0 = s.arg2IntVar(ce[0]);
00519 IntVar x1 = s.arg2IntVar(ce[1]);
00520 rel(s, x0 == -x1, s.ann2icl(ann));
00521 }
00522
00523
00524 void p_bool_CMP(FlatZincSpace& s, IntRelType irt, const ConExpr& ce,
00525 AST::Node* ann) {
00526 rel(s, s.arg2BoolVar(ce[0]), irt, s.arg2BoolVar(ce[1]),
00527 s.ann2icl(ann));
00528 }
00529 void p_bool_CMP_reif(FlatZincSpace& s, IntRelType irt, ReifyMode rm,
00530 const ConExpr& ce, AST::Node* ann) {
00531 rel(s, s.arg2BoolVar(ce[0]), irt, s.arg2BoolVar(ce[1]),
00532 Reify(s.arg2BoolVar(ce[2]), rm), s.ann2icl(ann));
00533 }
00534 void p_bool_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00535 p_bool_CMP(s, IRT_EQ, ce, ann);
00536 }
00537 void p_bool_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00538 p_bool_CMP_reif(s, IRT_EQ, RM_EQV, ce, ann);
00539 }
00540 void p_bool_eq_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00541 p_bool_CMP_reif(s, IRT_EQ, RM_IMP, ce, ann);
00542 }
00543 void p_bool_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00544 p_bool_CMP(s, IRT_NQ, ce, ann);
00545 }
00546 void p_bool_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00547 p_bool_CMP_reif(s, IRT_NQ, RM_EQV, ce, ann);
00548 }
00549 void p_bool_ne_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00550 p_bool_CMP_reif(s, IRT_NQ, RM_IMP, ce, ann);
00551 }
00552 void p_bool_ge(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00553 p_bool_CMP(s, IRT_GQ, ce, ann);
00554 }
00555 void p_bool_ge_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00556 p_bool_CMP_reif(s, IRT_GQ, RM_EQV, ce, ann);
00557 }
00558 void p_bool_ge_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00559 p_bool_CMP_reif(s, IRT_GQ, RM_IMP, ce, ann);
00560 }
00561 void p_bool_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00562 p_bool_CMP(s, IRT_LQ, ce, ann);
00563 }
00564 void p_bool_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00565 p_bool_CMP_reif(s, IRT_LQ, RM_EQV, ce, ann);
00566 }
00567 void p_bool_le_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00568 p_bool_CMP_reif(s, IRT_LQ, RM_IMP, ce, ann);
00569 }
00570 void p_bool_gt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00571 p_bool_CMP(s, IRT_GR, ce, ann);
00572 }
00573 void p_bool_gt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00574 p_bool_CMP_reif(s, IRT_GR, RM_EQV, ce, ann);
00575 }
00576 void p_bool_gt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00577 p_bool_CMP_reif(s, IRT_GR, RM_IMP, ce, ann);
00578 }
00579 void p_bool_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00580 p_bool_CMP(s, IRT_LE, ce, ann);
00581 }
00582 void p_bool_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00583 p_bool_CMP_reif(s, IRT_LE, RM_EQV, ce, ann);
00584 }
00585 void p_bool_lt_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00586 p_bool_CMP_reif(s, IRT_LE, RM_IMP, ce, ann);
00587 }
00588
00589 #define BOOL_OP(op) \
00590 BoolVar b0 = s.arg2BoolVar(ce[0]); \
00591 BoolVar b1 = s.arg2BoolVar(ce[1]); \
00592 if (ce[2]->isBool()) { \
00593 rel(s, b0, op, b1, ce[2]->getBool(), s.ann2icl(ann)); \
00594 } else { \
00595 rel(s, b0, op, b1, s.bv[ce[2]->getBoolVar()], s.ann2icl(ann)); \
00596 }
00597
00598 #define BOOL_ARRAY_OP(op) \
00599 BoolVarArgs bv = s.arg2boolvarargs(ce[0]); \
00600 if (ce.size()==1) { \
00601 rel(s, op, bv, 1, s.ann2icl(ann)); \
00602 } else if (ce[1]->isBool()) { \
00603 rel(s, op, bv, ce[1]->getBool(), s.ann2icl(ann)); \
00604 } else { \
00605 rel(s, op, bv, s.bv[ce[1]->getBoolVar()], s.ann2icl(ann)); \
00606 }
00607
00608 void p_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00609 BOOL_OP(BOT_OR);
00610 }
00611 void p_bool_or_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00612 BoolVar b0 = s.arg2BoolVar(ce[0]);
00613 BoolVar b1 = s.arg2BoolVar(ce[1]);
00614 BoolVar b2 = s.arg2BoolVar(ce[2]);
00615 clause(s, BOT_OR, BoolVarArgs()<<b0<<b1, BoolVarArgs()<<b2, 1,
00616 s.ann2icl(ann));
00617 }
00618 void p_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00619 BOOL_OP(BOT_AND);
00620 }
00621 void p_bool_and_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00622 BoolVar b0 = s.arg2BoolVar(ce[0]);
00623 BoolVar b1 = s.arg2BoolVar(ce[1]);
00624 BoolVar b2 = s.arg2BoolVar(ce[2]);
00625 rel(s, b2, BOT_IMP, b0, 1, s.ann2icl(ann));
00626 rel(s, b2, BOT_IMP, b1, 1, s.ann2icl(ann));
00627 }
00628 void p_array_bool_and(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00629 {
00630 BOOL_ARRAY_OP(BOT_AND);
00631 }
00632 void p_array_bool_and_imp(FlatZincSpace& s, const ConExpr& ce,
00633 AST::Node* ann)
00634 {
00635 BoolVarArgs bv = s.arg2boolvarargs(ce[0]);
00636 BoolVar b1 = s.arg2BoolVar(ce[1]);
00637 for (unsigned int i=bv.size(); i--;)
00638 rel(s, b1, BOT_IMP, bv[i], 1, s.ann2icl(ann));
00639 }
00640 void p_array_bool_or(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00641 {
00642 BOOL_ARRAY_OP(BOT_OR);
00643 }
00644 void p_array_bool_or_imp(FlatZincSpace& s, const ConExpr& ce,
00645 AST::Node* ann)
00646 {
00647 BoolVarArgs bv = s.arg2boolvarargs(ce[0]);
00648 BoolVar b1 = s.arg2BoolVar(ce[1]);
00649 clause(s, BOT_OR, bv, BoolVarArgs()<<b1, 1, s.ann2icl(ann));
00650 }
00651 void p_array_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann)
00652 {
00653 BOOL_ARRAY_OP(BOT_XOR);
00654 }
00655 void p_array_bool_xor_imp(FlatZincSpace& s, const ConExpr& ce,
00656 AST::Node* ann)
00657 {
00658 BoolVarArgs bv = s.arg2boolvarargs(ce[0]);
00659 BoolVar tmp(s,0,1);
00660 rel(s, BOT_XOR, bv, tmp, s.ann2icl(ann));
00661 rel(s, s.arg2BoolVar(ce[1]), BOT_IMP, tmp, 1);
00662 }
00663 void p_array_bool_clause(FlatZincSpace& s, const ConExpr& ce,
00664 AST::Node* ann) {
00665 BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
00666 BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
00667 clause(s, BOT_OR, bvp, bvn, 1, s.ann2icl(ann));
00668 }
00669 void p_array_bool_clause_reif(FlatZincSpace& s, const ConExpr& ce,
00670 AST::Node* ann) {
00671 BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
00672 BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
00673 BoolVar b0 = s.arg2BoolVar(ce[2]);
00674 clause(s, BOT_OR, bvp, bvn, b0, s.ann2icl(ann));
00675 }
00676 void p_array_bool_clause_imp(FlatZincSpace& s, const ConExpr& ce,
00677 AST::Node* ann) {
00678 BoolVarArgs bvp = s.arg2boolvarargs(ce[0]);
00679 BoolVarArgs bvn = s.arg2boolvarargs(ce[1]);
00680 BoolVar b0 = s.arg2BoolVar(ce[2]);
00681 clause(s, BOT_OR, bvp, bvn, b0, s.ann2icl(ann));
00682 }
00683 void p_bool_xor(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00684 BOOL_OP(BOT_XOR);
00685 }
00686 void p_bool_xor_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00687 BoolVar b0 = s.arg2BoolVar(ce[0]);
00688 BoolVar b1 = s.arg2BoolVar(ce[1]);
00689 BoolVar b2 = s.arg2BoolVar(ce[2]);
00690 clause(s, BOT_OR, BoolVarArgs()<<b0<<b1, BoolVarArgs()<<b2, 1,
00691 s.ann2icl(ann));
00692 clause(s, BOT_OR, BoolVarArgs(), BoolVarArgs()<<b0<<b1<<b2, 1,
00693 s.ann2icl(ann));
00694 }
00695 void p_bool_l_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00696 BoolVar b0 = s.arg2BoolVar(ce[0]);
00697 BoolVar b1 = s.arg2BoolVar(ce[1]);
00698 if (ce[2]->isBool()) {
00699 rel(s, b1, BOT_IMP, b0, ce[2]->getBool(), s.ann2icl(ann));
00700 } else {
00701 rel(s, b1, BOT_IMP, b0, s.bv[ce[2]->getBoolVar()], s.ann2icl(ann));
00702 }
00703 }
00704 void p_bool_r_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00705 BOOL_OP(BOT_IMP);
00706 }
00707 void p_bool_not(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00708 BoolVar x0 = s.arg2BoolVar(ce[0]);
00709 BoolVar x1 = s.arg2BoolVar(ce[1]);
00710 rel(s, x0, BOT_XOR, x1, 1, s.ann2icl(ann));
00711 }
00712
00713
00714 void p_array_int_element(FlatZincSpace& s, const ConExpr& ce,
00715 AST::Node* ann) {
00716 bool isConstant = true;
00717 AST::Array* a = ce[1]->getArray();
00718 for (int i=a->a.size(); i--;) {
00719 if (!a->a[i]->isInt()) {
00720 isConstant = false;
00721 break;
00722 }
00723 }
00724 IntVar selector = s.arg2IntVar(ce[0]);
00725 rel(s, selector > 0);
00726 if (isConstant) {
00727 IntArgs ia = s.arg2intargs(ce[1], 1);
00728 element(s, ia, selector, s.arg2IntVar(ce[2]), s.ann2icl(ann));
00729 } else {
00730 IntVarArgs iv = s.arg2intvarargs(ce[1], 1);
00731 element(s, iv, selector, s.arg2IntVar(ce[2]), s.ann2icl(ann));
00732 }
00733 }
00734 void p_array_bool_element(FlatZincSpace& s, const ConExpr& ce,
00735 AST::Node* ann) {
00736 bool isConstant = true;
00737 AST::Array* a = ce[1]->getArray();
00738 for (int i=a->a.size(); i--;) {
00739 if (!a->a[i]->isBool()) {
00740 isConstant = false;
00741 break;
00742 }
00743 }
00744 IntVar selector = s.arg2IntVar(ce[0]);
00745 rel(s, selector > 0);
00746 if (isConstant) {
00747 IntArgs ia = s.arg2boolargs(ce[1], 1);
00748 element(s, ia, selector, s.arg2BoolVar(ce[2]), s.ann2icl(ann));
00749 } else {
00750 BoolVarArgs iv = s.arg2boolvarargs(ce[1], 1);
00751 element(s, iv, selector, s.arg2BoolVar(ce[2]), s.ann2icl(ann));
00752 }
00753 }
00754
00755
00756 void p_bool2int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00757 BoolVar x0 = s.arg2BoolVar(ce[0]);
00758 IntVar x1 = s.arg2IntVar(ce[1]);
00759 if (ce[0]->isBoolVar() && ce[1]->isIntVar()) {
00760 s.aliasBool2Int(ce[1]->getIntVar(), ce[0]->getBoolVar());
00761 }
00762 channel(s, x0, x1, s.ann2icl(ann));
00763 }
00764
00765 void p_int_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
00766 IntSet d = s.arg2intset(ce[1]);
00767 if (ce[0]->isBoolVar()) {
00768 IntSetRanges dr(d);
00769 Iter::Ranges::Singleton sr(0,1);
00770 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
00771 IntSet d01(i);
00772 if (d01.size() == 0) {
00773 s.fail();
00774 } else {
00775 rel(s, s.arg2BoolVar(ce[0]), IRT_GQ, d01.min());
00776 rel(s, s.arg2BoolVar(ce[0]), IRT_LQ, d01.max());
00777 }
00778 } else {
00779 dom(s, s.arg2IntVar(ce[0]), d);
00780 }
00781 }
00782 void p_int_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
00783 IntSet d = s.arg2intset(ce[1]);
00784 if (ce[0]->isBoolVar()) {
00785 IntSetRanges dr(d);
00786 Iter::Ranges::Singleton sr(0,1);
00787 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
00788 IntSet d01(i);
00789 if (d01.size() == 0) {
00790 rel(s, s.arg2BoolVar(ce[2]) == 0);
00791 } else if (d01.max() == 0) {
00792 rel(s, s.arg2BoolVar(ce[2]) == !s.arg2BoolVar(ce[0]));
00793 } else if (d01.min() == 1) {
00794 rel(s, s.arg2BoolVar(ce[2]) == s.arg2BoolVar(ce[0]));
00795 } else {
00796 rel(s, s.arg2BoolVar(ce[2]) == 1);
00797 }
00798 } else {
00799 dom(s, s.arg2IntVar(ce[0]), d, s.arg2BoolVar(ce[2]));
00800 }
00801 }
00802 void p_int_in_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
00803 IntSet d = s.arg2intset(ce[1]);
00804 if (ce[0]->isBoolVar()) {
00805 IntSetRanges dr(d);
00806 Iter::Ranges::Singleton sr(0,1);
00807 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
00808 IntSet d01(i);
00809 if (d01.size() == 0) {
00810 rel(s, s.arg2BoolVar(ce[2]) == 0);
00811 } else if (d01.max() == 0) {
00812 rel(s, s.arg2BoolVar(ce[2]) >> !s.arg2BoolVar(ce[0]));
00813 } else if (d01.min() == 1) {
00814 rel(s, s.arg2BoolVar(ce[2]) >> s.arg2BoolVar(ce[0]));
00815 }
00816 } else {
00817 dom(s, s.arg2IntVar(ce[0]), d, Reify(s.arg2BoolVar(ce[2]),RM_IMP));
00818 }
00819 }
00820
00821
00822
00823 void p_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00824 IntVar x0 = s.arg2IntVar(ce[0]);
00825 IntVar x1 = s.arg2IntVar(ce[1]);
00826 abs(s, x0, x1, s.ann2icl(ann));
00827 }
00828
00829 void p_array_int_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00830 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
00831 IntVarArgs iv1 = s.arg2intvarargs(ce[1]);
00832 rel(s, iv0, IRT_LE, iv1, s.ann2icl(ann));
00833 }
00834
00835 void p_array_int_lq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00836 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
00837 IntVarArgs iv1 = s.arg2intvarargs(ce[1]);
00838 rel(s, iv0, IRT_LQ, iv1, s.ann2icl(ann));
00839 }
00840
00841 void p_array_bool_lt(FlatZincSpace& s, const ConExpr& ce,
00842 AST::Node* ann) {
00843 BoolVarArgs bv0 = s.arg2boolvarargs(ce[0]);
00844 BoolVarArgs bv1 = s.arg2boolvarargs(ce[1]);
00845 rel(s, bv0, IRT_LE, bv1, s.ann2icl(ann));
00846 }
00847
00848 void p_array_bool_lq(FlatZincSpace& s, const ConExpr& ce,
00849 AST::Node* ann) {
00850 BoolVarArgs bv0 = s.arg2boolvarargs(ce[0]);
00851 BoolVarArgs bv1 = s.arg2boolvarargs(ce[1]);
00852 rel(s, bv0, IRT_LQ, bv1, s.ann2icl(ann));
00853 }
00854
00855 void p_count(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00856 IntVarArgs iv = s.arg2intvarargs(ce[0]);
00857 if (!ce[1]->isIntVar()) {
00858 if (!ce[2]->isIntVar()) {
00859 count(s, iv, ce[1]->getInt(), IRT_EQ, ce[2]->getInt(),
00860 s.ann2icl(ann));
00861 } else {
00862 count(s, iv, ce[1]->getInt(), IRT_EQ, s.arg2IntVar(ce[2]),
00863 s.ann2icl(ann));
00864 }
00865 } else if (!ce[2]->isIntVar()) {
00866 count(s, iv, s.arg2IntVar(ce[1]), IRT_EQ, ce[2]->getInt(),
00867 s.ann2icl(ann));
00868 } else {
00869 count(s, iv, s.arg2IntVar(ce[1]), IRT_EQ, s.arg2IntVar(ce[2]),
00870 s.ann2icl(ann));
00871 }
00872 }
00873
00874 void p_count_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00875 IntVarArgs iv = s.arg2intvarargs(ce[0]);
00876 IntVar x = s.arg2IntVar(ce[1]);
00877 IntVar y = s.arg2IntVar(ce[2]);
00878 BoolVar b = s.arg2BoolVar(ce[3]);
00879 IntVar c(s,0,Int::Limits::max);
00880 count(s,iv,x,IRT_EQ,c,s.ann2icl(ann));
00881 rel(s, b == (c==y));
00882 }
00883 void p_count_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00884 IntVarArgs iv = s.arg2intvarargs(ce[0]);
00885 IntVar x = s.arg2IntVar(ce[1]);
00886 IntVar y = s.arg2IntVar(ce[2]);
00887 BoolVar b = s.arg2BoolVar(ce[3]);
00888 IntVar c(s,0,Int::Limits::max);
00889 count(s,iv,x,IRT_EQ,c,s.ann2icl(ann));
00890 rel(s, b >> (c==y));
00891 }
00892
00893 void count_rel(IntRelType irt,
00894 FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00895 IntVarArgs iv = s.arg2intvarargs(ce[1]);
00896 count(s, iv, ce[2]->getInt(), irt, ce[0]->getInt(), s.ann2icl(ann));
00897 }
00898
00899 void p_at_most(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00900 count_rel(IRT_LQ, s, ce, ann);
00901 }
00902
00903 void p_at_least(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
00904 count_rel(IRT_GQ, s, ce, ann);
00905 }
00906
00907 void p_bin_packing_load(FlatZincSpace& s, const ConExpr& ce,
00908 AST::Node* ann) {
00909 int minIdx = ce[3]->getInt();
00910 IntVarArgs load = s.arg2intvarargs(ce[0]);
00911 IntVarArgs l;
00912 IntVarArgs bin = s.arg2intvarargs(ce[1]);
00913 for (int i=bin.size(); i--;)
00914 rel(s, bin[i] >= minIdx);
00915 if (minIdx > 0) {
00916 for (int i=minIdx; i--;)
00917 l << IntVar(s,0,0);
00918 } else if (minIdx < 0) {
00919 IntVarArgs bin2(bin.size());
00920 for (int i=bin.size(); i--;)
00921 bin2[i] = expr(s, bin[i]-minIdx, s.ann2icl(ann));
00922 bin = bin2;
00923 }
00924 l << load;
00925 IntArgs sizes = s.arg2intargs(ce[2]);
00926
00927 IntVarArgs allvars = l + bin;
00928 unshare(s, allvars);
00929 binpacking(s, allvars.slice(0,1,l.size()), allvars.slice(l.size(),1,bin.size()),
00930 sizes, s.ann2icl(ann));
00931 }
00932
00933 void p_global_cardinality(FlatZincSpace& s, const ConExpr& ce,
00934 AST::Node* ann) {
00935 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
00936 IntArgs cover = s.arg2intargs(ce[1]);
00937 IntVarArgs iv1 = s.arg2intvarargs(ce[2]);
00938
00939 Region re(s);
00940 IntSet cover_s(cover);
00941 IntSetRanges cover_r(cover_s);
00942 IntVarRanges* iv0_ri = re.alloc<IntVarRanges>(iv0.size());
00943 for (int i=iv0.size(); i--;)
00944 iv0_ri[i] = IntVarRanges(iv0[i]);
00945 Iter::Ranges::NaryUnion iv0_r(re,iv0_ri,iv0.size());
00946 Iter::Ranges::Diff<Iter::Ranges::NaryUnion,IntSetRanges>
00947 extra_r(iv0_r,cover_r);
00948 Iter::Ranges::ToValues<Iter::Ranges::Diff<
00949 Iter::Ranges::NaryUnion,IntSetRanges> > extra(extra_r);
00950 for (; extra(); ++extra) {
00951 cover << extra.val();
00952 iv1 << IntVar(s,0,iv0.size());
00953 }
00954 IntConLevel icl = s.ann2icl(ann);
00955 if (icl==ICL_DOM) {
00956 IntVarArgs allvars = iv0+iv1;
00957 unshare(s, allvars);
00958 count(s, allvars.slice(0,1,iv0.size()),
00959 allvars.slice(iv0.size(),1,iv1.size()),
00960 cover, s.ann2icl(ann));
00961 } else {
00962 unshare(s, iv0);
00963 count(s, iv0, iv1, cover, s.ann2icl(ann));
00964 }
00965 }
00966
00967 void p_global_cardinality_closed(FlatZincSpace& s, const ConExpr& ce,
00968 AST::Node* ann) {
00969 IntVarArgs iv0 = s.arg2intvarargs(ce[0]);
00970 IntArgs cover = s.arg2intargs(ce[1]);
00971 IntVarArgs iv1 = s.arg2intvarargs(ce[2]);
00972 unshare(s, iv0);
00973 count(s, iv0, iv1, cover, s.ann2icl(ann));
00974 }
00975
00976 void p_global_cardinality_low_up(FlatZincSpace& s, const ConExpr& ce,
00977 AST::Node* ann) {
00978 IntVarArgs x = s.arg2intvarargs(ce[0]);
00979 IntArgs cover = s.arg2intargs(ce[1]);
00980
00981 IntArgs lbound = s.arg2intargs(ce[2]);
00982 IntArgs ubound = s.arg2intargs(ce[3]);
00983 IntSetArgs y(cover.size());
00984 for (int i=cover.size(); i--;)
00985 y[i] = IntSet(lbound[i],ubound[i]);
00986
00987 IntSet cover_s(cover);
00988 Region re(s);
00989 IntVarRanges* xrs = re.alloc<IntVarRanges>(x.size());
00990 for (int i=x.size(); i--;)
00991 xrs[i].init(x[i]);
00992 Iter::Ranges::NaryUnion u(re, xrs, x.size());
00993 Iter::Ranges::ToValues<Iter::Ranges::NaryUnion> uv(u);
00994 for (; uv(); ++uv) {
00995 if (!cover_s.in(uv.val())) {
00996 cover << uv.val();
00997 y << IntSet(0,x.size());
00998 }
00999 }
01000 unshare(s, x);
01001 count(s, x, y, cover, s.ann2icl(ann));
01002 }
01003
01004 void p_global_cardinality_low_up_closed(FlatZincSpace& s,
01005 const ConExpr& ce,
01006 AST::Node* ann) {
01007 IntVarArgs x = s.arg2intvarargs(ce[0]);
01008 IntArgs cover = s.arg2intargs(ce[1]);
01009
01010 IntArgs lbound = s.arg2intargs(ce[2]);
01011 IntArgs ubound = s.arg2intargs(ce[3]);
01012 IntSetArgs y(cover.size());
01013 for (int i=cover.size(); i--;)
01014 y[i] = IntSet(lbound[i],ubound[i]);
01015 unshare(s, x);
01016 count(s, x, y, cover, s.ann2icl(ann));
01017 }
01018
01019 void p_minimum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01020 IntVarArgs iv = s.arg2intvarargs(ce[1]);
01021 min(s, iv, s.arg2IntVar(ce[0]), s.ann2icl(ann));
01022 }
01023
01024 void p_maximum(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01025 IntVarArgs iv = s.arg2intvarargs(ce[1]);
01026 max(s, iv, s.arg2IntVar(ce[0]), s.ann2icl(ann));
01027 }
01028
01029 void p_minimum_arg(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01030 IntVarArgs iv = s.arg2intvarargs(ce[0]);
01031 argmin(s, iv, s.arg2IntVar(ce[1]), true, s.ann2icl(ann));
01032 }
01033
01034 void p_maximum_arg(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01035 IntVarArgs iv = s.arg2intvarargs(ce[0]);
01036 argmax(s, iv, s.arg2IntVar(ce[1]), true, s.ann2icl(ann));
01037 }
01038
01039 void p_regular(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01040 IntVarArgs iv = s.arg2intvarargs(ce[0]);
01041 int q = ce[1]->getInt();
01042 int symbols = ce[2]->getInt();
01043 IntArgs d = s.arg2intargs(ce[3]);
01044 int q0 = ce[4]->getInt();
01045
01046 int noOfTrans = 0;
01047 for (int i=1; i<=q; i++) {
01048 for (int j=1; j<=symbols; j++) {
01049 if (d[(i-1)*symbols+(j-1)] > 0)
01050 noOfTrans++;
01051 }
01052 }
01053
01054 Region re(s);
01055 DFA::Transition* t = re.alloc<DFA::Transition>(noOfTrans+1);
01056 noOfTrans = 0;
01057 for (int i=1; i<=q; i++) {
01058 for (int j=1; j<=symbols; j++) {
01059 if (d[(i-1)*symbols+(j-1)] > 0) {
01060 t[noOfTrans].i_state = i;
01061 t[noOfTrans].symbol = j;
01062 t[noOfTrans].o_state = d[(i-1)*symbols+(j-1)];
01063 noOfTrans++;
01064 }
01065 }
01066 }
01067 t[noOfTrans].i_state = -1;
01068
01069
01070 AST::SetLit* sl = ce[5]->getSet();
01071 int* f;
01072 if (sl->interval) {
01073 f = static_cast<int*>(malloc(sizeof(int)*(sl->max-sl->min+2)));
01074 for (int i=sl->min; i<=sl->max; i++)
01075 f[i-sl->min] = i;
01076 f[sl->max-sl->min+1] = -1;
01077 } else {
01078 f = static_cast<int*>(malloc(sizeof(int)*(sl->s.size()+1)));
01079 for (int j=sl->s.size(); j--; )
01080 f[j] = sl->s[j];
01081 f[sl->s.size()] = -1;
01082 }
01083
01084 DFA dfa(q0,t,f);
01085 free(f);
01086 unshare(s, iv);
01087 extensional(s, iv, dfa, s.ann2icl(ann));
01088 }
01089
01090 void
01091 p_sort(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01092 IntVarArgs x = s.arg2intvarargs(ce[0]);
01093 IntVarArgs y = s.arg2intvarargs(ce[1]);
01094 IntVarArgs xy(x.size()+y.size());
01095 for (int i=x.size(); i--;)
01096 xy[i] = x[i];
01097 for (int i=y.size(); i--;)
01098 xy[i+x.size()] = y[i];
01099 unshare(s, xy);
01100 for (int i=x.size(); i--;)
01101 x[i] = xy[i];
01102 for (int i=y.size(); i--;)
01103 y[i] = xy[i+x.size()];
01104 sorted(s, x, y, s.ann2icl(ann));
01105 }
01106
01107 void
01108 p_inverse_offsets(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01109 IntVarArgs x = s.arg2intvarargs(ce[0]);
01110 unshare(s, x);
01111 int xoff = ce[1]->getInt();
01112 IntVarArgs y = s.arg2intvarargs(ce[2]);
01113 unshare(s, y);
01114 int yoff = ce[3]->getInt();
01115 channel(s, x, xoff, y, yoff, s.ann2icl(ann));
01116 }
01117
01118 void
01119 p_increasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01120 IntVarArgs x = s.arg2intvarargs(ce[0]);
01121 rel(s,x,IRT_LQ,s.ann2icl(ann));
01122 }
01123
01124 void
01125 p_increasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01126 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01127 rel(s,x,IRT_LQ,s.ann2icl(ann));
01128 }
01129
01130 void
01131 p_decreasing_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01132 IntVarArgs x = s.arg2intvarargs(ce[0]);
01133 rel(s,x,IRT_GQ,s.ann2icl(ann));
01134 }
01135
01136 void
01137 p_decreasing_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01138 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01139 rel(s,x,IRT_GQ,s.ann2icl(ann));
01140 }
01141
01142 void
01143 p_table_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01144 IntVarArgs x = s.arg2intvarargs(ce[0]);
01145 IntArgs tuples = s.arg2intargs(ce[1]);
01146 int noOfVars = x.size();
01147 int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
01148 TupleSet ts;
01149 for (int i=0; i<noOfTuples; i++) {
01150 IntArgs t(noOfVars);
01151 for (int j=0; j<x.size(); j++) {
01152 t[j] = tuples[i*noOfVars+j];
01153 }
01154 ts.add(t);
01155 }
01156 ts.finalize();
01157 extensional(s,x,ts,EPK_DEF,s.ann2icl(ann));
01158 }
01159 void
01160 p_table_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01161 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01162 IntArgs tuples = s.arg2boolargs(ce[1]);
01163 int noOfVars = x.size();
01164 int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
01165 TupleSet ts;
01166 for (int i=0; i<noOfTuples; i++) {
01167 IntArgs t(noOfVars);
01168 for (int j=0; j<x.size(); j++) {
01169 t[j] = tuples[i*noOfVars+j];
01170 }
01171 ts.add(t);
01172 }
01173 ts.finalize();
01174 extensional(s,x,ts,EPK_DEF,s.ann2icl(ann));
01175 }
01176
01177 void p_cumulative_opt(FlatZincSpace& s, const ConExpr& ce,
01178 AST::Node* ann) {
01179 IntVarArgs start = s.arg2intvarargs(ce[0]);
01180 IntArgs duration = s.arg2intargs(ce[1]);
01181 IntArgs height = s.arg2intargs(ce[2]);
01182 BoolVarArgs opt = s.arg2boolvarargs(ce[3]);
01183 int bound = ce[4]->getInt();
01184 unshare(s,start);
01185 cumulative(s,bound,start,duration,height,opt,s.ann2icl(ann));
01186 }
01187
01188 void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
01189 AST::Node* ann) {
01190 IntVarArgs start = s.arg2intvarargs(ce[0]);
01191 IntVarArgs duration = s.arg2intvarargs(ce[1]);
01192 IntVarArgs height = s.arg2intvarargs(ce[2]);
01193 int n = start.size();
01194 IntVar bound = s.arg2IntVar(ce[3]);
01195
01196 if (n==0)
01197 return;
01198
01199 if (n == 1) {
01200 rel(s, height[0] <= bound);
01201 return;
01202 }
01203
01204 int minHeight = std::min(height[0].min(),height[1].min());
01205 int minHeight2 = std::max(height[0].min(),height[1].min());
01206 for (int i=2; i<n; i++) {
01207 if (height[i].min() < minHeight) {
01208 minHeight2 = minHeight;
01209 minHeight = height[i].min();
01210 } else if (height[i].min() < minHeight2) {
01211 minHeight2 = height[i].min();
01212 }
01213 }
01214 bool disjunctive =
01215 (minHeight > bound.max()/2) ||
01216 (minHeight2 > bound.max()/2 && minHeight+minHeight2>bound.max());
01217 if (disjunctive) {
01218 rel(s, bound >= max(height));
01219
01220 if (duration.assigned()) {
01221 IntArgs durationI(n);
01222 for (int i=n; i--;)
01223 durationI[i] = duration[i].val();
01224 unshare(s,start);
01225 unary(s,start,durationI);
01226 } else {
01227 IntVarArgs end(n);
01228 for (int i=n; i--;)
01229 end[i] = expr(s,start[i]+duration[i]);
01230 unshare(s,start);
01231 unary(s,start,duration,end);
01232 }
01233 } else if (height.assigned()) {
01234 IntArgs heightI(n);
01235 for (int i=n; i--;)
01236 heightI[i] = height[i].val();
01237 if (duration.assigned()) {
01238 IntArgs durationI(n);
01239 for (int i=n; i--;)
01240 durationI[i] = duration[i].val();
01241 cumulative(s, bound, start, durationI, heightI);
01242 } else {
01243 IntVarArgs end(n);
01244 for (int i = n; i--; )
01245 end[i] = expr(s,start[i]+duration[i]);
01246 cumulative(s, bound, start, duration, end, heightI);
01247 }
01248 } else if (bound.assigned()) {
01249 IntArgs machine = IntArgs::create(n,0,0);
01250 IntArgs limit(1, bound.val());
01251 IntVarArgs end(n);
01252 for (int i=n; i--;)
01253 end[i] = expr(s,start[i]+duration[i]);
01254 cumulatives(s, machine, start, duration, end, height, limit, true,
01255 s.ann2icl(ann));
01256 } else {
01257 int min = Gecode::Int::Limits::max;
01258 int max = Gecode::Int::Limits::min;
01259 IntVarArgs end(start.size());
01260 for (int i = start.size(); i--; ) {
01261 min = std::min(min, start[i].min());
01262 max = std::max(max, start[i].max() + duration[i].max());
01263 end[i] = expr(s, start[i] + duration[i]);
01264 }
01265 for (int time = min; time < max; ++time) {
01266 IntVarArgs x(start.size());
01267 for (int i = start.size(); i--; ) {
01268 IntVar overlaps = channel(s, expr(s, (start[i] <= time) &&
01269 (time < end[i])));
01270 x[i] = expr(s, overlaps * height[i]);
01271 }
01272 linear(s, x, IRT_LQ, bound);
01273 }
01274 }
01275 }
01276
01277 void p_among_seq_int(FlatZincSpace& s, const ConExpr& ce,
01278 AST::Node* ann) {
01279 IntVarArgs x = s.arg2intvarargs(ce[0]);
01280 IntSet S = s.arg2intset(ce[1]);
01281 int q = ce[2]->getInt();
01282 int l = ce[3]->getInt();
01283 int u = ce[4]->getInt();
01284 unshare(s, x);
01285 sequence(s, x, S, q, l, u, s.ann2icl(ann));
01286 }
01287
01288 void p_among_seq_bool(FlatZincSpace& s, const ConExpr& ce,
01289 AST::Node* ann) {
01290 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01291 bool val = ce[1]->getBool();
01292 int q = ce[2]->getInt();
01293 int l = ce[3]->getInt();
01294 int u = ce[4]->getInt();
01295 IntSet S(val, val);
01296 unshare(s, x);
01297 sequence(s, x, S, q, l, u, s.ann2icl(ann));
01298 }
01299
01300 void p_schedule_unary(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01301 IntVarArgs x = s.arg2intvarargs(ce[0]);
01302 IntArgs p = s.arg2intargs(ce[1]);
01303 unshare(s,x);
01304 unary(s, x, p);
01305 }
01306
01307 void p_schedule_unary_optional(FlatZincSpace& s, const ConExpr& ce,
01308 AST::Node*) {
01309 IntVarArgs x = s.arg2intvarargs(ce[0]);
01310 IntArgs p = s.arg2intargs(ce[1]);
01311 BoolVarArgs m = s.arg2boolvarargs(ce[2]);
01312 unshare(s,x);
01313 unary(s, x, p, m);
01314 }
01315
01316 void p_circuit(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01317 int off = ce[0]->getInt();
01318 IntVarArgs xv = s.arg2intvarargs(ce[1]);
01319 unshare(s,xv);
01320 circuit(s,off,xv,s.ann2icl(ann));
01321 }
01322 void p_circuit_cost_array(FlatZincSpace& s, const ConExpr& ce,
01323 AST::Node *ann) {
01324 IntArgs c = s.arg2intargs(ce[0]);
01325 IntVarArgs xv = s.arg2intvarargs(ce[1]);
01326 IntVarArgs yv = s.arg2intvarargs(ce[2]);
01327 IntVar z = s.arg2IntVar(ce[3]);
01328 unshare(s,xv);
01329 circuit(s,c,xv,yv,z,s.ann2icl(ann));
01330 }
01331 void p_circuit_cost(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01332 IntArgs c = s.arg2intargs(ce[0]);
01333 IntVarArgs xv = s.arg2intvarargs(ce[1]);
01334 IntVar z = s.arg2IntVar(ce[2]);
01335 unshare(s,xv);
01336 circuit(s,c,xv,z,s.ann2icl(ann));
01337 }
01338
01339 void p_nooverlap(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01340 IntVarArgs x0 = s.arg2intvarargs(ce[0]);
01341 IntVarArgs w = s.arg2intvarargs(ce[1]);
01342 IntVarArgs y0 = s.arg2intvarargs(ce[2]);
01343 IntVarArgs h = s.arg2intvarargs(ce[3]);
01344 if (w.assigned() && h.assigned()) {
01345 IntArgs iw(w.size());
01346 for (int i=w.size(); i--;)
01347 iw[i] = w[i].val();
01348 IntArgs ih(h.size());
01349 for (int i=h.size(); i--;)
01350 ih[i] = h[i].val();
01351 nooverlap(s,x0,iw,y0,ih,s.ann2icl(ann));
01352
01353 int miny = y0[0].min();
01354 int maxy = y0[0].max();
01355 int maxdy = ih[0];
01356 for (int i=1; i<y0.size(); i++) {
01357 miny = std::min(miny,y0[i].min());
01358 maxy = std::max(maxy,y0[i].max());
01359 maxdy = std::max(maxdy,ih[i]);
01360 }
01361 int minx = x0[0].min();
01362 int maxx = x0[0].max();
01363 int maxdx = iw[0];
01364 for (int i=1; i<x0.size(); i++) {
01365 minx = std::min(minx,x0[i].min());
01366 maxx = std::max(maxx,x0[i].max());
01367 maxdx = std::max(maxdx,iw[i]);
01368 }
01369 if (miny > Int::Limits::min && maxy < Int::Limits::max) {
01370 cumulative(s,maxdy+maxy-miny,x0,iw,ih);
01371 cumulative(s,maxdx+maxx-minx,y0,ih,iw);
01372 }
01373 } else {
01374 IntVarArgs x1(x0.size()), y1(y0.size());
01375 for (int i=x0.size(); i--; )
01376 x1[i] = expr(s, x0[i] + w[i]);
01377 for (int i=y0.size(); i--; )
01378 y1[i] = expr(s, y0[i] + h[i]);
01379 nooverlap(s,x0,w,x1,y0,h,y1,s.ann2icl(ann));
01380 }
01381 }
01382
01383 void p_precede(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01384 IntVarArgs x = s.arg2intvarargs(ce[0]);
01385 int p_s = ce[1]->getInt();
01386 int p_t = ce[2]->getInt();
01387 precede(s,x,p_s,p_t,s.ann2icl(ann));
01388 }
01389
01390 void p_nvalue(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01391 IntVarArgs x = s.arg2intvarargs(ce[1]);
01392 if (ce[0]->isIntVar()) {
01393 IntVar y = s.arg2IntVar(ce[0]);
01394 nvalues(s,x,IRT_EQ,y,s.ann2icl(ann));
01395 } else {
01396 nvalues(s,x,IRT_EQ,ce[0]->getInt(),s.ann2icl(ann));
01397 }
01398 }
01399
01400 void p_among(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01401 IntVarArgs x = s.arg2intvarargs(ce[1]);
01402 IntSet v = s.arg2intset(ce[2]);
01403 if (ce[0]->isIntVar()) {
01404 IntVar n = s.arg2IntVar(ce[0]);
01405 unshare(s, x);
01406 count(s,x,v,IRT_EQ,n,s.ann2icl(ann));
01407 } else {
01408 unshare(s, x);
01409 count(s,x,v,IRT_EQ,ce[0]->getInt(),s.ann2icl(ann));
01410 }
01411 }
01412
01413 void p_member_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01414 IntVarArgs x = s.arg2intvarargs(ce[0]);
01415 IntVar y = s.arg2IntVar(ce[1]);
01416 member(s,x,y,s.ann2icl(ann));
01417 }
01418 void p_member_int_reif(FlatZincSpace& s, const ConExpr& ce,
01419 AST::Node* ann) {
01420 IntVarArgs x = s.arg2intvarargs(ce[0]);
01421 IntVar y = s.arg2IntVar(ce[1]);
01422 BoolVar b = s.arg2BoolVar(ce[2]);
01423 member(s,x,y,b,s.ann2icl(ann));
01424 }
01425 void p_member_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01426 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01427 BoolVar y = s.arg2BoolVar(ce[1]);
01428 member(s,x,y,s.ann2icl(ann));
01429 }
01430 void p_member_bool_reif(FlatZincSpace& s, const ConExpr& ce,
01431 AST::Node* ann) {
01432 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01433 BoolVar y = s.arg2BoolVar(ce[1]);
01434 member(s,x,y,s.arg2BoolVar(ce[2]),s.ann2icl(ann));
01435 }
01436
01437 class IntPoster {
01438 public:
01439 IntPoster(void) {
01440 registry().add("all_different_int", &p_distinct);
01441 registry().add("all_different_offset", &p_distinctOffset);
01442 registry().add("all_equal_int", &p_all_equal);
01443 registry().add("int_eq", &p_int_eq);
01444 registry().add("int_ne", &p_int_ne);
01445 registry().add("int_ge", &p_int_ge);
01446 registry().add("int_gt", &p_int_gt);
01447 registry().add("int_le", &p_int_le);
01448 registry().add("int_lt", &p_int_lt);
01449 registry().add("int_eq_reif", &p_int_eq_reif);
01450 registry().add("int_ne_reif", &p_int_ne_reif);
01451 registry().add("int_ge_reif", &p_int_ge_reif);
01452 registry().add("int_gt_reif", &p_int_gt_reif);
01453 registry().add("int_le_reif", &p_int_le_reif);
01454 registry().add("int_lt_reif", &p_int_lt_reif);
01455 registry().add("int_eq_imp", &p_int_eq_imp);
01456 registry().add("int_ne_imp", &p_int_ne_imp);
01457 registry().add("int_ge_imp", &p_int_ge_imp);
01458 registry().add("int_gt_imp", &p_int_gt_imp);
01459 registry().add("int_le_imp", &p_int_le_imp);
01460 registry().add("int_lt_imp", &p_int_lt_imp);
01461 registry().add("int_lin_eq", &p_int_lin_eq);
01462 registry().add("int_lin_eq_reif", &p_int_lin_eq_reif);
01463 registry().add("int_lin_eq_imp", &p_int_lin_eq_imp);
01464 registry().add("int_lin_ne", &p_int_lin_ne);
01465 registry().add("int_lin_ne_reif", &p_int_lin_ne_reif);
01466 registry().add("int_lin_ne_imp", &p_int_lin_ne_imp);
01467 registry().add("int_lin_le", &p_int_lin_le);
01468 registry().add("int_lin_le_reif", &p_int_lin_le_reif);
01469 registry().add("int_lin_le_imp", &p_int_lin_le_imp);
01470 registry().add("int_lin_lt", &p_int_lin_lt);
01471 registry().add("int_lin_lt_reif", &p_int_lin_lt_reif);
01472 registry().add("int_lin_lt_imp", &p_int_lin_lt_imp);
01473 registry().add("int_lin_ge", &p_int_lin_ge);
01474 registry().add("int_lin_ge_reif", &p_int_lin_ge_reif);
01475 registry().add("int_lin_ge_imp", &p_int_lin_ge_imp);
01476 registry().add("int_lin_gt", &p_int_lin_gt);
01477 registry().add("int_lin_gt_reif", &p_int_lin_gt_reif);
01478 registry().add("int_lin_gt_imp", &p_int_lin_gt_imp);
01479 registry().add("int_plus", &p_int_plus);
01480 registry().add("int_minus", &p_int_minus);
01481 registry().add("int_times", &p_int_times);
01482 registry().add("int_div", &p_int_div);
01483 registry().add("int_mod", &p_int_mod);
01484 registry().add("int_min", &p_int_min);
01485 registry().add("int_max", &p_int_max);
01486 registry().add("int_abs", &p_abs);
01487 registry().add("int_negate", &p_int_negate);
01488 registry().add("bool_eq", &p_bool_eq);
01489 registry().add("bool_eq_reif", &p_bool_eq_reif);
01490 registry().add("bool_eq_imp", &p_bool_eq_imp);
01491 registry().add("bool_ne", &p_bool_ne);
01492 registry().add("bool_ne_reif", &p_bool_ne_reif);
01493 registry().add("bool_ne_imp", &p_bool_ne_imp);
01494 registry().add("bool_ge", &p_bool_ge);
01495 registry().add("bool_ge_reif", &p_bool_ge_reif);
01496 registry().add("bool_ge_imp", &p_bool_ge_imp);
01497 registry().add("bool_le", &p_bool_le);
01498 registry().add("bool_le_reif", &p_bool_le_reif);
01499 registry().add("bool_le_imp", &p_bool_le_imp);
01500 registry().add("bool_gt", &p_bool_gt);
01501 registry().add("bool_gt_reif", &p_bool_gt_reif);
01502 registry().add("bool_gt_imp", &p_bool_gt_imp);
01503 registry().add("bool_lt", &p_bool_lt);
01504 registry().add("bool_lt_reif", &p_bool_lt_reif);
01505 registry().add("bool_lt_imp", &p_bool_lt_imp);
01506 registry().add("bool_or", &p_bool_or);
01507 registry().add("bool_or_imp", &p_bool_or_imp);
01508 registry().add("bool_and", &p_bool_and);
01509 registry().add("bool_and_imp", &p_bool_and_imp);
01510 registry().add("bool_xor", &p_bool_xor);
01511 registry().add("bool_xor_imp", &p_bool_xor_imp);
01512 registry().add("array_bool_and", &p_array_bool_and);
01513 registry().add("array_bool_and_imp", &p_array_bool_and_imp);
01514 registry().add("array_bool_or", &p_array_bool_or);
01515 registry().add("array_bool_or_imp", &p_array_bool_or_imp);
01516 registry().add("array_bool_xor", &p_array_bool_xor);
01517 registry().add("array_bool_xor_imp", &p_array_bool_xor_imp);
01518 registry().add("bool_clause", &p_array_bool_clause);
01519 registry().add("bool_clause_reif", &p_array_bool_clause_reif);
01520 registry().add("bool_clause_imp", &p_array_bool_clause_imp);
01521 registry().add("bool_left_imp", &p_bool_l_imp);
01522 registry().add("bool_right_imp", &p_bool_r_imp);
01523 registry().add("bool_not", &p_bool_not);
01524 registry().add("array_int_element", &p_array_int_element);
01525 registry().add("array_var_int_element", &p_array_int_element);
01526 registry().add("array_bool_element", &p_array_bool_element);
01527 registry().add("array_var_bool_element", &p_array_bool_element);
01528 registry().add("bool2int", &p_bool2int);
01529 registry().add("int_in", &p_int_in);
01530 registry().add("int_in_reif", &p_int_in_reif);
01531 registry().add("int_in_imp", &p_int_in_imp);
01532 #ifndef GECODE_HAS_SET_VARS
01533 registry().add("set_in", &p_int_in);
01534 registry().add("set_in_reif", &p_int_in_reif);
01535 registry().add("set_in_imp", &p_int_in_imp);
01536 #endif
01537
01538 registry().add("array_int_lt", &p_array_int_lt);
01539 registry().add("array_int_lq", &p_array_int_lq);
01540 registry().add("array_bool_lt", &p_array_bool_lt);
01541 registry().add("array_bool_lq", &p_array_bool_lq);
01542 registry().add("count", &p_count);
01543 registry().add("count_reif", &p_count_reif);
01544 registry().add("count_imp", &p_count_imp);
01545 registry().add("at_least_int", &p_at_least);
01546 registry().add("at_most_int", &p_at_most);
01547 registry().add("gecode_bin_packing_load", &p_bin_packing_load);
01548 registry().add("global_cardinality", &p_global_cardinality);
01549 registry().add("global_cardinality_closed",
01550 &p_global_cardinality_closed);
01551 registry().add("global_cardinality_low_up",
01552 &p_global_cardinality_low_up);
01553 registry().add("global_cardinality_low_up_closed",
01554 &p_global_cardinality_low_up_closed);
01555 registry().add("array_int_minimum", &p_minimum);
01556 registry().add("array_int_maximum", &p_maximum);
01557 registry().add("gecode_minimum_arg_int", &p_minimum_arg);
01558 registry().add("gecode_maximum_arg_int", &p_maximum_arg);
01559 registry().add("array_int_maximum", &p_maximum);
01560 registry().add("regular", &p_regular);
01561 registry().add("sort", &p_sort);
01562 registry().add("inverse_offsets", &p_inverse_offsets);
01563 registry().add("increasing_int", &p_increasing_int);
01564 registry().add("increasing_bool", &p_increasing_bool);
01565 registry().add("decreasing_int", &p_decreasing_int);
01566 registry().add("decreasing_bool", &p_decreasing_bool);
01567 registry().add("table_int", &p_table_int);
01568 registry().add("table_bool", &p_table_bool);
01569 registry().add("cumulatives", &p_cumulatives);
01570 registry().add("gecode_among_seq_int", &p_among_seq_int);
01571 registry().add("gecode_among_seq_bool", &p_among_seq_bool);
01572
01573 registry().add("bool_lin_eq", &p_bool_lin_eq);
01574 registry().add("bool_lin_ne", &p_bool_lin_ne);
01575 registry().add("bool_lin_le", &p_bool_lin_le);
01576 registry().add("bool_lin_lt", &p_bool_lin_lt);
01577 registry().add("bool_lin_ge", &p_bool_lin_ge);
01578 registry().add("bool_lin_gt", &p_bool_lin_gt);
01579
01580 registry().add("bool_lin_eq_reif", &p_bool_lin_eq_reif);
01581 registry().add("bool_lin_eq_imp", &p_bool_lin_eq_imp);
01582 registry().add("bool_lin_ne_reif", &p_bool_lin_ne_reif);
01583 registry().add("bool_lin_ne_imp", &p_bool_lin_ne_imp);
01584 registry().add("bool_lin_le_reif", &p_bool_lin_le_reif);
01585 registry().add("bool_lin_le_imp", &p_bool_lin_le_imp);
01586 registry().add("bool_lin_lt_reif", &p_bool_lin_lt_reif);
01587 registry().add("bool_lin_lt_imp", &p_bool_lin_lt_imp);
01588 registry().add("bool_lin_ge_reif", &p_bool_lin_ge_reif);
01589 registry().add("bool_lin_ge_imp", &p_bool_lin_ge_imp);
01590 registry().add("bool_lin_gt_reif", &p_bool_lin_gt_reif);
01591 registry().add("bool_lin_gt_imp", &p_bool_lin_gt_imp);
01592
01593 registry().add("gecode_schedule_unary", &p_schedule_unary);
01594 registry().add("gecode_schedule_unary_optional", &p_schedule_unary_optional);
01595 registry().add("gecode_schedule_cumulative_optional", &p_cumulative_opt);
01596
01597 registry().add("gecode_circuit", &p_circuit);
01598 registry().add("gecode_circuit_cost_array", &p_circuit_cost_array);
01599 registry().add("gecode_circuit_cost", &p_circuit_cost);
01600 registry().add("gecode_nooverlap", &p_nooverlap);
01601 registry().add("gecode_precede", &p_precede);
01602 registry().add("nvalue",&p_nvalue);
01603 registry().add("among",&p_among);
01604 registry().add("member_int",&p_member_int);
01605 registry().add("gecode_member_int_reif",&p_member_int_reif);
01606 registry().add("member_bool",&p_member_bool);
01607 registry().add("gecode_member_bool_reif",&p_member_bool_reif);
01608 }
01609 };
01610 IntPoster __int_poster;
01611
01612 #ifdef GECODE_HAS_SET_VARS
01613 void p_set_OP(FlatZincSpace& s, SetOpType op,
01614 const ConExpr& ce, AST::Node *) {
01615 rel(s, s.arg2SetVar(ce[0]), op, s.arg2SetVar(ce[1]),
01616 SRT_EQ, s.arg2SetVar(ce[2]));
01617 }
01618 void p_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01619 p_set_OP(s, SOT_UNION, ce, ann);
01620 }
01621 void p_set_intersect(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01622 p_set_OP(s, SOT_INTER, ce, ann);
01623 }
01624 void p_set_diff(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01625 p_set_OP(s, SOT_MINUS, ce, ann);
01626 }
01627
01628 void p_set_symdiff(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01629 SetVar x = s.arg2SetVar(ce[0]);
01630 SetVar y = s.arg2SetVar(ce[1]);
01631
01632 SetVarLubRanges xub(x);
01633 IntSet xubs(xub);
01634 SetVar x_y(s,IntSet::empty,xubs);
01635 rel(s, x, SOT_MINUS, y, SRT_EQ, x_y);
01636
01637 SetVarLubRanges yub(y);
01638 IntSet yubs(yub);
01639 SetVar y_x(s,IntSet::empty,yubs);
01640 rel(s, y, SOT_MINUS, x, SRT_EQ, y_x);
01641
01642 rel(s, x_y, SOT_UNION, y_x, SRT_EQ, s.arg2SetVar(ce[2]));
01643 }
01644
01645 void p_array_set_OP(FlatZincSpace& s, SetOpType op,
01646 const ConExpr& ce, AST::Node *) {
01647 SetVarArgs xs = s.arg2setvarargs(ce[0]);
01648 rel(s, op, xs, s.arg2SetVar(ce[1]));
01649 }
01650 void p_array_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01651 p_array_set_OP(s, SOT_UNION, ce, ann);
01652 }
01653 void p_array_set_partition(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01654 p_array_set_OP(s, SOT_DUNION, ce, ann);
01655 }
01656
01657
01658 void p_set_rel(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
01659 rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]));
01660 }
01661
01662 void p_set_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01663 p_set_rel(s, SRT_EQ, ce);
01664 }
01665 void p_set_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01666 p_set_rel(s, SRT_NQ, ce);
01667 }
01668 void p_set_subset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01669 p_set_rel(s, SRT_SUB, ce);
01670 }
01671 void p_set_superset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01672 p_set_rel(s, SRT_SUP, ce);
01673 }
01674 void p_set_le(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01675 p_set_rel(s, SRT_LQ, ce);
01676 }
01677 void p_set_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01678 p_set_rel(s, SRT_LE, ce);
01679 }
01680 void p_set_card(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01681 if (!ce[1]->isIntVar()) {
01682 cardinality(s, s.arg2SetVar(ce[0]), ce[1]->getInt(),
01683 ce[1]->getInt());
01684 } else {
01685 cardinality(s, s.arg2SetVar(ce[0]), s.arg2IntVar(ce[1]));
01686 }
01687 }
01688 void p_set_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01689 if (!ce[1]->isSetVar()) {
01690 IntSet d = s.arg2intset(ce[1]);
01691 if (ce[0]->isBoolVar()) {
01692 IntSetRanges dr(d);
01693 Iter::Ranges::Singleton sr(0,1);
01694 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01695 IntSet d01(i);
01696 if (d01.size() == 0) {
01697 s.fail();
01698 } else {
01699 rel(s, s.arg2BoolVar(ce[0]), IRT_GQ, d01.min());
01700 rel(s, s.arg2BoolVar(ce[0]), IRT_LQ, d01.max());
01701 }
01702 } else {
01703 dom(s, s.arg2IntVar(ce[0]), d);
01704 }
01705 } else {
01706 if (!ce[0]->isIntVar()) {
01707 dom(s, s.arg2SetVar(ce[1]), SRT_SUP, ce[0]->getInt());
01708 } else {
01709 rel(s, s.arg2SetVar(ce[1]), SRT_SUP, s.arg2IntVar(ce[0]));
01710 }
01711 }
01712 }
01713 void p_set_rel_reif(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
01714 rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]),
01715 s.arg2BoolVar(ce[2]));
01716 }
01717
01718 void p_set_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01719 p_set_rel_reif(s,SRT_EQ,ce);
01720 }
01721 void p_set_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01722 p_set_rel_reif(s,SRT_LQ,ce);
01723 }
01724 void p_set_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01725 p_set_rel_reif(s,SRT_LE,ce);
01726 }
01727 void p_set_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01728 p_set_rel_reif(s,SRT_NQ,ce);
01729 }
01730 void p_set_subset_reif(FlatZincSpace& s, const ConExpr& ce,
01731 AST::Node *) {
01732 p_set_rel_reif(s,SRT_SUB,ce);
01733 }
01734 void p_set_superset_reif(FlatZincSpace& s, const ConExpr& ce,
01735 AST::Node *) {
01736 p_set_rel_reif(s,SRT_SUP,ce);
01737 }
01738 void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann, ReifyMode rm) {
01739 if (!ce[1]->isSetVar()) {
01740 if (rm==RM_EQV) {
01741 p_int_in_reif(s,ce,ann);
01742 } else {
01743 assert(rm==RM_IMP);
01744 p_int_in_imp(s,ce,ann);
01745 }
01746 } else {
01747 if (!ce[0]->isIntVar()) {
01748 dom(s, s.arg2SetVar(ce[1]), SRT_SUP, ce[0]->getInt(),
01749 Reify(s.arg2BoolVar(ce[2]),rm));
01750 } else {
01751 rel(s, s.arg2SetVar(ce[1]), SRT_SUP, s.arg2IntVar(ce[0]),
01752 Reify(s.arg2BoolVar(ce[2]),rm));
01753 }
01754 }
01755 }
01756 void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01757 p_set_in_reif(s,ce,ann,RM_EQV);
01758 }
01759 void p_set_in_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01760 p_set_in_reif(s,ce,ann,RM_IMP);
01761 }
01762 void p_set_disjoint(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01763 rel(s, s.arg2SetVar(ce[0]), SRT_DISJ, s.arg2SetVar(ce[1]));
01764 }
01765
01766 void p_link_set_to_booleans(FlatZincSpace& s, const ConExpr& ce,
01767 AST::Node *) {
01768 SetVar x = s.arg2SetVar(ce[0]);
01769 int idx = ce[2]->getInt();
01770 assert(idx >= 0);
01771 rel(s, x || IntSet(Set::Limits::min,idx-1));
01772 BoolVarArgs y = s.arg2boolvarargs(ce[1],idx);
01773 unshare(s, y);
01774 channel(s, y, x);
01775 }
01776
01777 void p_array_set_element(FlatZincSpace& s, const ConExpr& ce,
01778 AST::Node*) {
01779 bool isConstant = true;
01780 AST::Array* a = ce[1]->getArray();
01781 for (int i=a->a.size(); i--;) {
01782 if (a->a[i]->isSetVar()) {
01783 isConstant = false;
01784 break;
01785 }
01786 }
01787 IntVar selector = s.arg2IntVar(ce[0]);
01788 rel(s, selector > 0);
01789 if (isConstant) {
01790 IntSetArgs sv = s.arg2intsetargs(ce[1],1);
01791 element(s, sv, selector, s.arg2SetVar(ce[2]));
01792 } else {
01793 SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
01794 element(s, sv, selector, s.arg2SetVar(ce[2]));
01795 }
01796 }
01797
01798 void p_array_set_element_op(FlatZincSpace& s, const ConExpr& ce,
01799 AST::Node*, SetOpType op,
01800 const IntSet& universe =
01801 IntSet(Set::Limits::min,Set::Limits::max)) {
01802 bool isConstant = true;
01803 AST::Array* a = ce[1]->getArray();
01804 for (int i=a->a.size(); i--;) {
01805 if (a->a[i]->isSetVar()) {
01806 isConstant = false;
01807 break;
01808 }
01809 }
01810 SetVar selector = s.arg2SetVar(ce[0]);
01811 dom(s, selector, SRT_DISJ, 0);
01812 if (isConstant) {
01813 IntSetArgs sv = s.arg2intsetargs(ce[1], 1);
01814 element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
01815 } else {
01816 SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
01817 element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
01818 }
01819 }
01820
01821 void p_array_set_element_union(FlatZincSpace& s, const ConExpr& ce,
01822 AST::Node* ann) {
01823 p_array_set_element_op(s, ce, ann, SOT_UNION);
01824 }
01825
01826 void p_array_set_element_intersect(FlatZincSpace& s, const ConExpr& ce,
01827 AST::Node* ann) {
01828 p_array_set_element_op(s, ce, ann, SOT_INTER);
01829 }
01830
01831 void p_array_set_element_intersect_in(FlatZincSpace& s,
01832 const ConExpr& ce,
01833 AST::Node* ann) {
01834 IntSet d = s.arg2intset(ce[3]);
01835 p_array_set_element_op(s, ce, ann, SOT_INTER, d);
01836 }
01837
01838 void p_array_set_element_partition(FlatZincSpace& s, const ConExpr& ce,
01839 AST::Node* ann) {
01840 p_array_set_element_op(s, ce, ann, SOT_DUNION);
01841 }
01842
01843 void p_set_convex(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01844 convex(s, s.arg2SetVar(ce[0]));
01845 }
01846
01847 void p_array_set_seq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01848 SetVarArgs sv = s.arg2setvarargs(ce[0]);
01849 sequence(s, sv);
01850 }
01851
01852 void p_array_set_seq_union(FlatZincSpace& s, const ConExpr& ce,
01853 AST::Node *) {
01854 SetVarArgs sv = s.arg2setvarargs(ce[0]);
01855 sequence(s, sv, s.arg2SetVar(ce[1]));
01856 }
01857
01858 void p_int_set_channel(FlatZincSpace& s, const ConExpr& ce,
01859 AST::Node *) {
01860 int xoff=ce[1]->getInt();
01861 assert(xoff >= 0);
01862 int yoff=ce[3]->getInt();
01863 assert(yoff >= 0);
01864 IntVarArgs xv = s.arg2intvarargs(ce[0], xoff);
01865 SetVarArgs yv = s.arg2setvarargs(ce[2], yoff, 1, IntSet(0, xoff-1));
01866 IntSet xd(yoff,yv.size()-1);
01867 for (int i=xoff; i<xv.size(); i++) {
01868 dom(s, xv[i], xd);
01869 }
01870 IntSet yd(xoff,xv.size()-1);
01871 for (int i=yoff; i<yv.size(); i++) {
01872 dom(s, yv[i], SRT_SUB, yd);
01873 }
01874 channel(s,xv,yv);
01875 }
01876
01877 void p_range(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01878 int xoff=ce[1]->getInt();
01879 assert(xoff >= 0);
01880 IntVarArgs xv = s.arg2intvarargs(ce[0],xoff);
01881 element(s, SOT_UNION, xv, s.arg2SetVar(ce[2]), s.arg2SetVar(ce[3]));
01882 }
01883
01884 void p_weights(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01885 IntArgs e = s.arg2intargs(ce[0]);
01886 IntArgs w = s.arg2intargs(ce[1]);
01887 SetVar x = s.arg2SetVar(ce[2]);
01888 IntVar y = s.arg2IntVar(ce[3]);
01889 weights(s,e,w,x,y);
01890 }
01891
01892 void p_inverse_set(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01893 int xoff = ce[2]->getInt();
01894 int yoff = ce[3]->getInt();
01895 SetVarArgs x = s.arg2setvarargs(ce[0],xoff);
01896 SetVarArgs y = s.arg2setvarargs(ce[1],yoff);
01897 channel(s, x, y);
01898 }
01899
01900 void p_precede_set(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01901 SetVarArgs x = s.arg2setvarargs(ce[0]);
01902 int p_s = ce[1]->getInt();
01903 int p_t = ce[2]->getInt();
01904 precede(s,x,p_s,p_t);
01905 }
01906
01907 class SetPoster {
01908 public:
01909 SetPoster(void) {
01910 registry().add("set_eq", &p_set_eq);
01911 registry().add("set_le", &p_set_le);
01912 registry().add("set_lt", &p_set_lt);
01913 registry().add("equal", &p_set_eq);
01914 registry().add("set_ne", &p_set_ne);
01915 registry().add("set_union", &p_set_union);
01916 registry().add("array_set_element", &p_array_set_element);
01917 registry().add("array_var_set_element", &p_array_set_element);
01918 registry().add("set_intersect", &p_set_intersect);
01919 registry().add("set_diff", &p_set_diff);
01920 registry().add("set_symdiff", &p_set_symdiff);
01921 registry().add("set_subset", &p_set_subset);
01922 registry().add("set_superset", &p_set_superset);
01923 registry().add("set_card", &p_set_card);
01924 registry().add("set_in", &p_set_in);
01925 registry().add("set_eq_reif", &p_set_eq_reif);
01926 registry().add("set_le_reif", &p_set_le_reif);
01927 registry().add("set_lt_reif", &p_set_lt_reif);
01928 registry().add("equal_reif", &p_set_eq_reif);
01929 registry().add("set_ne_reif", &p_set_ne_reif);
01930 registry().add("set_subset_reif", &p_set_subset_reif);
01931 registry().add("set_superset_reif", &p_set_superset_reif);
01932 registry().add("set_in_reif", &p_set_in_reif);
01933 registry().add("set_in_imp", &p_set_in_imp);
01934 registry().add("disjoint", &p_set_disjoint);
01935 registry().add("gecode_link_set_to_booleans",
01936 &p_link_set_to_booleans);
01937
01938 registry().add("array_set_union", &p_array_set_union);
01939 registry().add("array_set_partition", &p_array_set_partition);
01940 registry().add("set_convex", &p_set_convex);
01941 registry().add("array_set_seq", &p_array_set_seq);
01942 registry().add("array_set_seq_union", &p_array_set_seq_union);
01943 registry().add("gecode_array_set_element_union",
01944 &p_array_set_element_union);
01945 registry().add("gecode_array_set_element_intersect",
01946 &p_array_set_element_intersect);
01947 registry().add("gecode_array_set_element_intersect_in",
01948 &p_array_set_element_intersect_in);
01949 registry().add("gecode_array_set_element_partition",
01950 &p_array_set_element_partition);
01951 registry().add("gecode_int_set_channel",
01952 &p_int_set_channel);
01953 registry().add("gecode_range",
01954 &p_range);
01955 registry().add("gecode_set_weights",
01956 &p_weights);
01957 registry().add("gecode_inverse_set", &p_inverse_set);
01958 registry().add("gecode_precede_set", &p_precede_set);
01959 }
01960 };
01961 SetPoster __set_poster;
01962 #endif
01963
01964 #ifdef GECODE_HAS_FLOAT_VARS
01965
01966 void p_int2float(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01967 IntVar x0 = s.arg2IntVar(ce[0]);
01968 FloatVar x1 = s.arg2FloatVar(ce[1]);
01969 channel(s, x0, x1);
01970 }
01971
01972 void p_float_lin_cmp(FlatZincSpace& s, FloatRelType frt,
01973 const ConExpr& ce, AST::Node*) {
01974 FloatValArgs fa = s.arg2floatargs(ce[0]);
01975 FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
01976 linear(s, fa, fv, frt, ce[2]->getFloat());
01977 }
01978 void p_float_lin_cmp_reif(FlatZincSpace& s, FloatRelType frt,
01979 const ConExpr& ce, AST::Node*) {
01980 FloatValArgs fa = s.arg2floatargs(ce[0]);
01981 FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
01982 linear(s, fa, fv, frt, ce[2]->getFloat(), s.arg2BoolVar(ce[3]));
01983 }
01984 void p_float_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01985 p_float_lin_cmp(s,FRT_EQ,ce,ann);
01986 }
01987 void p_float_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce,
01988 AST::Node* ann) {
01989 p_float_lin_cmp_reif(s,FRT_EQ,ce,ann);
01990 }
01991 void p_float_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01992 p_float_lin_cmp(s,FRT_LQ,ce,ann);
01993 }
01994 void p_float_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01995 p_float_lin_cmp(s,FRT_LE,ce,ann);
01996 }
01997 void p_float_lin_le_reif(FlatZincSpace& s, const ConExpr& ce,
01998 AST::Node* ann) {
01999 p_float_lin_cmp_reif(s,FRT_LQ,ce,ann);
02000 }
02001 void p_float_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce,
02002 AST::Node* ann) {
02003 p_float_lin_cmp_reif(s,FRT_LE,ce,ann);
02004 }
02005
02006 void p_float_times(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02007 FloatVar x = s.arg2FloatVar(ce[0]);
02008 FloatVar y = s.arg2FloatVar(ce[1]);
02009 FloatVar z = s.arg2FloatVar(ce[2]);
02010 mult(s,x,y,z);
02011 }
02012
02013 void p_float_div(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02014 FloatVar x = s.arg2FloatVar(ce[0]);
02015 FloatVar y = s.arg2FloatVar(ce[1]);
02016 FloatVar z = s.arg2FloatVar(ce[2]);
02017 div(s,x,y,z);
02018 }
02019
02020 void p_float_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02021 FloatVar x = s.arg2FloatVar(ce[0]);
02022 FloatVar y = s.arg2FloatVar(ce[1]);
02023 FloatVar z = s.arg2FloatVar(ce[2]);
02024 rel(s,x+y==z);
02025 }
02026
02027 void p_float_sqrt(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02028 FloatVar x = s.arg2FloatVar(ce[0]);
02029 FloatVar y = s.arg2FloatVar(ce[1]);
02030 sqrt(s,x,y);
02031 }
02032
02033 void p_float_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02034 FloatVar x = s.arg2FloatVar(ce[0]);
02035 FloatVar y = s.arg2FloatVar(ce[1]);
02036 abs(s,x,y);
02037 }
02038
02039 void p_float_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02040 FloatVar x = s.arg2FloatVar(ce[0]);
02041 FloatVar y = s.arg2FloatVar(ce[1]);
02042 rel(s,x,FRT_EQ,y);
02043 }
02044 void p_float_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02045 FloatVar x = s.arg2FloatVar(ce[0]);
02046 FloatVar y = s.arg2FloatVar(ce[1]);
02047 BoolVar b = s.arg2BoolVar(ce[2]);
02048 rel(s,x,FRT_EQ,y,b);
02049 }
02050 void p_float_le(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02051 FloatVar x = s.arg2FloatVar(ce[0]);
02052 FloatVar y = s.arg2FloatVar(ce[1]);
02053 rel(s,x,FRT_LQ,y);
02054 }
02055 void p_float_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02056 FloatVar x = s.arg2FloatVar(ce[0]);
02057 FloatVar y = s.arg2FloatVar(ce[1]);
02058 BoolVar b = s.arg2BoolVar(ce[2]);
02059 rel(s,x,FRT_LQ,y,b);
02060 }
02061 void p_float_max(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02062 FloatVar x = s.arg2FloatVar(ce[0]);
02063 FloatVar y = s.arg2FloatVar(ce[1]);
02064 FloatVar z = s.arg2FloatVar(ce[2]);
02065 max(s,x,y,z);
02066 }
02067 void p_float_min(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02068 FloatVar x = s.arg2FloatVar(ce[0]);
02069 FloatVar y = s.arg2FloatVar(ce[1]);
02070 FloatVar z = s.arg2FloatVar(ce[2]);
02071 min(s,x,y,z);
02072 }
02073 void p_float_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02074 FloatVar x = s.arg2FloatVar(ce[0]);
02075 FloatVar y = s.arg2FloatVar(ce[1]);
02076 rel(s, x, FRT_LQ, y);
02077 rel(s, x, FRT_EQ, y, BoolVar(s,0,0));
02078 }
02079
02080 void p_float_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02081 FloatVar x = s.arg2FloatVar(ce[0]);
02082 FloatVar y = s.arg2FloatVar(ce[1]);
02083 BoolVar b = s.arg2BoolVar(ce[2]);
02084 BoolVar b0(s,0,1);
02085 BoolVar b1(s,0,1);
02086 rel(s, b == (b0 && !b1));
02087 rel(s, x, FRT_LQ, y, b0);
02088 rel(s, x, FRT_EQ, y, b1);
02089 }
02090
02091 void p_float_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02092 FloatVar x = s.arg2FloatVar(ce[0]);
02093 FloatVar y = s.arg2FloatVar(ce[1]);
02094 rel(s, x, FRT_EQ, y, BoolVar(s,0,0));
02095 }
02096
02097 #ifdef GECODE_HAS_MPFR
02098 #define P_FLOAT_OP(Op) \
02099 void p_float_ ## Op (FlatZincSpace& s, const ConExpr& ce, AST::Node*) {\
02100 FloatVar x = s.arg2FloatVar(ce[0]);\
02101 FloatVar y = s.arg2FloatVar(ce[1]);\
02102 Op(s,x,y);\
02103 }
02104 P_FLOAT_OP(acos)
02105 P_FLOAT_OP(asin)
02106 P_FLOAT_OP(atan)
02107 P_FLOAT_OP(cos)
02108 P_FLOAT_OP(exp)
02109 P_FLOAT_OP(sin)
02110 P_FLOAT_OP(tan)
02111
02112
02113
02114 #undef P_FLOAT_OP
02115
02116 void p_float_ln(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02117 FloatVar x = s.arg2FloatVar(ce[0]);
02118 FloatVar y = s.arg2FloatVar(ce[1]);
02119 log(s,x,y);
02120 }
02121 void p_float_log10(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02122 FloatVar x = s.arg2FloatVar(ce[0]);
02123 FloatVar y = s.arg2FloatVar(ce[1]);
02124 log(s,10.0,x,y);
02125 }
02126 void p_float_log2(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02127 FloatVar x = s.arg2FloatVar(ce[0]);
02128 FloatVar y = s.arg2FloatVar(ce[1]);
02129 log(s,2.0,x,y);
02130 }
02131
02132 #endif
02133
02134 class FloatPoster {
02135 public:
02136 FloatPoster(void) {
02137 registry().add("int2float",&p_int2float);
02138 registry().add("float_abs",&p_float_abs);
02139 registry().add("float_sqrt",&p_float_sqrt);
02140 registry().add("float_eq",&p_float_eq);
02141 registry().add("float_eq_reif",&p_float_eq_reif);
02142 registry().add("float_le",&p_float_le);
02143 registry().add("float_le_reif",&p_float_le_reif);
02144 registry().add("float_lt",&p_float_lt);
02145 registry().add("float_lt_reif",&p_float_lt_reif);
02146 registry().add("float_ne",&p_float_ne);
02147 registry().add("float_times",&p_float_times);
02148 registry().add("float_div",&p_float_div);
02149 registry().add("float_plus",&p_float_plus);
02150 registry().add("float_max",&p_float_max);
02151 registry().add("float_min",&p_float_min);
02152
02153 registry().add("float_lin_eq",&p_float_lin_eq);
02154 registry().add("float_lin_eq_reif",&p_float_lin_eq_reif);
02155 registry().add("float_lin_le",&p_float_lin_le);
02156 registry().add("float_lin_lt",&p_float_lin_lt);
02157 registry().add("float_lin_le_reif",&p_float_lin_le_reif);
02158 registry().add("float_lin_lt_reif",&p_float_lin_lt_reif);
02159
02160 #ifdef GECODE_HAS_MPFR
02161 registry().add("float_acos",&p_float_acos);
02162 registry().add("float_asin",&p_float_asin);
02163 registry().add("float_atan",&p_float_atan);
02164 registry().add("float_cos",&p_float_cos);
02165
02166 registry().add("float_exp",&p_float_exp);
02167 registry().add("float_ln",&p_float_ln);
02168 registry().add("float_log10",&p_float_log10);
02169 registry().add("float_log2",&p_float_log2);
02170 registry().add("float_sin",&p_float_sin);
02171
02172 registry().add("float_tan",&p_float_tan);
02173
02174 #endif
02175 }
02176 } __float_poster;
02177 #endif
02178
02179 }
02180 }}
02181
02182