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