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