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 TupleSet ts = s.arg2tupleset(ce[1],x.size());
01140 extensional(s,x,ts,s.ann2ipl(ann));
01141 }
01142
01143 void
01144 p_table_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01145 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01146 IntArgs tuples = s.arg2boolargs(ce[1]);
01147 int noOfVars = x.size();
01148 int noOfTuples = tuples.size() == 0 ? 0 : (tuples.size()/noOfVars);
01149 TupleSet ts(noOfVars);
01150 for (int i=0; i<noOfTuples; i++) {
01151 IntArgs t(noOfVars);
01152 for (int j=0; j<x.size(); j++) {
01153 t[j] = tuples[i*noOfVars+j];
01154 }
01155 ts.add(t);
01156 }
01157 ts.finalize();
01158 extensional(s,x,ts,s.ann2ipl(ann));
01159 }
01160
01161 void p_cumulative_opt(FlatZincSpace& s, const ConExpr& ce,
01162 AST::Node* ann) {
01163 IntVarArgs start = s.arg2intvarargs(ce[0]);
01164 IntArgs duration = s.arg2intargs(ce[1]);
01165 IntArgs height = s.arg2intargs(ce[2]);
01166 BoolVarArgs opt = s.arg2boolvarargs(ce[3]);
01167 int bound = ce[4]->getInt();
01168 unshare(s,start);
01169 cumulative(s,bound,start,duration,height,opt,s.ann2ipl(ann));
01170 }
01171
01172 void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
01173 AST::Node* ann) {
01174 IntVarArgs start = s.arg2intvarargs(ce[0]);
01175 IntVarArgs duration = s.arg2intvarargs(ce[1]);
01176 IntVarArgs height = s.arg2intvarargs(ce[2]);
01177 int n = start.size();
01178 IntVar bound = s.arg2IntVar(ce[3]);
01179
01180 if (n==0)
01181 return;
01182
01183 if (n == 1) {
01184 rel(s, height[0] <= bound);
01185 return;
01186 }
01187
01188 int minHeight = std::min(height[0].min(),height[1].min());
01189 int minHeight2 = std::max(height[0].min(),height[1].min());
01190 for (int i=2; i<n; i++) {
01191 if (height[i].min() < minHeight) {
01192 minHeight2 = minHeight;
01193 minHeight = height[i].min();
01194 } else if (height[i].min() < minHeight2) {
01195 minHeight2 = height[i].min();
01196 }
01197 }
01198 bool disjunctive =
01199 (minHeight > bound.max()/2) ||
01200 (minHeight2 > bound.max()/2 && minHeight+minHeight2>bound.max());
01201 if (disjunctive) {
01202 rel(s, bound >= max(height));
01203
01204 if (duration.assigned()) {
01205 IntArgs durationI(n);
01206 for (int i=n; i--;)
01207 durationI[i] = duration[i].val();
01208 unshare(s,start);
01209 unary(s,start,durationI);
01210 } else {
01211 IntVarArgs end(n);
01212 for (int i=n; i--;)
01213 end[i] = expr(s,start[i]+duration[i]);
01214 unshare(s,start);
01215 unary(s,start,duration,end);
01216 }
01217 } else if (height.assigned()) {
01218 IntArgs heightI(n);
01219 for (int i=n; i--;)
01220 heightI[i] = height[i].val();
01221 if (duration.assigned()) {
01222 IntArgs durationI(n);
01223 for (int i=n; i--;)
01224 durationI[i] = duration[i].val();
01225 cumulative(s, bound, start, durationI, heightI);
01226 } else {
01227 IntVarArgs end(n);
01228 for (int i = n; i--; )
01229 end[i] = expr(s,start[i]+duration[i]);
01230 cumulative(s, bound, start, duration, end, heightI);
01231 }
01232 } else if (bound.assigned()) {
01233 IntArgs machine = IntArgs::create(n,0,0);
01234 IntArgs limit(1, bound.val());
01235 IntVarArgs end(n);
01236 for (int i=n; i--;)
01237 end[i] = expr(s,start[i]+duration[i]);
01238 cumulatives(s, machine, start, duration, end, height, limit, true,
01239 s.ann2ipl(ann));
01240 } else {
01241 int min = Gecode::Int::Limits::max;
01242 int max = Gecode::Int::Limits::min;
01243 IntVarArgs end(start.size());
01244 for (int i = start.size(); i--; ) {
01245 min = std::min(min, start[i].min());
01246 max = std::max(max, start[i].max() + duration[i].max());
01247 end[i] = expr(s, start[i] + duration[i]);
01248 }
01249 for (int time = min; time < max; ++time) {
01250 IntVarArgs x(start.size());
01251 for (int i = start.size(); i--; ) {
01252 IntVar overlaps = channel(s, expr(s, (start[i] <= time) &&
01253 (time < end[i])));
01254 x[i] = expr(s, overlaps * height[i]);
01255 }
01256 linear(s, x, IRT_LQ, bound);
01257 }
01258 }
01259 }
01260
01261 void p_among_seq_int(FlatZincSpace& s, const ConExpr& ce,
01262 AST::Node* ann) {
01263 IntVarArgs x = s.arg2intvarargs(ce[0]);
01264 IntSet S = s.arg2intset(ce[1]);
01265 int q = ce[2]->getInt();
01266 int l = ce[3]->getInt();
01267 int u = ce[4]->getInt();
01268 unshare(s, x);
01269 sequence(s, x, S, q, l, u, s.ann2ipl(ann));
01270 }
01271
01272 void p_among_seq_bool(FlatZincSpace& s, const ConExpr& ce,
01273 AST::Node* ann) {
01274 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01275 bool val = ce[1]->getBool();
01276 int q = ce[2]->getInt();
01277 int l = ce[3]->getInt();
01278 int u = ce[4]->getInt();
01279 IntSet S(val, val);
01280 unshare(s, x);
01281 sequence(s, x, S, q, l, u, s.ann2ipl(ann));
01282 }
01283
01284 void p_schedule_unary(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01285 IntVarArgs x = s.arg2intvarargs(ce[0]);
01286 IntArgs p = s.arg2intargs(ce[1]);
01287 unshare(s,x);
01288 unary(s, x, p);
01289 }
01290
01291 void p_schedule_unary_optional(FlatZincSpace& s, const ConExpr& ce,
01292 AST::Node*) {
01293 IntVarArgs x = s.arg2intvarargs(ce[0]);
01294 IntArgs p = s.arg2intargs(ce[1]);
01295 BoolVarArgs m = s.arg2boolvarargs(ce[2]);
01296 unshare(s,x);
01297 unary(s, x, p, m);
01298 }
01299
01300 void p_circuit(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01301 int off = ce[0]->getInt();
01302 IntVarArgs xv = s.arg2intvarargs(ce[1]);
01303 unshare(s,xv);
01304 circuit(s,off,xv,s.ann2ipl(ann));
01305 }
01306 void p_circuit_cost_array(FlatZincSpace& s, const ConExpr& ce,
01307 AST::Node *ann) {
01308 IntArgs c = s.arg2intargs(ce[0]);
01309 IntVarArgs xv = s.arg2intvarargs(ce[1]);
01310 IntVarArgs yv = s.arg2intvarargs(ce[2]);
01311 IntVar z = s.arg2IntVar(ce[3]);
01312 unshare(s,xv);
01313 circuit(s,c,xv,yv,z,s.ann2ipl(ann));
01314 }
01315 void p_circuit_cost(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01316 IntArgs c = s.arg2intargs(ce[0]);
01317 IntVarArgs xv = s.arg2intvarargs(ce[1]);
01318 IntVar z = s.arg2IntVar(ce[2]);
01319 unshare(s,xv);
01320 circuit(s,c,xv,z,s.ann2ipl(ann));
01321 }
01322
01323 void p_nooverlap(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01324 IntVarArgs x0 = s.arg2intvarargs(ce[0]);
01325 IntVarArgs w = s.arg2intvarargs(ce[1]);
01326 IntVarArgs y0 = s.arg2intvarargs(ce[2]);
01327 IntVarArgs h = s.arg2intvarargs(ce[3]);
01328 if (w.assigned() && h.assigned()) {
01329 IntArgs iw(w.size());
01330 for (int i=w.size(); i--;)
01331 iw[i] = w[i].val();
01332 IntArgs ih(h.size());
01333 for (int i=h.size(); i--;)
01334 ih[i] = h[i].val();
01335 nooverlap(s,x0,iw,y0,ih,s.ann2ipl(ann));
01336
01337 int miny = y0[0].min();
01338 int maxy = y0[0].max();
01339 int maxdy = ih[0];
01340 for (int i=1; i<y0.size(); i++) {
01341 miny = std::min(miny,y0[i].min());
01342 maxy = std::max(maxy,y0[i].max());
01343 maxdy = std::max(maxdy,ih[i]);
01344 }
01345 int minx = x0[0].min();
01346 int maxx = x0[0].max();
01347 int maxdx = iw[0];
01348 for (int i=1; i<x0.size(); i++) {
01349 minx = std::min(minx,x0[i].min());
01350 maxx = std::max(maxx,x0[i].max());
01351 maxdx = std::max(maxdx,iw[i]);
01352 }
01353 if (miny > Int::Limits::min && maxy < Int::Limits::max) {
01354 cumulative(s,maxdy+maxy-miny,x0,iw,ih);
01355 cumulative(s,maxdx+maxx-minx,y0,ih,iw);
01356 }
01357 } else {
01358 IntVarArgs x1(x0.size()), y1(y0.size());
01359 for (int i=x0.size(); i--; )
01360 x1[i] = expr(s, x0[i] + w[i]);
01361 for (int i=y0.size(); i--; )
01362 y1[i] = expr(s, y0[i] + h[i]);
01363 nooverlap(s,x0,w,x1,y0,h,y1,s.ann2ipl(ann));
01364 }
01365 }
01366
01367 void p_precede(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01368 IntVarArgs x = s.arg2intvarargs(ce[0]);
01369 int p_s = ce[1]->getInt();
01370 int p_t = ce[2]->getInt();
01371 precede(s,x,p_s,p_t,s.ann2ipl(ann));
01372 }
01373
01374 void p_nvalue(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01375 IntVarArgs x = s.arg2intvarargs(ce[1]);
01376 if (ce[0]->isIntVar()) {
01377 IntVar y = s.arg2IntVar(ce[0]);
01378 nvalues(s,x,IRT_EQ,y,s.ann2ipl(ann));
01379 } else {
01380 nvalues(s,x,IRT_EQ,ce[0]->getInt(),s.ann2ipl(ann));
01381 }
01382 }
01383
01384 void p_among(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01385 IntVarArgs x = s.arg2intvarargs(ce[1]);
01386 IntSet v = s.arg2intset(ce[2]);
01387 if (ce[0]->isIntVar()) {
01388 IntVar n = s.arg2IntVar(ce[0]);
01389 unshare(s, x);
01390 count(s,x,v,IRT_EQ,n,s.ann2ipl(ann));
01391 } else {
01392 unshare(s, x);
01393 count(s,x,v,IRT_EQ,ce[0]->getInt(),s.ann2ipl(ann));
01394 }
01395 }
01396
01397 void p_member_int(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01398 IntVarArgs x = s.arg2intvarargs(ce[0]);
01399 IntVar y = s.arg2IntVar(ce[1]);
01400 member(s,x,y,s.ann2ipl(ann));
01401 }
01402 void p_member_int_reif(FlatZincSpace& s, const ConExpr& ce,
01403 AST::Node* ann) {
01404 IntVarArgs x = s.arg2intvarargs(ce[0]);
01405 IntVar y = s.arg2IntVar(ce[1]);
01406 BoolVar b = s.arg2BoolVar(ce[2]);
01407 member(s,x,y,b,s.ann2ipl(ann));
01408 }
01409 void p_member_bool(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01410 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01411 BoolVar y = s.arg2BoolVar(ce[1]);
01412 member(s,x,y,s.ann2ipl(ann));
01413 }
01414 void p_member_bool_reif(FlatZincSpace& s, const ConExpr& ce,
01415 AST::Node* ann) {
01416 BoolVarArgs x = s.arg2boolvarargs(ce[0]);
01417 BoolVar y = s.arg2BoolVar(ce[1]);
01418 member(s,x,y,s.arg2BoolVar(ce[2]),s.ann2ipl(ann));
01419 }
01420
01421 class IntPoster {
01422 public:
01423 IntPoster(void) {
01424 registry().add("all_different_int", &p_distinct);
01425 registry().add("all_different_offset", &p_distinctOffset);
01426 registry().add("all_equal_int", &p_all_equal);
01427 registry().add("int_eq", &p_int_eq);
01428 registry().add("int_ne", &p_int_ne);
01429 registry().add("int_ge", &p_int_ge);
01430 registry().add("int_gt", &p_int_gt);
01431 registry().add("int_le", &p_int_le);
01432 registry().add("int_lt", &p_int_lt);
01433 registry().add("int_eq_reif", &p_int_eq_reif);
01434 registry().add("int_ne_reif", &p_int_ne_reif);
01435 registry().add("int_ge_reif", &p_int_ge_reif);
01436 registry().add("int_gt_reif", &p_int_gt_reif);
01437 registry().add("int_le_reif", &p_int_le_reif);
01438 registry().add("int_lt_reif", &p_int_lt_reif);
01439 registry().add("int_eq_imp", &p_int_eq_imp);
01440 registry().add("int_ne_imp", &p_int_ne_imp);
01441 registry().add("int_ge_imp", &p_int_ge_imp);
01442 registry().add("int_gt_imp", &p_int_gt_imp);
01443 registry().add("int_le_imp", &p_int_le_imp);
01444 registry().add("int_lt_imp", &p_int_lt_imp);
01445 registry().add("int_lin_eq", &p_int_lin_eq);
01446 registry().add("int_lin_eq_reif", &p_int_lin_eq_reif);
01447 registry().add("int_lin_eq_imp", &p_int_lin_eq_imp);
01448 registry().add("int_lin_ne", &p_int_lin_ne);
01449 registry().add("int_lin_ne_reif", &p_int_lin_ne_reif);
01450 registry().add("int_lin_ne_imp", &p_int_lin_ne_imp);
01451 registry().add("int_lin_le", &p_int_lin_le);
01452 registry().add("int_lin_le_reif", &p_int_lin_le_reif);
01453 registry().add("int_lin_le_imp", &p_int_lin_le_imp);
01454 registry().add("int_lin_lt", &p_int_lin_lt);
01455 registry().add("int_lin_lt_reif", &p_int_lin_lt_reif);
01456 registry().add("int_lin_lt_imp", &p_int_lin_lt_imp);
01457 registry().add("int_lin_ge", &p_int_lin_ge);
01458 registry().add("int_lin_ge_reif", &p_int_lin_ge_reif);
01459 registry().add("int_lin_ge_imp", &p_int_lin_ge_imp);
01460 registry().add("int_lin_gt", &p_int_lin_gt);
01461 registry().add("int_lin_gt_reif", &p_int_lin_gt_reif);
01462 registry().add("int_lin_gt_imp", &p_int_lin_gt_imp);
01463 registry().add("int_plus", &p_int_plus);
01464 registry().add("int_minus", &p_int_minus);
01465 registry().add("int_times", &p_int_times);
01466 registry().add("gecode_int_pow", &p_int_pow);
01467 registry().add("int_div", &p_int_div);
01468 registry().add("int_mod", &p_int_mod);
01469 registry().add("int_min", &p_int_min);
01470 registry().add("int_max", &p_int_max);
01471 registry().add("int_abs", &p_abs);
01472 registry().add("int_negate", &p_int_negate);
01473 registry().add("bool_eq", &p_bool_eq);
01474 registry().add("bool_eq_reif", &p_bool_eq_reif);
01475 registry().add("bool_eq_imp", &p_bool_eq_imp);
01476 registry().add("bool_ne", &p_bool_ne);
01477 registry().add("bool_ne_reif", &p_bool_ne_reif);
01478 registry().add("bool_ne_imp", &p_bool_ne_imp);
01479 registry().add("bool_ge", &p_bool_ge);
01480 registry().add("bool_ge_reif", &p_bool_ge_reif);
01481 registry().add("bool_ge_imp", &p_bool_ge_imp);
01482 registry().add("bool_le", &p_bool_le);
01483 registry().add("bool_le_reif", &p_bool_le_reif);
01484 registry().add("bool_le_imp", &p_bool_le_imp);
01485 registry().add("bool_gt", &p_bool_gt);
01486 registry().add("bool_gt_reif", &p_bool_gt_reif);
01487 registry().add("bool_gt_imp", &p_bool_gt_imp);
01488 registry().add("bool_lt", &p_bool_lt);
01489 registry().add("bool_lt_reif", &p_bool_lt_reif);
01490 registry().add("bool_lt_imp", &p_bool_lt_imp);
01491 registry().add("bool_or", &p_bool_or);
01492 registry().add("bool_or_imp", &p_bool_or_imp);
01493 registry().add("bool_and", &p_bool_and);
01494 registry().add("bool_and_imp", &p_bool_and_imp);
01495 registry().add("bool_xor", &p_bool_xor);
01496 registry().add("bool_xor_imp", &p_bool_xor_imp);
01497 registry().add("array_bool_and", &p_array_bool_and);
01498 registry().add("array_bool_and_imp", &p_array_bool_and_imp);
01499 registry().add("array_bool_or", &p_array_bool_or);
01500 registry().add("array_bool_or_imp", &p_array_bool_or_imp);
01501 registry().add("array_bool_xor", &p_array_bool_xor);
01502 registry().add("array_bool_xor_imp", &p_array_bool_xor_imp);
01503 registry().add("bool_clause", &p_array_bool_clause);
01504 registry().add("bool_clause_reif", &p_array_bool_clause_reif);
01505 registry().add("bool_clause_imp", &p_array_bool_clause_imp);
01506 registry().add("bool_left_imp", &p_bool_l_imp);
01507 registry().add("bool_right_imp", &p_bool_r_imp);
01508 registry().add("bool_not", &p_bool_not);
01509 registry().add("array_int_element", &p_array_int_element);
01510 registry().add("array_var_int_element", &p_array_int_element);
01511 registry().add("array_bool_element", &p_array_bool_element);
01512 registry().add("array_var_bool_element", &p_array_bool_element);
01513 registry().add("bool2int", &p_bool2int);
01514 registry().add("int_in", &p_int_in);
01515 registry().add("int_in_reif", &p_int_in_reif);
01516 registry().add("int_in_imp", &p_int_in_imp);
01517 #ifndef GECODE_HAS_SET_VARS
01518 registry().add("set_in", &p_int_in);
01519 registry().add("set_in_reif", &p_int_in_reif);
01520 registry().add("set_in_imp", &p_int_in_imp);
01521 #endif
01522
01523 registry().add("array_int_lt", &p_array_int_lt);
01524 registry().add("array_int_lq", &p_array_int_lq);
01525 registry().add("array_bool_lt", &p_array_bool_lt);
01526 registry().add("array_bool_lq", &p_array_bool_lq);
01527 registry().add("count", &p_count);
01528 registry().add("count_reif", &p_count_reif);
01529 registry().add("count_imp", &p_count_imp);
01530 registry().add("at_least_int", &p_at_least);
01531 registry().add("at_most_int", &p_at_most);
01532 registry().add("gecode_bin_packing_load", &p_bin_packing_load);
01533 registry().add("gecode_global_cardinality", &p_global_cardinality);
01534 registry().add("gecode_global_cardinality_closed",
01535 &p_global_cardinality_closed);
01536 registry().add("global_cardinality_low_up",
01537 &p_global_cardinality_low_up);
01538 registry().add("global_cardinality_low_up_closed",
01539 &p_global_cardinality_low_up_closed);
01540 registry().add("array_int_minimum", &p_minimum);
01541 registry().add("array_int_maximum", &p_maximum);
01542 registry().add("gecode_minimum_arg_int", &p_minimum_arg);
01543 registry().add("gecode_maximum_arg_int", &p_maximum_arg);
01544 registry().add("array_int_maximum", &p_maximum);
01545 registry().add("gecode_regular", &p_regular);
01546 registry().add("sort", &p_sort);
01547 registry().add("inverse_offsets", &p_inverse_offsets);
01548 registry().add("increasing_int", &p_increasing_int);
01549 registry().add("increasing_bool", &p_increasing_bool);
01550 registry().add("decreasing_int", &p_decreasing_int);
01551 registry().add("decreasing_bool", &p_decreasing_bool);
01552 registry().add("gecode_table_int", &p_table_int);
01553 registry().add("gecode_table_bool", &p_table_bool);
01554 registry().add("cumulatives", &p_cumulatives);
01555 registry().add("gecode_among_seq_int", &p_among_seq_int);
01556 registry().add("gecode_among_seq_bool", &p_among_seq_bool);
01557
01558 registry().add("bool_lin_eq", &p_bool_lin_eq);
01559 registry().add("bool_lin_ne", &p_bool_lin_ne);
01560 registry().add("bool_lin_le", &p_bool_lin_le);
01561 registry().add("bool_lin_lt", &p_bool_lin_lt);
01562 registry().add("bool_lin_ge", &p_bool_lin_ge);
01563 registry().add("bool_lin_gt", &p_bool_lin_gt);
01564
01565 registry().add("bool_lin_eq_reif", &p_bool_lin_eq_reif);
01566 registry().add("bool_lin_eq_imp", &p_bool_lin_eq_imp);
01567 registry().add("bool_lin_ne_reif", &p_bool_lin_ne_reif);
01568 registry().add("bool_lin_ne_imp", &p_bool_lin_ne_imp);
01569 registry().add("bool_lin_le_reif", &p_bool_lin_le_reif);
01570 registry().add("bool_lin_le_imp", &p_bool_lin_le_imp);
01571 registry().add("bool_lin_lt_reif", &p_bool_lin_lt_reif);
01572 registry().add("bool_lin_lt_imp", &p_bool_lin_lt_imp);
01573 registry().add("bool_lin_ge_reif", &p_bool_lin_ge_reif);
01574 registry().add("bool_lin_ge_imp", &p_bool_lin_ge_imp);
01575 registry().add("bool_lin_gt_reif", &p_bool_lin_gt_reif);
01576 registry().add("bool_lin_gt_imp", &p_bool_lin_gt_imp);
01577
01578 registry().add("gecode_schedule_unary", &p_schedule_unary);
01579 registry().add("gecode_schedule_unary_optional", &p_schedule_unary_optional);
01580 registry().add("gecode_schedule_cumulative_optional", &p_cumulative_opt);
01581
01582 registry().add("gecode_circuit", &p_circuit);
01583 registry().add("gecode_circuit_cost_array", &p_circuit_cost_array);
01584 registry().add("gecode_circuit_cost", &p_circuit_cost);
01585 registry().add("gecode_nooverlap", &p_nooverlap);
01586 registry().add("gecode_precede", &p_precede);
01587 registry().add("nvalue",&p_nvalue);
01588 registry().add("among",&p_among);
01589 registry().add("member_int",&p_member_int);
01590 registry().add("gecode_member_int_reif",&p_member_int_reif);
01591 registry().add("member_bool",&p_member_bool);
01592 registry().add("gecode_member_bool_reif",&p_member_bool_reif);
01593 }
01594 };
01595 IntPoster __int_poster;
01596
01597 #ifdef GECODE_HAS_SET_VARS
01598 void p_set_OP(FlatZincSpace& s, SetOpType op,
01599 const ConExpr& ce, AST::Node *) {
01600 rel(s, s.arg2SetVar(ce[0]), op, s.arg2SetVar(ce[1]),
01601 SRT_EQ, s.arg2SetVar(ce[2]));
01602 }
01603 void p_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01604 p_set_OP(s, SOT_UNION, ce, ann);
01605 }
01606 void p_set_intersect(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01607 p_set_OP(s, SOT_INTER, ce, ann);
01608 }
01609 void p_set_diff(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01610 p_set_OP(s, SOT_MINUS, ce, ann);
01611 }
01612
01613 void p_set_symdiff(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01614 SetVar x = s.arg2SetVar(ce[0]);
01615 SetVar y = s.arg2SetVar(ce[1]);
01616
01617 SetVarLubRanges xub(x);
01618 IntSet xubs(xub);
01619 SetVar x_y(s,IntSet::empty,xubs);
01620 rel(s, x, SOT_MINUS, y, SRT_EQ, x_y);
01621
01622 SetVarLubRanges yub(y);
01623 IntSet yubs(yub);
01624 SetVar y_x(s,IntSet::empty,yubs);
01625 rel(s, y, SOT_MINUS, x, SRT_EQ, y_x);
01626
01627 rel(s, x_y, SOT_UNION, y_x, SRT_EQ, s.arg2SetVar(ce[2]));
01628 }
01629
01630 void p_array_set_OP(FlatZincSpace& s, SetOpType op,
01631 const ConExpr& ce, AST::Node *) {
01632 SetVarArgs xs = s.arg2setvarargs(ce[0]);
01633 rel(s, op, xs, s.arg2SetVar(ce[1]));
01634 }
01635 void p_array_set_union(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01636 p_array_set_OP(s, SOT_UNION, ce, ann);
01637 }
01638 void p_array_set_partition(FlatZincSpace& s, const ConExpr& ce, AST::Node *ann) {
01639 p_array_set_OP(s, SOT_DUNION, ce, ann);
01640 }
01641
01642
01643 void p_set_rel(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
01644 rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]));
01645 }
01646
01647 void p_set_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01648 p_set_rel(s, SRT_EQ, ce);
01649 }
01650 void p_set_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01651 p_set_rel(s, SRT_NQ, ce);
01652 }
01653 void p_set_subset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01654 p_set_rel(s, SRT_SUB, ce);
01655 }
01656 void p_set_superset(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01657 p_set_rel(s, SRT_SUP, ce);
01658 }
01659 void p_set_le(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01660 p_set_rel(s, SRT_LQ, ce);
01661 }
01662 void p_set_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01663 p_set_rel(s, SRT_LE, ce);
01664 }
01665 void p_set_card(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01666 if (!ce[1]->isIntVar()) {
01667 cardinality(s, s.arg2SetVar(ce[0]), ce[1]->getInt(),
01668 ce[1]->getInt());
01669 } else {
01670 cardinality(s, s.arg2SetVar(ce[0]), s.arg2IntVar(ce[1]));
01671 }
01672 }
01673 void p_set_in(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01674 if (!ce[1]->isSetVar()) {
01675 IntSet d = s.arg2intset(ce[1]);
01676 if (ce[0]->isBoolVar()) {
01677 IntSetRanges dr(d);
01678 Iter::Ranges::Singleton sr(0,1);
01679 Iter::Ranges::Inter<IntSetRanges,Iter::Ranges::Singleton> i(dr,sr);
01680 IntSet d01(i);
01681 if (d01.size() == 0) {
01682 s.fail();
01683 } else {
01684 rel(s, s.arg2BoolVar(ce[0]), IRT_GQ, d01.min());
01685 rel(s, s.arg2BoolVar(ce[0]), IRT_LQ, d01.max());
01686 }
01687 } else {
01688 dom(s, s.arg2IntVar(ce[0]), d);
01689 }
01690 } else {
01691 if (!ce[0]->isIntVar()) {
01692 dom(s, s.arg2SetVar(ce[1]), SRT_SUP, ce[0]->getInt());
01693 } else {
01694 rel(s, s.arg2SetVar(ce[1]), SRT_SUP, s.arg2IntVar(ce[0]));
01695 }
01696 }
01697 }
01698 void p_set_rel_reif(FlatZincSpace& s, SetRelType srt, const ConExpr& ce) {
01699 rel(s, s.arg2SetVar(ce[0]), srt, s.arg2SetVar(ce[1]),
01700 s.arg2BoolVar(ce[2]));
01701 }
01702
01703 void p_set_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01704 p_set_rel_reif(s,SRT_EQ,ce);
01705 }
01706 void p_set_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01707 p_set_rel_reif(s,SRT_LQ,ce);
01708 }
01709 void p_set_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01710 p_set_rel_reif(s,SRT_LE,ce);
01711 }
01712 void p_set_ne_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01713 p_set_rel_reif(s,SRT_NQ,ce);
01714 }
01715 void p_set_subset_reif(FlatZincSpace& s, const ConExpr& ce,
01716 AST::Node *) {
01717 p_set_rel_reif(s,SRT_SUB,ce);
01718 }
01719 void p_set_superset_reif(FlatZincSpace& s, const ConExpr& ce,
01720 AST::Node *) {
01721 p_set_rel_reif(s,SRT_SUP,ce);
01722 }
01723 void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann, ReifyMode rm) {
01724 if (!ce[1]->isSetVar()) {
01725 if (rm==RM_EQV) {
01726 p_int_in_reif(s,ce,ann);
01727 } else {
01728 assert(rm==RM_IMP);
01729 p_int_in_imp(s,ce,ann);
01730 }
01731 } else {
01732 if (!ce[0]->isIntVar()) {
01733 dom(s, s.arg2SetVar(ce[1]), SRT_SUP, ce[0]->getInt(),
01734 Reify(s.arg2BoolVar(ce[2]),rm));
01735 } else {
01736 rel(s, s.arg2SetVar(ce[1]), SRT_SUP, s.arg2IntVar(ce[0]),
01737 Reify(s.arg2BoolVar(ce[2]),rm));
01738 }
01739 }
01740 }
01741 void p_set_in_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01742 p_set_in_reif(s,ce,ann,RM_EQV);
01743 }
01744 void p_set_in_imp(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01745 p_set_in_reif(s,ce,ann,RM_IMP);
01746 }
01747 void p_set_disjoint(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01748 rel(s, s.arg2SetVar(ce[0]), SRT_DISJ, s.arg2SetVar(ce[1]));
01749 }
01750
01751 void p_link_set_to_booleans(FlatZincSpace& s, const ConExpr& ce,
01752 AST::Node *) {
01753 SetVar x = s.arg2SetVar(ce[0]);
01754 int idx = ce[2]->getInt();
01755 assert(idx >= 0);
01756 rel(s, x || IntSet(Set::Limits::min,idx-1));
01757 BoolVarArgs y = s.arg2boolvarargs(ce[1],idx);
01758 unshare(s, y);
01759 channel(s, y, x);
01760 }
01761
01762 void p_array_set_element(FlatZincSpace& s, const ConExpr& ce,
01763 AST::Node*) {
01764 bool isConstant = true;
01765 AST::Array* a = ce[1]->getArray();
01766 for (int i=a->a.size(); i--;) {
01767 if (a->a[i]->isSetVar()) {
01768 isConstant = false;
01769 break;
01770 }
01771 }
01772 IntVar selector = s.arg2IntVar(ce[0]);
01773 rel(s, selector > 0);
01774 if (isConstant) {
01775 IntSetArgs sv = s.arg2intsetargs(ce[1],1);
01776 element(s, sv, selector, s.arg2SetVar(ce[2]));
01777 } else {
01778 SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
01779 element(s, sv, selector, s.arg2SetVar(ce[2]));
01780 }
01781 }
01782
01783 void p_array_set_element_op(FlatZincSpace& s, const ConExpr& ce,
01784 AST::Node*, SetOpType op,
01785 const IntSet& universe =
01786 IntSet(Set::Limits::min,Set::Limits::max)) {
01787 bool isConstant = true;
01788 AST::Array* a = ce[1]->getArray();
01789 for (int i=a->a.size(); i--;) {
01790 if (a->a[i]->isSetVar()) {
01791 isConstant = false;
01792 break;
01793 }
01794 }
01795 SetVar selector = s.arg2SetVar(ce[0]);
01796 dom(s, selector, SRT_DISJ, 0);
01797 if (isConstant) {
01798 IntSetArgs sv = s.arg2intsetargs(ce[1], 1);
01799 element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
01800 } else {
01801 SetVarArgs sv = s.arg2setvarargs(ce[1], 1);
01802 element(s, op, sv, selector, s.arg2SetVar(ce[2]), universe);
01803 }
01804 }
01805
01806 void p_array_set_element_union(FlatZincSpace& s, const ConExpr& ce,
01807 AST::Node* ann) {
01808 p_array_set_element_op(s, ce, ann, SOT_UNION);
01809 }
01810
01811 void p_array_set_element_intersect(FlatZincSpace& s, const ConExpr& ce,
01812 AST::Node* ann) {
01813 p_array_set_element_op(s, ce, ann, SOT_INTER);
01814 }
01815
01816 void p_array_set_element_intersect_in(FlatZincSpace& s,
01817 const ConExpr& ce,
01818 AST::Node* ann) {
01819 IntSet d = s.arg2intset(ce[3]);
01820 p_array_set_element_op(s, ce, ann, SOT_INTER, d);
01821 }
01822
01823 void p_array_set_element_partition(FlatZincSpace& s, const ConExpr& ce,
01824 AST::Node* ann) {
01825 p_array_set_element_op(s, ce, ann, SOT_DUNION);
01826 }
01827
01828 void p_set_convex(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01829 convex(s, s.arg2SetVar(ce[0]));
01830 }
01831
01832 void p_array_set_seq(FlatZincSpace& s, const ConExpr& ce, AST::Node *) {
01833 SetVarArgs sv = s.arg2setvarargs(ce[0]);
01834 sequence(s, sv);
01835 }
01836
01837 void p_array_set_seq_union(FlatZincSpace& s, const ConExpr& ce,
01838 AST::Node *) {
01839 SetVarArgs sv = s.arg2setvarargs(ce[0]);
01840 sequence(s, sv, s.arg2SetVar(ce[1]));
01841 }
01842
01843 void p_int_set_channel(FlatZincSpace& s, const ConExpr& ce,
01844 AST::Node *) {
01845 int xoff=ce[1]->getInt();
01846 assert(xoff >= 0);
01847 int yoff=ce[3]->getInt();
01848 assert(yoff >= 0);
01849 IntVarArgs xv = s.arg2intvarargs(ce[0], xoff);
01850 SetVarArgs yv = s.arg2setvarargs(ce[2], yoff, 1, IntSet(0, xoff-1));
01851 IntSet xd(yoff,yv.size()-1);
01852 for (int i=xoff; i<xv.size(); i++) {
01853 dom(s, xv[i], xd);
01854 }
01855 IntSet yd(xoff,xv.size()-1);
01856 for (int i=yoff; i<yv.size(); i++) {
01857 dom(s, yv[i], SRT_SUB, yd);
01858 }
01859 channel(s,xv,yv);
01860 }
01861
01862 void p_range(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01863 int xoff=ce[1]->getInt();
01864 assert(xoff >= 0);
01865 IntVarArgs xv = s.arg2intvarargs(ce[0],xoff);
01866 element(s, SOT_UNION, xv, s.arg2SetVar(ce[2]), s.arg2SetVar(ce[3]));
01867 }
01868
01869 void p_weights(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01870 IntArgs e = s.arg2intargs(ce[0]);
01871 IntArgs w = s.arg2intargs(ce[1]);
01872 SetVar x = s.arg2SetVar(ce[2]);
01873 IntVar y = s.arg2IntVar(ce[3]);
01874 weights(s,e,w,x,y);
01875 }
01876
01877 void p_inverse_set(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01878 int xoff = ce[2]->getInt();
01879 int yoff = ce[3]->getInt();
01880 SetVarArgs x = s.arg2setvarargs(ce[0],xoff);
01881 SetVarArgs y = s.arg2setvarargs(ce[1],yoff);
01882 channel(s, x, y);
01883 }
01884
01885 void p_precede_set(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01886 SetVarArgs x = s.arg2setvarargs(ce[0]);
01887 int p_s = ce[1]->getInt();
01888 int p_t = ce[2]->getInt();
01889 precede(s,x,p_s,p_t);
01890 }
01891
01892 class SetPoster {
01893 public:
01894 SetPoster(void) {
01895 registry().add("set_eq", &p_set_eq);
01896 registry().add("set_le", &p_set_le);
01897 registry().add("set_lt", &p_set_lt);
01898 registry().add("equal", &p_set_eq);
01899 registry().add("set_ne", &p_set_ne);
01900 registry().add("set_union", &p_set_union);
01901 registry().add("array_set_element", &p_array_set_element);
01902 registry().add("array_var_set_element", &p_array_set_element);
01903 registry().add("set_intersect", &p_set_intersect);
01904 registry().add("set_diff", &p_set_diff);
01905 registry().add("set_symdiff", &p_set_symdiff);
01906 registry().add("set_subset", &p_set_subset);
01907 registry().add("set_superset", &p_set_superset);
01908 registry().add("set_card", &p_set_card);
01909 registry().add("set_in", &p_set_in);
01910 registry().add("set_eq_reif", &p_set_eq_reif);
01911 registry().add("set_le_reif", &p_set_le_reif);
01912 registry().add("set_lt_reif", &p_set_lt_reif);
01913 registry().add("equal_reif", &p_set_eq_reif);
01914 registry().add("set_ne_reif", &p_set_ne_reif);
01915 registry().add("set_subset_reif", &p_set_subset_reif);
01916 registry().add("set_superset_reif", &p_set_superset_reif);
01917 registry().add("set_in_reif", &p_set_in_reif);
01918 registry().add("set_in_imp", &p_set_in_imp);
01919 registry().add("disjoint", &p_set_disjoint);
01920 registry().add("gecode_link_set_to_booleans",
01921 &p_link_set_to_booleans);
01922
01923 registry().add("array_set_union", &p_array_set_union);
01924 registry().add("array_set_partition", &p_array_set_partition);
01925 registry().add("set_convex", &p_set_convex);
01926 registry().add("array_set_seq", &p_array_set_seq);
01927 registry().add("array_set_seq_union", &p_array_set_seq_union);
01928 registry().add("gecode_array_set_element_union",
01929 &p_array_set_element_union);
01930 registry().add("gecode_array_set_element_intersect",
01931 &p_array_set_element_intersect);
01932 registry().add("gecode_array_set_element_intersect_in",
01933 &p_array_set_element_intersect_in);
01934 registry().add("gecode_array_set_element_partition",
01935 &p_array_set_element_partition);
01936 registry().add("gecode_int_set_channel",
01937 &p_int_set_channel);
01938 registry().add("gecode_range",
01939 &p_range);
01940 registry().add("gecode_set_weights",
01941 &p_weights);
01942 registry().add("gecode_inverse_set", &p_inverse_set);
01943 registry().add("gecode_precede_set", &p_precede_set);
01944 }
01945 };
01946 SetPoster __set_poster;
01947 #endif
01948
01949 #ifdef GECODE_HAS_FLOAT_VARS
01950
01951 void p_int2float(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01952 IntVar x0 = s.arg2IntVar(ce[0]);
01953 FloatVar x1 = s.arg2FloatVar(ce[1]);
01954 channel(s, x0, x1);
01955 }
01956
01957 void p_float_lin_cmp(FlatZincSpace& s, FloatRelType frt,
01958 const ConExpr& ce, AST::Node*) {
01959 FloatValArgs fa = s.arg2floatargs(ce[0]);
01960 FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
01961 linear(s, fa, fv, frt, ce[2]->getFloat());
01962 }
01963 void p_float_lin_cmp_reif(FlatZincSpace& s, FloatRelType frt,
01964 const ConExpr& ce, AST::Node*) {
01965 FloatValArgs fa = s.arg2floatargs(ce[0]);
01966 FloatVarArgs fv = s.arg2floatvarargs(ce[1]);
01967 linear(s, fa, fv, frt, ce[2]->getFloat(), s.arg2BoolVar(ce[3]));
01968 }
01969 void p_float_lin_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01970 p_float_lin_cmp(s,FRT_EQ,ce,ann);
01971 }
01972 void p_float_lin_eq_reif(FlatZincSpace& s, const ConExpr& ce,
01973 AST::Node* ann) {
01974 p_float_lin_cmp_reif(s,FRT_EQ,ce,ann);
01975 }
01976 void p_float_lin_le(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01977 p_float_lin_cmp(s,FRT_LQ,ce,ann);
01978 }
01979 void p_float_lin_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node* ann) {
01980 p_float_lin_cmp(s,FRT_LE,ce,ann);
01981 }
01982 void p_float_lin_le_reif(FlatZincSpace& s, const ConExpr& ce,
01983 AST::Node* ann) {
01984 p_float_lin_cmp_reif(s,FRT_LQ,ce,ann);
01985 }
01986 void p_float_lin_lt_reif(FlatZincSpace& s, const ConExpr& ce,
01987 AST::Node* ann) {
01988 p_float_lin_cmp_reif(s,FRT_LE,ce,ann);
01989 }
01990
01991 void p_float_times(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01992 FloatVar x = s.arg2FloatVar(ce[0]);
01993 FloatVar y = s.arg2FloatVar(ce[1]);
01994 FloatVar z = s.arg2FloatVar(ce[2]);
01995 mult(s,x,y,z);
01996 }
01997
01998 void p_float_div(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
01999 FloatVar x = s.arg2FloatVar(ce[0]);
02000 FloatVar y = s.arg2FloatVar(ce[1]);
02001 FloatVar z = s.arg2FloatVar(ce[2]);
02002 div(s,x,y,z);
02003 }
02004
02005 void p_float_plus(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02006 FloatVar x = s.arg2FloatVar(ce[0]);
02007 FloatVar y = s.arg2FloatVar(ce[1]);
02008 FloatVar z = s.arg2FloatVar(ce[2]);
02009 rel(s,x+y==z);
02010 }
02011
02012 void p_float_sqrt(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02013 FloatVar x = s.arg2FloatVar(ce[0]);
02014 FloatVar y = s.arg2FloatVar(ce[1]);
02015 sqrt(s,x,y);
02016 }
02017
02018 void p_float_abs(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02019 FloatVar x = s.arg2FloatVar(ce[0]);
02020 FloatVar y = s.arg2FloatVar(ce[1]);
02021 abs(s,x,y);
02022 }
02023
02024 void p_float_eq(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02025 FloatVar x = s.arg2FloatVar(ce[0]);
02026 FloatVar y = s.arg2FloatVar(ce[1]);
02027 rel(s,x,FRT_EQ,y);
02028 }
02029 void p_float_eq_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02030 FloatVar x = s.arg2FloatVar(ce[0]);
02031 FloatVar y = s.arg2FloatVar(ce[1]);
02032 BoolVar b = s.arg2BoolVar(ce[2]);
02033 rel(s,x,FRT_EQ,y,b);
02034 }
02035 void p_float_le(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02036 FloatVar x = s.arg2FloatVar(ce[0]);
02037 FloatVar y = s.arg2FloatVar(ce[1]);
02038 rel(s,x,FRT_LQ,y);
02039 }
02040 void p_float_le_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02041 FloatVar x = s.arg2FloatVar(ce[0]);
02042 FloatVar y = s.arg2FloatVar(ce[1]);
02043 BoolVar b = s.arg2BoolVar(ce[2]);
02044 rel(s,x,FRT_LQ,y,b);
02045 }
02046 void p_float_max(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02047 FloatVar x = s.arg2FloatVar(ce[0]);
02048 FloatVar y = s.arg2FloatVar(ce[1]);
02049 FloatVar z = s.arg2FloatVar(ce[2]);
02050 max(s,x,y,z);
02051 }
02052 void p_float_min(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02053 FloatVar x = s.arg2FloatVar(ce[0]);
02054 FloatVar y = s.arg2FloatVar(ce[1]);
02055 FloatVar z = s.arg2FloatVar(ce[2]);
02056 min(s,x,y,z);
02057 }
02058 void p_float_lt(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02059 FloatVar x = s.arg2FloatVar(ce[0]);
02060 FloatVar y = s.arg2FloatVar(ce[1]);
02061 rel(s, x, FRT_LQ, y);
02062 rel(s, x, FRT_EQ, y, BoolVar(s,0,0));
02063 }
02064
02065 void p_float_lt_reif(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02066 FloatVar x = s.arg2FloatVar(ce[0]);
02067 FloatVar y = s.arg2FloatVar(ce[1]);
02068 BoolVar b = s.arg2BoolVar(ce[2]);
02069 BoolVar b0(s,0,1);
02070 BoolVar b1(s,0,1);
02071 rel(s, b == (b0 && !b1));
02072 rel(s, x, FRT_LQ, y, b0);
02073 rel(s, x, FRT_EQ, y, b1);
02074 }
02075
02076 void p_float_ne(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02077 FloatVar x = s.arg2FloatVar(ce[0]);
02078 FloatVar y = s.arg2FloatVar(ce[1]);
02079 rel(s, x, FRT_EQ, y, BoolVar(s,0,0));
02080 }
02081
02082 #ifdef GECODE_HAS_MPFR
02083 #define P_FLOAT_OP(Op) \
02084 void p_float_ ## Op (FlatZincSpace& s, const ConExpr& ce, AST::Node*) {\
02085 FloatVar x = s.arg2FloatVar(ce[0]);\
02086 FloatVar y = s.arg2FloatVar(ce[1]);\
02087 Op(s,x,y);\
02088 }
02089 P_FLOAT_OP(acos)
02090 P_FLOAT_OP(asin)
02091 P_FLOAT_OP(atan)
02092 P_FLOAT_OP(cos)
02093 P_FLOAT_OP(exp)
02094 P_FLOAT_OP(sin)
02095 P_FLOAT_OP(tan)
02096
02097
02098
02099 #undef P_FLOAT_OP
02100
02101 void p_float_ln(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02102 FloatVar x = s.arg2FloatVar(ce[0]);
02103 FloatVar y = s.arg2FloatVar(ce[1]);
02104 log(s,x,y);
02105 }
02106 void p_float_log10(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02107 FloatVar x = s.arg2FloatVar(ce[0]);
02108 FloatVar y = s.arg2FloatVar(ce[1]);
02109 log(s,10.0,x,y);
02110 }
02111 void p_float_log2(FlatZincSpace& s, const ConExpr& ce, AST::Node*) {
02112 FloatVar x = s.arg2FloatVar(ce[0]);
02113 FloatVar y = s.arg2FloatVar(ce[1]);
02114 log(s,2.0,x,y);
02115 }
02116
02117 #endif
02118
02119 class FloatPoster {
02120 public:
02121 FloatPoster(void) {
02122 registry().add("int2float",&p_int2float);
02123 registry().add("float_abs",&p_float_abs);
02124 registry().add("float_sqrt",&p_float_sqrt);
02125 registry().add("float_eq",&p_float_eq);
02126 registry().add("float_eq_reif",&p_float_eq_reif);
02127 registry().add("float_le",&p_float_le);
02128 registry().add("float_le_reif",&p_float_le_reif);
02129 registry().add("float_lt",&p_float_lt);
02130 registry().add("float_lt_reif",&p_float_lt_reif);
02131 registry().add("float_ne",&p_float_ne);
02132 registry().add("float_times",&p_float_times);
02133 registry().add("float_div",&p_float_div);
02134 registry().add("float_plus",&p_float_plus);
02135 registry().add("float_max",&p_float_max);
02136 registry().add("float_min",&p_float_min);
02137
02138 registry().add("float_lin_eq",&p_float_lin_eq);
02139 registry().add("float_lin_eq_reif",&p_float_lin_eq_reif);
02140 registry().add("float_lin_le",&p_float_lin_le);
02141 registry().add("float_lin_lt",&p_float_lin_lt);
02142 registry().add("float_lin_le_reif",&p_float_lin_le_reif);
02143 registry().add("float_lin_lt_reif",&p_float_lin_lt_reif);
02144
02145 #ifdef GECODE_HAS_MPFR
02146 registry().add("float_acos",&p_float_acos);
02147 registry().add("float_asin",&p_float_asin);
02148 registry().add("float_atan",&p_float_atan);
02149 registry().add("float_cos",&p_float_cos);
02150
02151 registry().add("float_exp",&p_float_exp);
02152 registry().add("float_ln",&p_float_ln);
02153 registry().add("float_log10",&p_float_log10);
02154 registry().add("float_log2",&p_float_log2);
02155 registry().add("float_sin",&p_float_sin);
02156
02157 registry().add("float_tan",&p_float_tan);
02158
02159 #endif
02160 }
02161 } __float_poster;
02162 #endif
02163
02164 }
02165 }}
02166
02167