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