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 <algorithm>
00041
00042 #include <gecode/int/bool.hh>
00043
00044 namespace Gecode { namespace Int { namespace Linear {
00045
00046
00047
00048
00049
00050 template<class VX>
00051 forceinline
00052 LinBoolInt<VX>::LinBoolInt(Home home, ViewArray<VX>& x0,
00053 int n_s, int c0)
00054 : Propagator(home), co(home), x(x0), n_as(n_s), n_hs(n_s), c(c0) {
00055 Advisor* a = new (home) Advisor(home,*this,co);
00056 for (int i=n_as; i--; )
00057 x[i].subscribe(home,*a);
00058 }
00059
00060 template<class VX>
00061 forceinline void
00062 LinBoolInt<VX>::normalize(void) {
00063 if (n_as != n_hs) {
00064
00065 int n_x = x.size();
00066 for (int i=n_hs; i--; )
00067 if (!x[i].none()) {
00068 x[i]=x[--n_hs]; x[n_hs]=x[--n_x];
00069 }
00070 x.size(n_x);
00071 }
00072 assert(n_as == n_hs);
00073
00074 {
00075 int n_x = x.size();
00076 for (int i=n_x-1; i>=n_hs; i--)
00077 if (x[i].one()) {
00078 c--; x[i]=x[--n_x];
00079 } else if (x[i].zero()) {
00080 x[i]=x[--n_x];
00081 }
00082 x.size(n_x);
00083 }
00084 }
00085
00086 template<class VX>
00087 forceinline
00088 LinBoolInt<VX>::LinBoolInt(Space& home, bool share, LinBoolInt<VX>& p)
00089 : Propagator(home,share,p), n_as(p.n_as), n_hs(n_as) {
00090 p.normalize();
00091 c=p.c;
00092 co.update(home,share,p.co);
00093 x.update(home,share,p.x);
00094 }
00095
00096 template<class VX>
00097 PropCost
00098 LinBoolInt<VX>::cost(const Space&, const ModEventDelta&) const {
00099 return PropCost::unary(PropCost::HI);
00100 }
00101
00102 template<class VX>
00103 forceinline size_t
00104 LinBoolInt<VX>::dispose(Space& home) {
00105 Advisors<Advisor> as(co);
00106 for (int i=n_hs; i--; )
00107 x[i].cancel(home,as.advisor());
00108 co.dispose(home);
00109 (void) Propagator::dispose(home);
00110 return sizeof(*this);
00111 }
00112
00113
00114
00115
00116
00117 template<class VX>
00118 forceinline
00119 GqBoolInt<VX>::GqBoolInt(Home home, ViewArray<VX>& x, int c)
00120 : LinBoolInt<VX>(home,x,c+1,c) {}
00121
00122 template<class VX>
00123 forceinline
00124 GqBoolInt<VX>::GqBoolInt(Space& home, bool share, GqBoolInt<VX>& p)
00125 : LinBoolInt<VX>(home,share,p) {}
00126
00127 template<class VX>
00128 Actor*
00129 GqBoolInt<VX>::copy(Space& home, bool share) {
00130 return new (home) GqBoolInt<VX>(home,share,*this);
00131 }
00132
00133 template<class VX>
00134 ExecStatus
00135 GqBoolInt<VX>::advise(Space& home, Advisor& a, const Delta& d) {
00136
00137 if (n_as == 0)
00138 return ES_FIX;
00139
00140 if (VX::one(d)) {
00141 c--; goto check;
00142 }
00143 if (c+1 < n_as)
00144 goto check;
00145
00146 for (int i = x.size()-1; i>=n_hs; i--)
00147 if (x[i].none()) {
00148 std::swap(x[i],x[n_hs]);
00149 x[n_hs++].subscribe(home,a);
00150 x.size(i+1);
00151 return ES_FIX;
00152 } else if (x[i].one()) {
00153 c--;
00154 if (c+1 < n_as) {
00155 x.size(i);
00156 assert(n_hs <= x.size());
00157 goto check;
00158 }
00159 }
00160
00161 x.size(n_hs);
00162 check:
00163
00164 n_as--;
00165 int n = x.size()-n_hs+n_as;
00166 if ((n < c) && !disabled())
00167 return ES_FAILED;
00168 if ((c <= 0) || (c == n))
00169 return ES_NOFIX;
00170 else
00171 return ES_FIX;
00172 }
00173
00174 template<class VX>
00175 void
00176 GqBoolInt<VX>::reschedule(Space& home) {
00177 int n = x.size()-n_hs+n_as;
00178 if ((c <= 0) || (c >= n))
00179 VX::schedule(home,*this,ME_INT_VAL);
00180 }
00181
00182 template<class VX>
00183 ExecStatus
00184 GqBoolInt<VX>::propagate(Space& home, const ModEventDelta&) {
00185
00186 if (x.size() - n_hs + n_as < c)
00187 return ES_FAILED;
00188 if (c > 0) {
00189 assert((n_as == c) && (x.size() == n_hs));
00190
00191 n_as = 0;
00192
00193 for (int i=n_hs; i--; )
00194 if (x[i].none())
00195 GECODE_ME_CHECK(x[i].one_none(home));
00196 }
00197 return home.ES_SUBSUMED(*this);
00198 }
00199
00200 template<class VX>
00201 ExecStatus
00202 GqBoolInt<VX>::post(Home home, ViewArray<VX>& x, int c) {
00203
00204 int n_x = x.size();
00205 for (int i=n_x; i--; )
00206 if (x[i].zero()) {
00207 x[i] = x[--n_x];
00208 } else if (x[i].one()) {
00209 x[i] = x[--n_x]; c--;
00210 }
00211 x.size(n_x);
00212
00213 if (n_x < c)
00214 return ES_FAILED;
00215
00216 if (c <= 0)
00217 return ES_OK;
00218
00219 if (c == 1)
00220 return Bool::NaryOrTrue<VX>::post(home,x);
00221
00222 if (c == n_x) {
00223 for (int i=n_x; i--; )
00224 GECODE_ME_CHECK(x[i].one_none(home));
00225 return ES_OK;
00226 }
00227
00228 assert(n_x > c);
00229 (void) new (home) GqBoolInt<VX>(home,x,c);
00230 return ES_OK;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240 template<class VX>
00241 forceinline
00242 EqBoolInt<VX>::EqBoolInt(Home home, ViewArray<VX>& x, int c)
00243 : LinBoolInt<VX>(home,x,std::max(c,x.size()-c)+1,c) {}
00244
00245 template<class VX>
00246 forceinline
00247 EqBoolInt<VX>::EqBoolInt(Space& home, bool share, EqBoolInt<VX>& p)
00248 : LinBoolInt<VX>(home,share,p) {}
00249
00250 template<class VX>
00251 Actor*
00252 EqBoolInt<VX>::copy(Space& home, bool share) {
00253 return new (home) EqBoolInt<VX>(home,share,*this);
00254 }
00255
00256 template<class VX>
00257 ExecStatus
00258 EqBoolInt<VX>::advise(Space& home, Advisor& a, const Delta& d) {
00259
00260 if (n_as == 0)
00261 return ES_FIX;
00262
00263 if (VX::one(d))
00264 c--;
00265 if ((c+1 < n_as) && (x.size()-n_hs < c))
00266 goto check;
00267
00268 for (int i = x.size()-1; i>=n_hs; i--)
00269 if (x[i].none()) {
00270 std::swap(x[i],x[n_hs]);
00271 x[n_hs++].subscribe(home,a);
00272 x.size(i+1);
00273 return ES_FIX;
00274 } else if (x[i].one()) {
00275 c--;
00276 }
00277
00278 x.size(n_hs);
00279 check:
00280
00281 n_as--;
00282 int n = x.size()-n_hs+n_as;
00283 if (((c < 0) || (c > n)) && !disabled())
00284 return ES_FAILED;
00285 if ((c == 0) || (c == n))
00286 return ES_NOFIX;
00287 else
00288 return ES_FIX;
00289 }
00290
00291 template<class VX>
00292 void
00293 EqBoolInt<VX>::reschedule(Space& home) {
00294 int n = x.size()-n_hs+n_as;
00295 if ((c <= 0) || (c >= n))
00296 VX::schedule(home,*this,ME_INT_VAL);
00297 }
00298
00299 template<class VX>
00300 ExecStatus
00301 EqBoolInt<VX>::propagate(Space& home, const ModEventDelta&) {
00302
00303 if ((c < 0) || (c > x.size()-n_hs+n_as))
00304 return ES_FAILED;
00305
00306 assert(x.size() == n_hs);
00307
00308 n_as = 0;
00309 if (c == 0) {
00310
00311 for (int i=n_hs; i--; )
00312 if (x[i].none())
00313 GECODE_ME_CHECK(x[i].zero_none(home));
00314 } else {
00315
00316 for (int i=n_hs; i--; )
00317 if (x[i].none())
00318 GECODE_ME_CHECK(x[i].one_none(home));
00319 }
00320 return home.ES_SUBSUMED(*this);
00321 }
00322
00323 template<class VX>
00324 ExecStatus
00325 EqBoolInt<VX>::post(Home home, ViewArray<VX>& x, int c) {
00326
00327 int n_x = x.size();
00328 for (int i=n_x; i--; )
00329 if (x[i].zero()) {
00330 x[i] = x[--n_x];
00331 } else if (x[i].one()) {
00332 x[i] = x[--n_x]; c--;
00333 }
00334 x.size(n_x);
00335
00336 if ((c < 0) || (c > n_x))
00337 return ES_FAILED;
00338
00339 if (c == 0) {
00340 for (int i=n_x; i--; )
00341 GECODE_ME_CHECK(x[i].zero_none(home));
00342 return ES_OK;
00343 }
00344
00345 if (c == n_x) {
00346 for (int i=n_x; i--; )
00347 GECODE_ME_CHECK(x[i].one_none(home));
00348 return ES_OK;
00349 }
00350 (void) new (home) EqBoolInt<VX>(home,x,c);
00351 return ES_OK;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360 template<class VX>
00361 forceinline
00362 NqBoolInt<VX>::NqBoolInt(Home home, ViewArray<VX>& b, int c0)
00363 : BinaryPropagator<VX,PC_INT_VAL>(home,
00364 b[b.size()-2],
00365 b[b.size()-1]), x(b), c(c0) {
00366 assert(x.size() >= 2);
00367 x.size(x.size()-2);
00368 }
00369
00370 template<class VX>
00371 forceinline size_t
00372 NqBoolInt<VX>::dispose(Space& home) {
00373 (void) BinaryPropagator<VX,PC_INT_VAL>::dispose(home);
00374 return sizeof(*this);
00375 }
00376
00377 template<class VX>
00378 forceinline
00379 NqBoolInt<VX>::NqBoolInt(Space& home, bool share, NqBoolInt<VX>& p)
00380 : BinaryPropagator<VX,PC_INT_VAL>(home,share,p), x(home,p.x.size()) {
00381
00382 int n = p.x.size();
00383 int p_c = p.c;
00384 for (int i=n; i--; )
00385 if (p.x[i].zero()) {
00386 n--; p.x[i]=p.x[n]; x[i]=x[n];
00387 } else if (p.x[i].one()) {
00388 n--; p_c--; p.x[i]=p.x[n]; x[i]=x[n];
00389 } else {
00390 x[i].update(home,share,p.x[i]);
00391 }
00392 c = p_c; p.c = p_c;
00393 x.size(n); p.x.size(n);
00394 }
00395
00396 template<class VX>
00397 forceinline ExecStatus
00398 NqBoolInt<VX>::post(Home home, ViewArray<VX>& x, int c) {
00399 int n = x.size();
00400 for (int i=n; i--; )
00401 if (x[i].one()) {
00402 x[i]=x[--n]; c--;
00403 } else if (x[i].zero()) {
00404 x[i]=x[--n];
00405 }
00406 x.size(n);
00407 if ((n < c) || (c < 0))
00408 return ES_OK;
00409 if (n == 0)
00410 return (c == 0) ? ES_FAILED : ES_OK;
00411 if (n == 1) {
00412 if (c == 1) {
00413 GECODE_ME_CHECK(x[0].zero_none(home));
00414 } else {
00415 GECODE_ME_CHECK(x[0].one_none(home));
00416 }
00417 return ES_OK;
00418 }
00419 (void) new (home) NqBoolInt(home,x,c);
00420 return ES_OK;
00421 }
00422
00423 template<class VX>
00424 Actor*
00425 NqBoolInt<VX>::copy(Space& home, bool share) {
00426 return new (home) NqBoolInt<VX>(home,share,*this);
00427 }
00428
00429 template<class VX>
00430 PropCost
00431 NqBoolInt<VX>::cost(const Space&, const ModEventDelta&) const {
00432 return PropCost::linear(PropCost::LO, x.size());
00433 }
00434
00435 template<class VX>
00436 forceinline bool
00437 NqBoolInt<VX>::resubscribe(Space& home, VX& y) {
00438 if (y.one())
00439 c--;
00440 int n = x.size();
00441 for (int i=n; i--; )
00442 if (x[i].one()) {
00443 c--; x[i]=x[--n];
00444 } else if (x[i].zero()) {
00445 x[i] = x[--n];
00446 } else {
00447
00448 assert(!x[i].zero() && !x[i].one());
00449
00450 y=x[i]; x[i]=x[--n];
00451 x.size(n);
00452 y.subscribe(home,*this,PC_INT_VAL,false);
00453 return true;
00454 }
00455
00456 x.size(0);
00457 return false;
00458 }
00459
00460 template<class VX>
00461 ExecStatus
00462 NqBoolInt<VX>::propagate(Space& home, const ModEventDelta&) {
00463 bool s0 = true;
00464 if (x0.zero() || x0.one())
00465 s0 = resubscribe(home,x0);
00466 bool s1 = true;
00467 if (x1.zero() || x1.one())
00468 s1 = resubscribe(home,x1);
00469 int n = x.size() + s0 + s1;
00470 if ((n < c) || (c < 0))
00471 return home.ES_SUBSUMED(*this);
00472 if (n == 0)
00473 return (c == 0) ? ES_FAILED : home.ES_SUBSUMED(*this);
00474 if (n == 1) {
00475 if (s0) {
00476 if (c == 1) {
00477 GECODE_ME_CHECK(x0.zero_none(home));
00478 } else {
00479 GECODE_ME_CHECK(x0.one_none(home));
00480 }
00481 } else {
00482 assert(s1);
00483 if (c == 1) {
00484 GECODE_ME_CHECK(x1.zero_none(home));
00485 } else {
00486 GECODE_ME_CHECK(x1.one_none(home));
00487 }
00488 }
00489 return home.ES_SUBSUMED(*this);
00490 }
00491 return ES_FIX;
00492 }
00493
00494
00495
00496
00497
00498 template<class VX, class VB>
00499 forceinline
00500 ReLinBoolInt<VX,VB>::ReLinBoolInt(Home home, ViewArray<VX>& x0,
00501 int c0, VB b0)
00502 : Propagator(home), co(home), x(x0), n_s(x.size()), c(c0), b(b0) {
00503 x.subscribe(home,*new (home) Advisor(home,*this,co));
00504 b.subscribe(home,*this,PC_BOOL_VAL);
00505 }
00506
00507 template<class VX, class VB>
00508 forceinline void
00509 ReLinBoolInt<VX,VB>::normalize(void) {
00510 if (n_s != x.size()) {
00511 int n_x = x.size();
00512 for (int i=n_x; i--; )
00513 if (!x[i].none())
00514 x[i] = x[--n_x];
00515 x.size(n_x);
00516 assert(x.size() == n_s);
00517 }
00518 }
00519
00520 template<class VX, class VB>
00521 forceinline
00522 ReLinBoolInt<VX,VB>::ReLinBoolInt(Space& home, bool share,
00523 ReLinBoolInt<VX,VB>& p)
00524 : Propagator(home,share,p), n_s(p.n_s), c(p.c) {
00525 p.normalize();
00526 co.update(home,share,p.co);
00527 x.update(home,share,p.x);
00528 b.update(home,share,p.b);
00529 }
00530
00531 template<class VX, class VB>
00532 forceinline size_t
00533 ReLinBoolInt<VX,VB>::dispose(Space& home) {
00534 Advisors<Advisor> as(co);
00535 x.cancel(home,as.advisor());
00536 co.dispose(home);
00537 b.cancel(home,*this,PC_BOOL_VAL);
00538 (void) Propagator::dispose(home);
00539 return sizeof(*this);
00540 }
00541
00542 template<class VX, class VB>
00543 PropCost
00544 ReLinBoolInt<VX,VB>::cost(const Space&, const ModEventDelta&) const {
00545 return PropCost::unary(PropCost::HI);
00546 }
00547
00548 template<>
00550 class BoolNegTraits<BoolView> {
00551 public:
00553 typedef NegBoolView NegView;
00555 static NegBoolView neg(BoolView x) {
00556 NegBoolView y(x); return y;
00557 }
00558 };
00559
00560 template<>
00562 class BoolNegTraits<NegBoolView> {
00563 public:
00565 typedef BoolView NegView;
00567 static BoolView neg(NegBoolView x) {
00568 return x.base();
00569 }
00570 };
00571
00572
00573
00574
00575
00576
00577 template<class VX, class VB, ReifyMode rm>
00578 forceinline
00579 ReGqBoolInt<VX,VB,rm>::ReGqBoolInt(Home home, ViewArray<VX>& x, int c, VB b)
00580 : ReLinBoolInt<VX,VB>(home,x,c,b) {}
00581
00582 template<class VX, class VB, ReifyMode rm>
00583 forceinline
00584 ReGqBoolInt<VX,VB,rm>::ReGqBoolInt(Space& home, bool share,
00585 ReGqBoolInt<VX,VB,rm>& p)
00586 : ReLinBoolInt<VX,VB>(home,share,p) {}
00587
00588 template<class VX, class VB, ReifyMode rm>
00589 Actor*
00590 ReGqBoolInt<VX,VB,rm>::copy(Space& home, bool share) {
00591 return new (home) ReGqBoolInt<VX,VB,rm>(home,share,*this);
00592 }
00593
00594 template<class VX, class VB, ReifyMode rm>
00595 ExecStatus
00596 ReGqBoolInt<VX,VB,rm>::advise(Space&, Advisor&, const Delta& d) {
00597 if (VX::one(d))
00598 c--;
00599 n_s--;
00600 if ((n_s < c) || (c <= 0))
00601 return ES_NOFIX;
00602 else
00603 return ES_FIX;
00604 }
00605
00606 template<class VX, class VB, ReifyMode rm>
00607 void
00608 ReGqBoolInt<VX,VB,rm>::reschedule(Space& home) {
00609 b.reschedule(home,*this,PC_BOOL_VAL);
00610 if ((n_s < c) || (c <= 0))
00611 VX::schedule(home,*this,ME_BOOL_VAL);
00612 }
00613
00614 template<class VX, class VB, ReifyMode rm>
00615 ExecStatus
00616 ReGqBoolInt<VX,VB,rm>::propagate(Space& home, const ModEventDelta&) {
00617 if (b.none()) {
00618 if (c <= 0) {
00619 if (rm != RM_IMP)
00620 GECODE_ME_CHECK(b.one_none(home));
00621 } else {
00622 if (rm != RM_PMI)
00623 GECODE_ME_CHECK(b.zero_none(home));
00624 }
00625 } else {
00626 normalize();
00627 if (b.one()) {
00628 if (rm != RM_PMI)
00629 GECODE_REWRITE(*this,(GqBoolInt<VX>::post(home(*this),x,c)));
00630 } else {
00631 if (rm != RM_IMP) {
00632 ViewArray<typename BoolNegTraits<VX>::NegView> nx(home,x.size());
00633 for (int i=x.size(); i--; )
00634 nx[i]=BoolNegTraits<VX>::neg(x[i]);
00635 GECODE_REWRITE(*this,GqBoolInt<typename BoolNegTraits<VX>::NegView>
00636 ::post(home(*this),nx,x.size()-c+1));
00637 }
00638 }
00639 }
00640 return home.ES_SUBSUMED(*this);
00641 }
00642
00643 template<class VX, class VB, ReifyMode rm>
00644 ExecStatus
00645 ReGqBoolInt<VX,VB,rm>::post(Home home, ViewArray<VX>& x, int c, VB b) {
00646 assert(!b.assigned());
00647
00648
00649 int n_x = x.size();
00650 for (int i=n_x; i--; )
00651 if (x[i].zero()) {
00652 x[i] = x[--n_x];
00653 } else if (x[i].one()) {
00654 x[i] = x[--n_x]; c--;
00655 }
00656 x.size(n_x);
00657 if (n_x < c) {
00658
00659 if (rm != RM_PMI)
00660 GECODE_ME_CHECK(b.zero_none(home));
00661 } else if (c <= 0) {
00662
00663 if (rm != RM_IMP)
00664 GECODE_ME_CHECK(b.one_none(home));
00665 } else if ((c == 1) && (rm == RM_EQV)) {
00666
00667 return Bool::NaryOr<VX,VB>::post(home,x,b);
00668 } else if ((c == n_x) && (rm == RM_EQV)) {
00669
00670 ViewArray<typename BoolNegTraits<VX>::NegView> nx(home,n_x);
00671 for (int i=n_x; i--; )
00672 nx[i]=BoolNegTraits<VX>::neg(x[i]);
00673 return Bool::NaryOr
00674 <typename BoolNegTraits<VX>::NegView,
00675 typename BoolNegTraits<VB>::NegView>
00676 ::post(home,nx,BoolNegTraits<VB>::neg(b));
00677 } else {
00678 (void) new (home) ReGqBoolInt<VX,VB,rm>(home,x,c,b);
00679 }
00680 return ES_OK;
00681 }
00682
00683
00684
00685
00686
00687 template<class VX, class VB, ReifyMode rm>
00688 forceinline
00689 ReEqBoolInt<VX,VB,rm>::ReEqBoolInt(Home home, ViewArray<VX>& x, int c, VB b)
00690 : ReLinBoolInt<VX,VB>(home,x,c,b) {}
00691
00692 template<class VX, class VB, ReifyMode rm>
00693 forceinline
00694 ReEqBoolInt<VX,VB,rm>::ReEqBoolInt(Space& home, bool share,
00695 ReEqBoolInt<VX,VB,rm>& p)
00696 : ReLinBoolInt<VX,VB>(home,share,p) {}
00697
00698 template<class VX, class VB, ReifyMode rm>
00699 Actor*
00700 ReEqBoolInt<VX,VB,rm>::copy(Space& home, bool share) {
00701 return new (home) ReEqBoolInt<VX,VB,rm>(home,share,*this);
00702 }
00703
00704 template<class VX, class VB, ReifyMode rm>
00705 ExecStatus
00706 ReEqBoolInt<VX,VB,rm>::advise(Space&, Advisor&, const Delta& d) {
00707 if (VX::one(d))
00708 c--;
00709 n_s--;
00710
00711 if ((c < 0) || (c > n_s) || (n_s == 0))
00712 return ES_NOFIX;
00713 else
00714 return ES_FIX;
00715 }
00716
00717 template<class VX, class VB, ReifyMode rm>
00718 void
00719 ReEqBoolInt<VX,VB,rm>::reschedule(Space& home) {
00720 b.reschedule(home,*this,PC_BOOL_VAL);
00721 if ((c < 0) || (c > n_s) || (n_s == 0))
00722 VX::schedule(home,*this,ME_BOOL_VAL);
00723 }
00724
00725 template<class VX, class VB, ReifyMode rm>
00726 ExecStatus
00727 ReEqBoolInt<VX,VB,rm>::propagate(Space& home, const ModEventDelta&) {
00728 if (b.none()) {
00729 if ((c == 0) && (n_s == 0)) {
00730 if (rm != RM_IMP)
00731 GECODE_ME_CHECK(b.one_none(home));
00732 } else {
00733 if (rm != RM_PMI)
00734 GECODE_ME_CHECK(b.zero_none(home));
00735 }
00736 } else {
00737 normalize();
00738 if (b.one()) {
00739 if (rm != RM_PMI)
00740 GECODE_REWRITE(*this,(EqBoolInt<VX>::post(home(*this),x,c)));
00741 } else {
00742 if (rm != RM_IMP)
00743 GECODE_REWRITE(*this,(NqBoolInt<VX>::post(home(*this),x,c)));
00744 }
00745 }
00746 return home.ES_SUBSUMED(*this);
00747 }
00748
00749 template<class VX, class VB, ReifyMode rm>
00750 ExecStatus
00751 ReEqBoolInt<VX,VB,rm>::post(Home home, ViewArray<VX>& x, int c, VB b) {
00752 assert(!b.assigned());
00753
00754
00755 int n_x = x.size();
00756 for (int i=n_x; i--; )
00757 if (x[i].zero()) {
00758 x[i] = x[--n_x];
00759 } else if (x[i].one()) {
00760 x[i] = x[--n_x]; c--;
00761 }
00762 x.size(n_x);
00763 if ((n_x < c) || (c < 0)) {
00764
00765 if (rm != RM_PMI)
00766 GECODE_ME_CHECK(b.zero_none(home));
00767 } else if ((c == 0) && (n_x == 0)) {
00768
00769 if (rm != RM_IMP)
00770 GECODE_ME_CHECK(b.one_none(home));
00771 } else if ((c == 0) && (rm == RM_EQV)) {
00772
00773 return Bool::NaryOr<VX,typename BoolNegTraits<VB>::NegView>
00774 ::post(home,x,BoolNegTraits<VB>::neg(b));
00775 } else if ((c == n_x) && (rm == RM_EQV)) {
00776
00777 ViewArray<typename BoolNegTraits<VX>::NegView> nx(home,n_x);
00778 for (int i=n_x; i--; )
00779 nx[i]=BoolNegTraits<VX>::neg(x[i]);
00780 return Bool::NaryOr
00781 <typename BoolNegTraits<VX>::NegView,
00782 typename BoolNegTraits<VB>::NegView>
00783 ::post(home,nx,BoolNegTraits<VB>::neg(b));
00784 } else {
00785 (void) new (home) ReEqBoolInt<VX,VB,rm>(home,x,c,b);
00786 }
00787 return ES_OK;
00788 }
00789
00790
00791 }}}
00792
00793
00794