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