00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <gecode/minimodel.hh>
00041
00042 #ifdef GECODE_HAS_SET_VARS
00043
00044 namespace Gecode {
00045
00046
00047
00048
00049
00050 bool
00051 SetExpr::Node::decrement(void) {
00052 if (--use == 0) {
00053 if ((l != NULL) && l->decrement())
00054 delete l;
00055 if ((r != NULL) && r->decrement())
00056 delete r;
00057 return true;
00058 }
00059 return false;
00060 }
00061
00062
00063 SetExpr::SetExpr(const SetVar& x) : n(new Node) {
00064 n->same = 1;
00065 n->t = NT_VAR;
00066 n->l = NULL;
00067 n->r = NULL;
00068 n->x = x;
00069 }
00070
00071 SetExpr::SetExpr(const IntSet& s) : n(new Node) {
00072 n->same = 1;
00073 n->t = NT_CONST;
00074 n->l = NULL;
00075 n->r = NULL;
00076 n->s = s;
00077 }
00078
00079 SetExpr::SetExpr(const LinExpr& e) : n(new Node) {
00080 n->same = 1;
00081 n->t = NT_LEXP;
00082 n->l = NULL;
00083 n->r = NULL;
00084 n->e = e;
00085 }
00086
00087 SetExpr::SetExpr(const SetExpr& l, NodeType t, const SetExpr& r)
00088 : n(new Node) {
00089 int ls = same(t,l.n->t) ? l.n->same : 1;
00090 int rs = same(t,r.n->t) ? r.n->same : 1;
00091 n->same = ls+rs;
00092 n->t = t;
00093 n->l = l.n;
00094 n->l->use++;
00095 n->r = r.n;
00096 n->r->use++;
00097 }
00098
00099 SetExpr::SetExpr(const SetExpr& l, NodeType t) {
00100 (void) t;
00101 assert(t == NT_CMPL);
00102 if (l.n->t == NT_CMPL) {
00103 n = l.n->l;
00104 n->use++;
00105 } else {
00106 n = new Node;
00107 n->same = 1;
00108 n->t = NT_CMPL;
00109 n->l = l.n;
00110 n->l->use++;
00111 n->r = NULL;
00112 }
00113 }
00114
00115 const SetExpr&
00116 SetExpr::operator =(const SetExpr& e) {
00117 if (this != &e) {
00118 if (n != NULL && n->decrement())
00119 delete n;
00120 n = e.n;
00121 n->use++;
00122 }
00123 return *this;
00124 }
00125
00126 SetExpr::~SetExpr(void) {
00127 if (n != NULL && n->decrement())
00128 delete n;
00129 }
00130
00131
00132
00133
00134
00135 forceinline void
00136 SetExpr::NNF::operator delete(void*) {}
00137
00138 forceinline void
00139 SetExpr::NNF::operator delete(void*, Region&) {}
00140
00141 forceinline void*
00142 SetExpr::NNF::operator new(size_t s, Region& r) {
00143 return r.ralloc(s);
00144 }
00145
00146 void
00147 SetExpr::NNF::post(Home home, SetRelType srt, SetVar s) const {
00148 switch (t) {
00149 case NT_VAR:
00150 if (neg) {
00151 switch (srt) {
00152 case SRT_EQ:
00153 rel(home, u.a.x->x, SRT_CMPL, s);
00154 break;
00155 case SRT_CMPL:
00156 rel(home, u.a.x->x, SRT_EQ, s);
00157 break;
00158 default:
00159 SetVar bc(home,IntSet::empty,
00160 IntSet(Set::Limits::min,Set::Limits::max));
00161 rel(home, s, SRT_CMPL, bc);
00162 rel(home, u.a.x->x, srt, bc);
00163 break;
00164 }
00165 } else
00166 rel(home, u.a.x->x, srt, s);
00167 break;
00168 case NT_CONST:
00169 {
00170 IntSet ss;
00171 if (neg) {
00172 IntSetRanges sr(u.a.x->s);
00173 Set::RangesCompl<IntSetRanges> src(sr);
00174 ss = IntSet(src);
00175 } else {
00176 ss = u.a.x->s;
00177 }
00178 switch (srt) {
00179 case SRT_SUB: srt = SRT_SUP; break;
00180 case SRT_SUP: srt = SRT_SUB; break;
00181 default: break;
00182 }
00183 dom(home, s, srt, ss);
00184 }
00185 break;
00186 case NT_LEXP:
00187 {
00188 IntVar iv = u.a.x->e.post(home,ICL_DEF);
00189 if (neg) {
00190 SetVar ic(home,IntSet::empty,
00191 IntSet(Set::Limits::min,Set::Limits::max));
00192 rel(home, iv, SRT_CMPL, ic);
00193 rel(home,ic,srt,s);
00194 } else {
00195 rel(home,iv,srt,s);
00196 }
00197 }
00198 break;
00199 case NT_INTER:
00200 {
00201 SetVarArgs bs(p+n);
00202 int i=0;
00203 post(home, NT_INTER, bs, i);
00204 if (i == 2) {
00205 rel(home, bs[0], SOT_INTER, bs[1], srt, s);
00206 } else {
00207 if (srt == SRT_EQ)
00208 rel(home, SOT_INTER, bs, s);
00209 else {
00210 SetVar bc(home,IntSet::empty,
00211 IntSet(Set::Limits::min,Set::Limits::max));
00212 rel(home, SOT_INTER, bs, bc);
00213 rel(home, bc, srt, s);
00214 }
00215 }
00216 }
00217 break;
00218 case NT_UNION:
00219 {
00220 SetVarArgs bs(p+n);
00221 int i=0;
00222 post(home, NT_UNION, bs, i);
00223 if (i == 2) {
00224 rel(home, bs[0], SOT_UNION, bs[1], srt, s);
00225 } else {
00226 if (srt == SRT_EQ)
00227 rel(home, SOT_UNION, bs, s);
00228 else {
00229 SetVar bc(home,IntSet::empty,
00230 IntSet(Set::Limits::min,Set::Limits::max));
00231 rel(home, SOT_UNION, bs, bc);
00232 rel(home, bc, srt, s);
00233 }
00234 }
00235 }
00236 break;
00237 case NT_DUNION:
00238 {
00239 SetVarArgs bs(p+n);
00240 int i=0;
00241 post(home, NT_DUNION, bs, i);
00242
00243 if (i == 2) {
00244 if (neg) {
00245 if (srt == SRT_CMPL) {
00246 rel(home, bs[0], SOT_DUNION, bs[1], srt, s);
00247 } else {
00248 SetVar bc(home,IntSet::empty,
00249 IntSet(Set::Limits::min,Set::Limits::max));
00250 rel(home,s,SRT_CMPL,bc);
00251 rel(home, bs[0], SOT_DUNION, bs[1], srt, bc);
00252 }
00253 } else {
00254 rel(home, bs[0], SOT_DUNION, bs[1], srt, s);
00255 }
00256 } else {
00257 if (neg) {
00258 if (srt == SRT_CMPL) {
00259 rel(home, SOT_DUNION, bs, s);
00260 } else {
00261 SetVar br(home,IntSet::empty,
00262 IntSet(Set::Limits::min,Set::Limits::max));
00263 rel(home, SOT_DUNION, bs, br);
00264 if (srt == SRT_EQ)
00265 rel(home, br, SRT_CMPL, s);
00266 else {
00267 SetVar bc(home,IntSet::empty,
00268 IntSet(Set::Limits::min,Set::Limits::max));
00269 rel(home, br, srt, bc);
00270 rel(home, bc, SRT_CMPL, s);
00271 }
00272 }
00273 } else {
00274 if (srt == SRT_EQ)
00275 rel(home, SOT_DUNION, bs, s);
00276 else {
00277 SetVar br(home,IntSet::empty,
00278 IntSet(Set::Limits::min,Set::Limits::max));
00279 rel(home, SOT_DUNION, bs, br);
00280 rel(home, br, srt, s);
00281 }
00282 }
00283 }
00284 }
00285 break;
00286 default:
00287 GECODE_NEVER;
00288 }
00289 }
00290
00291 void
00292 SetExpr::NNF::post(Home home, SetRelType srt, SetVar s, BoolVar b) const {
00293 switch (t) {
00294 case NT_VAR:
00295 if (neg) {
00296 switch (srt) {
00297 case SRT_EQ:
00298 rel(home, u.a.x->x, SRT_CMPL, s, b);
00299 break;
00300 case SRT_CMPL:
00301 rel(home, u.a.x->x, SRT_EQ, s, b);
00302 break;
00303 default:
00304 SetVar bc(home,IntSet::empty,
00305 IntSet(Set::Limits::min,Set::Limits::max));
00306 rel(home, s, SRT_CMPL, bc);
00307 rel(home, u.a.x->x, srt, bc, b);
00308 break;
00309 }
00310 } else
00311 rel(home, u.a.x->x, srt, s, b);
00312 break;
00313 case NT_CONST:
00314 {
00315 IntSet ss;
00316 if (neg) {
00317 IntSetRanges sr(u.a.x->s);
00318 Set::RangesCompl<IntSetRanges> src(sr);
00319 ss = IntSet(src);
00320 } else {
00321 ss = u.a.x->s;
00322 }
00323 dom(home, s, srt, ss, b);
00324 }
00325 break;
00326 case NT_LEXP:
00327 {
00328 IntVar iv = u.a.x->e.post(home,ICL_DEF);
00329 if (neg) {
00330 SetVar ic(home,IntSet::empty,
00331 IntSet(Set::Limits::min,Set::Limits::max));
00332 rel(home, iv, SRT_CMPL, ic);
00333 rel(home,ic,srt,s,b);
00334 } else {
00335 rel(home,iv,srt,s,b);
00336 }
00337 }
00338 case NT_INTER:
00339 {
00340 SetVarArgs bs(p+n);
00341 int i=0;
00342 post(home, NT_INTER, bs, i);
00343 SetVar br(home,IntSet::empty,
00344 IntSet(Set::Limits::min,Set::Limits::max));
00345 rel(home, SOT_INTER, bs, br);
00346 rel(home, br, srt, s, b);
00347 }
00348 break;
00349 case NT_UNION:
00350 {
00351 SetVarArgs bs(p+n);
00352 int i=0;
00353 post(home, NT_UNION, bs, i);
00354 SetVar br(home,IntSet::empty,
00355 IntSet(Set::Limits::min,Set::Limits::max));
00356 rel(home, SOT_UNION, bs, br);
00357 rel(home, br, srt, s, b);
00358 }
00359 break;
00360 case NT_DUNION:
00361 {
00362 SetVarArgs bs(p+n);
00363 int i=0;
00364 post(home, NT_DUNION, bs, i);
00365
00366 if (neg) {
00367 SetVar br(home,IntSet::empty,
00368 IntSet(Set::Limits::min,Set::Limits::max));
00369 rel(home, SOT_DUNION, bs, br);
00370 if (srt == SRT_CMPL)
00371 rel(home, br, SRT_EQ, s, b);
00372 else if (srt == SRT_EQ)
00373 rel(home, br, SRT_CMPL, s, b);
00374 else {
00375 SetVar bc(home,IntSet::empty,
00376 IntSet(Set::Limits::min,Set::Limits::max));
00377 rel(home, br, srt, bc);
00378 rel(home, bc, SRT_CMPL, s, b);
00379 }
00380 } else {
00381 SetVar br(home,IntSet::empty,
00382 IntSet(Set::Limits::min,Set::Limits::max));
00383 rel(home, SOT_DUNION, bs, br);
00384 rel(home, br, srt, s, b);
00385 }
00386 }
00387 break;
00388 default:
00389 GECODE_NEVER;
00390 }
00391 }
00392
00393 void
00394 SetExpr::NNF::post(Home home, NodeType t,
00395 SetVarArgs& b, int& i) const {
00396 if (this->t != t) {
00397 switch (this->t) {
00398 case NT_VAR:
00399 if (neg) {
00400 SetVar xc(home,IntSet::empty,
00401 IntSet(Set::Limits::min,Set::Limits::max));
00402 rel(home, xc, SRT_CMPL, u.a.x->x);
00403 b[i++]=xc;
00404 } else {
00405 b[i++]=u.a.x->x;
00406 }
00407 break;
00408 default:
00409 {
00410 SetVar s(home,IntSet::empty,
00411 IntSet(Set::Limits::min,Set::Limits::max));
00412 post(home,SRT_EQ,s);
00413 b[i++] = s;
00414 }
00415 break;
00416 }
00417 } else {
00418 u.b.l->post(home, t, b, i);
00419 u.b.r->post(home, t, b, i);
00420 }
00421 }
00422
00423 void
00424 SetExpr::NNF::post(Home home, SetRelType srt, const NNF* n) const {
00425 if (n->t == NT_VAR && !n->neg) {
00426 post(home,srt,n->u.a.x->x);
00427 } else if (t == NT_VAR && !neg) {
00428 SetRelType n_srt;
00429 switch (srt) {
00430 case SRT_SUB: n_srt = SRT_SUP; break;
00431 case SRT_SUP: n_srt = SRT_SUB; break;
00432 default: n_srt = srt;
00433 }
00434 n->post(home,n_srt,this);
00435 } else {
00436 SetVar nx(home,IntSet::empty,
00437 IntSet(Set::Limits::min,Set::Limits::max));
00438 n->post(home,SRT_EQ,nx);
00439 post(home,srt,nx);
00440 }
00441 }
00442
00443 void
00444 SetExpr::NNF::post(Home home, BoolVar b, bool t,
00445 SetRelType srt, const NNF* n) const {
00446 if (t) {
00447 if (n->t == NT_VAR && !n->neg) {
00448 post(home,srt,n->u.a.x->x,b);
00449 } else if (t == NT_VAR && !neg) {
00450 SetRelType n_srt;
00451 switch (srt) {
00452 case SRT_SUB: n_srt = SRT_SUP; break;
00453 case SRT_SUP: n_srt = SRT_SUB; break;
00454 default: n_srt = srt;
00455 }
00456 n->post(home,b,true,n_srt,this);
00457 } else {
00458 SetVar nx(home,IntSet::empty,
00459 IntSet(Set::Limits::min,Set::Limits::max));
00460 n->post(home,SRT_EQ,nx);
00461 post(home,srt,nx,b);
00462 }
00463 } else if (srt == SRT_EQ) {
00464 post(home,b,true,SRT_NQ,n);
00465 } else if (srt == SRT_NQ) {
00466 post(home,b,true,SRT_EQ,n);
00467 } else {
00468 BoolVar nb(home,0,1);
00469 rel(home,b,IRT_NQ,nb);
00470 post(home,nb,true,srt,n);
00471 }
00472 }
00473
00474 SetExpr::NNF*
00475 SetExpr::NNF::nnf(Region& r, Node* n, bool neg) {
00476 switch (n->t) {
00477 case NT_VAR: case NT_CONST: case NT_LEXP:
00478 {
00479 NNF* x = new (r) NNF;
00480 x->t = n->t; x->neg = neg; x->u.a.x = n;
00481 if (neg) {
00482 x->p = 0; x->n = 1;
00483 } else {
00484 x->p = 1; x->n = 0;
00485 }
00486 return x;
00487 }
00488 case NT_CMPL:
00489 return nnf(r,n->l,!neg);
00490 case NT_INTER: case NT_UNION: case NT_DUNION:
00491 {
00492 NodeType t; bool xneg;
00493 if (n->t == NT_DUNION) {
00494 t = n->t; xneg = neg; neg = false;
00495 } else {
00496 t = ((n->t == NT_INTER) == neg) ? NT_UNION : NT_INTER;
00497 xneg = false;
00498 }
00499 NNF* x = new (r) NNF;
00500 x->neg = xneg;
00501 x->t = t;
00502 x->u.b.l = nnf(r,n->l,neg);
00503 x->u.b.r = nnf(r,n->r,neg);
00504 int p_l, n_l;
00505 if ((x->u.b.l->t == t) || (x->u.b.l->t == NT_VAR)) {
00506 p_l=x->u.b.l->p; n_l=x->u.b.l->n;
00507 } else {
00508 p_l=1; n_l=0;
00509 }
00510 int p_r, n_r;
00511 if ((x->u.b.r->t == t) || (x->u.b.r->t == NT_VAR)) {
00512 p_r=x->u.b.r->p; n_r=x->u.b.r->n;
00513 } else {
00514 p_r=1; n_r=0;
00515 }
00516 x->p = p_l+p_r;
00517 x->n = n_l+n_r;
00518 return x;
00519 }
00520 default:
00521 GECODE_NEVER;
00522 }
00523 GECODE_NEVER;
00524 return NULL;
00525 }
00526
00527
00528 SetExpr
00529 operator &(const SetExpr& l, const SetExpr& r) {
00530 return SetExpr(l,SetExpr::NT_INTER,r);
00531 }
00532 SetExpr
00533 operator |(const SetExpr& l, const SetExpr& r) {
00534 return SetExpr(l,SetExpr::NT_UNION,r);
00535 }
00536 SetExpr
00537 operator +(const SetExpr& l, const SetExpr& r) {
00538 return SetExpr(l,SetExpr::NT_DUNION,r);
00539 }
00540 SetExpr
00541 operator -(const SetExpr& e) {
00542 return SetExpr(e,SetExpr::NT_CMPL);
00543 }
00544 SetExpr
00545 operator -(const SetExpr& l, const SetExpr& r) {
00546 return SetExpr(l,SetExpr::NT_INTER,-r);
00547 }
00548 SetExpr
00549 singleton(const LinExpr& e) {
00550 return SetExpr(e);
00551 }
00552
00553 SetExpr
00554 inter(const SetVarArgs& x) {
00555 if (x.size() == 0)
00556 return SetExpr(IntSet(Set::Limits::min,Set::Limits::max));
00557 SetExpr r(x[0]);
00558 for (int i=1; i<x.size(); i++)
00559 r = (r & x[i]);
00560 return r;
00561 }
00562 SetExpr
00563 setunion(const SetVarArgs& x) {
00564 if (x.size() == 0)
00565 return SetExpr(IntSet::empty);
00566 SetExpr r(x[0]);
00567 for (int i=1; i<x.size(); i++)
00568 r = (r | x[i]);
00569 return r;
00570 }
00571 SetExpr
00572 setdunion(const SetVarArgs& x) {
00573 if (x.size() == 0)
00574 return SetExpr(IntSet::empty);
00575 SetExpr r(x[0]);
00576 for (int i=1; i<x.size(); i++)
00577 r = (r + x[i]);
00578 return r;
00579 }
00580
00581 namespace MiniModel {
00583 class GECODE_MINIMODEL_EXPORT SetNonLinExpr : public NonLinExpr {
00584 public:
00586 enum SetNonLinExprType {
00587 SNLE_CARD,
00588 SNLE_MIN,
00589 SNLE_MAX
00590 } t;
00592 SetExpr e;
00594 SetNonLinExpr(const SetExpr& e0, SetNonLinExprType t0)
00595 : t(t0), e(e0) {}
00597 virtual IntVar post(Home home, IntVar* ret, IntConLevel) const {
00598 IntVar m = result(home,ret);
00599 switch (t) {
00600 case SNLE_CARD:
00601 cardinality(home, e.post(home), m);
00602 break;
00603 case SNLE_MIN:
00604 min(home, e.post(home), m);
00605 break;
00606 case SNLE_MAX:
00607 max(home, e.post(home), m);
00608 break;
00609 default:
00610 GECODE_NEVER;
00611 break;
00612 }
00613 return m;
00614 }
00615 virtual void post(Home home, IntRelType irt, int c,
00616 IntConLevel icl) const {
00617 if (t==SNLE_CARD && irt!=IRT_NQ) {
00618 switch (irt) {
00619 case IRT_LQ:
00620 cardinality(home, e.post(home),
00621 0U,
00622 static_cast<unsigned int>(c));
00623 break;
00624 case IRT_LE:
00625 cardinality(home, e.post(home),
00626 0U,
00627 static_cast<unsigned int>(c-1));
00628 break;
00629 case IRT_GQ:
00630 cardinality(home, e.post(home),
00631 static_cast<unsigned int>(c),
00632 Set::Limits::card);
00633 break;
00634 case IRT_GR:
00635 cardinality(home, e.post(home),
00636 static_cast<unsigned int>(c+1),
00637 Set::Limits::card);
00638 break;
00639 case IRT_EQ:
00640 cardinality(home, e.post(home),
00641 static_cast<unsigned int>(c),
00642 static_cast<unsigned int>(c));
00643 break;
00644 default:
00645 GECODE_NEVER;
00646 }
00647 } else if (t==SNLE_MIN && (irt==IRT_GR || irt==IRT_GQ)) {
00648 c = (irt==IRT_GQ ? c : c+1);
00649 dom(home, e.post(home), SRT_SUB, c, Set::Limits::max);
00650 } else if (t==SNLE_MAX && (irt==IRT_LE || irt==IRT_LQ)) {
00651 c = (irt==IRT_LQ ? c : c-1);
00652 dom(home, e.post(home), SRT_SUB, Set::Limits::min, c);
00653 } else {
00654 rel(home, post(home,NULL,icl), irt, c);
00655 }
00656 }
00657 virtual void post(Home home, IntRelType irt, int c,
00658 BoolVar b, IntConLevel icl) const {
00659 if (t==SNLE_MIN && (irt==IRT_GR || irt==IRT_GQ)) {
00660 c = (irt==IRT_GQ ? c : c+1);
00661 dom(home, e.post(home), SRT_SUB, c, Set::Limits::max, b);
00662 } else if (t==SNLE_MAX && (irt==IRT_LE || irt==IRT_LQ)) {
00663 c = (irt==IRT_LQ ? c : c-1);
00664 dom(home, e.post(home), SRT_SUB, Set::Limits::min, c, b);
00665 } else {
00666 rel(home, post(home,NULL,icl), irt, c, b);
00667 }
00668 }
00669 };
00670 }
00671
00672 LinExpr
00673 cardinality(const SetExpr& e) {
00674 return LinExpr(new MiniModel::SetNonLinExpr(e,
00675 MiniModel::SetNonLinExpr::SNLE_CARD));
00676 }
00677 LinExpr
00678 min(const SetExpr& e) {
00679 return LinExpr(new MiniModel::SetNonLinExpr(e,
00680 MiniModel::SetNonLinExpr::SNLE_MIN));
00681 }
00682 LinExpr
00683 max(const SetExpr& e) {
00684 return LinExpr(new MiniModel::SetNonLinExpr(e,
00685 MiniModel::SetNonLinExpr::SNLE_MAX));
00686 }
00687
00688
00689
00690
00691
00692 SetVar
00693 expr(Home home, const SetExpr& e) {
00694 if (!home.failed())
00695 return e.post(home);
00696 SetVar x(home,IntSet::empty,IntSet::empty);
00697 return x;
00698 }
00699
00700 }
00701
00702 #endif
00703
00704