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 namespace Gecode { namespace Int { namespace Rel {
00041
00042
00043
00044
00045
00046
00047 template<class V0, class V1>
00048 forceinline
00049 Lq<V0,V1>::Lq(Home home, V0 x0, V1 x1)
00050 : MixBinaryPropagator<V0,PC_INT_BND,V1,PC_INT_BND>(home,x0,x1) {}
00051
00052 template<class V0, class V1>
00053 forceinline bool
00054 Lq<V0,V1>::same(V0 x0, V1 x1) {
00055 (void) x0; (void) x1;
00056 return false;
00057 }
00058
00059 template<>
00060 forceinline bool
00061 Lq<IntView,IntView>::same(IntView x0, IntView x1) {
00062 return Gecode::same(x0,x1);
00063 }
00064
00065 template<>
00066 forceinline bool
00067 Lq<BoolView,BoolView>::same(BoolView x0, BoolView x1) {
00068 return Gecode::same(x0,x1);
00069 }
00070
00071 template<class V0, class V1>
00072 ExecStatus
00073 Lq<V0,V1>::post(Home home, V0 x0, V1 x1) {
00074 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00075 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00076 if (!same(x0,x1) && (x0.max() > x1.min()))
00077 (void) new (home) Lq<V0,V1>(home,x0,x1);
00078 return ES_OK;
00079 }
00080
00081 template<class V0, class V1>
00082 forceinline
00083 Lq<V0,V1>::Lq(Space& home, bool share, Lq<V0,V1>& p)
00084 : MixBinaryPropagator<V0,PC_INT_BND,V1,PC_INT_BND>(home,share,p) {}
00085
00086 template<class V0, class V1>
00087 Actor*
00088 Lq<V0,V1>::copy(Space& home, bool share) {
00089 return new (home) Lq<V0,V1>(home,share,*this);
00090 }
00091
00092 template<class V0, class V1>
00093 ExecStatus
00094 Lq<V0,V1>::propagate(Space& home, const ModEventDelta&) {
00095 GECODE_ME_CHECK(x0.lq(home,x1.max()));
00096 GECODE_ME_CHECK(x1.gq(home,x0.min()));
00097 return (x0.max() <= x1.min()) ? home.ES_SUBSUMED(*this) : ES_FIX;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107 template<class V0, class V1>
00108 forceinline
00109 Le<V0,V1>::Le(Home home, V0 x0, V1 x1)
00110 : MixBinaryPropagator<V0,PC_INT_BND,V1,PC_INT_BND>(home,x0,x1) {}
00111
00112 template<class V0, class V1>
00113 forceinline bool
00114 Le<V0,V1>::same(V0 x0, V1 x1) {
00115 (void) x0; (void) x1;
00116 return false;
00117 }
00118
00119 template<>
00120 forceinline bool
00121 Le<IntView,IntView>::same(IntView x0, IntView x1) {
00122 return Gecode::same(x0,x1);
00123 }
00124
00125 template<>
00126 forceinline bool
00127 Le<MinusView,MinusView>::same(MinusView x0, MinusView x1) {
00128 return Gecode::same(x0,x1);
00129 }
00130
00131 template<>
00132 forceinline bool
00133 Le<BoolView,BoolView>::same(BoolView x0, BoolView x1) {
00134 return Gecode::same(x0,x1);
00135 }
00136
00137 template<class V0, class V1>
00138 ExecStatus
00139 Le<V0,V1>::post(Home home, V0 x0, V1 x1) {
00140 if (same(x0,x1))
00141 return ES_FAILED;
00142 GECODE_ME_CHECK(x0.le(home,x1.max()));
00143 GECODE_ME_CHECK(x1.gr(home,x0.min()));
00144 if (x0.max() >= x1.min())
00145 (void) new (home) Le<V0,V1>(home,x0,x1);
00146 return ES_OK;
00147 }
00148
00149 template<class V0, class V1>
00150 forceinline
00151 Le<V0,V1>::Le(Space& home, bool share, Le<V0,V1>& p)
00152 : MixBinaryPropagator<V0,PC_INT_BND,V1,PC_INT_BND>(home,share,p) {}
00153
00154 template<class V0, class V1>
00155 Actor*
00156 Le<V0,V1>::copy(Space& home, bool share) {
00157 return new (home) Le<V0,V1>(home,share,*this);
00158 }
00159
00160 template<class V0, class V1>
00161 ExecStatus
00162 Le<V0,V1>::propagate(Space& home, const ModEventDelta&) {
00163 GECODE_ME_CHECK(x0.le(home,x1.max()));
00164 GECODE_ME_CHECK(x1.gr(home,x0.min()));
00165 return (x0.max() < x1.min()) ? home.ES_SUBSUMED(*this) : ES_FIX;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 template<class View, int o>
00176 forceinline
00177 NaryLqLe<View,o>::Index::Index(Space& home, Propagator& p,
00178 Council<Index>& c, int i0)
00179 : Advisor(home,p,c), i(i0) {}
00180
00181 template<class View, int o>
00182 forceinline
00183 NaryLqLe<View,o>::Index::Index(Space& home, bool share, Index& a)
00184 : Advisor(home,share,a), i(a.i) {}
00185
00186
00187
00188 template<class View, int o>
00189 forceinline
00190 NaryLqLe<View,o>::Pos::Pos(int p0, Pos* n)
00191 : FreeList(n), p(p0) {}
00192
00193 template<class View, int o>
00194 forceinline typename NaryLqLe<View,o>::Pos*
00195 NaryLqLe<View,o>::Pos::next(void) const {
00196 return static_cast<Pos*>(FreeList::next());
00197 }
00198
00199 template<class View, int o>
00200 forceinline void
00201 NaryLqLe<View,o>::Pos::operator delete(void*) {}
00202
00203 template<class View, int o>
00204 forceinline void
00205 NaryLqLe<View,o>::Pos::operator delete(void*, Space&) {
00206 GECODE_NEVER;
00207 }
00208
00209 template<class View, int o>
00210 forceinline void*
00211 NaryLqLe<View,o>::Pos::operator new(size_t, Space& home) {
00212 return home.fl_alloc<sizeof(Pos)>();
00213 }
00214
00215 template<class View, int o>
00216 forceinline void
00217 NaryLqLe<View,o>::Pos::dispose(Space& home) {
00218 home.fl_dispose<sizeof(Pos)>(this,this);
00219 }
00220
00221
00222 template<class View, int o>
00223 forceinline bool
00224 NaryLqLe<View,o>::empty(void) const {
00225 return pos == NULL;
00226 }
00227 template<class View, int o>
00228 forceinline void
00229 NaryLqLe<View,o>::push(Space& home, int p) {
00230
00231 if ((pos != NULL) && (pos->p == p))
00232 return;
00233 pos = new (home) Pos(p,pos);
00234 }
00235 template<class View, int o>
00236 forceinline int
00237 NaryLqLe<View,o>::pop(Space& home) {
00238 Pos* t = pos;
00239 int p = t->p;
00240 pos = pos->next();
00241 t->dispose(home);
00242 return p;
00243 }
00244
00245 template<class View, int o>
00246 forceinline
00247 NaryLqLe<View,o>::NaryLqLe(Home home, ViewArray<View>& x)
00248 : NaryPropagator<View,PC_INT_NONE>(home,x),
00249 c(home), pos(NULL), run(false), n_subsumed(0) {
00250 for (int i=x.size(); i--; )
00251 x[i].subscribe(home, *new (home) Index(home,*this,c,i));
00252 }
00253
00254 template<class View, int o>
00255 ExecStatus
00256 NaryLqLe<View,o>::post(Home home, ViewArray<View>& x) {
00257 assert((o == 0) || (o == 1));
00258
00259 if (x.same(home)) {
00260 if (o == 1)
00261 return ES_FAILED;
00262
00263
00264
00265
00266 int n = x.size();
00267 for (int i=0; i<n; i++)
00268 for (int j=n-1; j>i; j--)
00269 if (same(x[i],x[j])) {
00270 if (i+1 != j) {
00271
00272 ViewArray<View> y(home,j-i);
00273 for (int k=j-i; k--; )
00274 y[k] = x[i+1+k];
00275 GECODE_ES_CHECK(NaryEqBnd<View>::post(home,y));
00276 }
00277 for (int k=0; k<n-1-j-1+1; k++)
00278 x[i+1+k]=x[j+1+k];
00279 n -= j-i;
00280 break;
00281 }
00282 x.size(n);
00283 }
00284
00285
00286 for (int i=1; i<x.size(); i++)
00287 GECODE_ME_CHECK(x[i].gq(home,x[i-1].min()+o));
00288 for (int i=x.size()-1; i--;)
00289 GECODE_ME_CHECK(x[i].lq(home,x[i+1].max()-o));
00290
00291 {
00292
00293 {
00294 int i=0;
00295 while ((i+1 < x.size()) && (x[i].max()+o <= x[i+1].min()))
00296 i++;
00297 x.drop_fst(i);
00298 }
00299
00300 {
00301 int i=x.size()-1;
00302 while ((i > 0) && (x[i-1].max()+o <= x[i].min()))
00303 i--;
00304 x.drop_lst(i);
00305 }
00306
00307 if (x.size() > 1) {
00308 int j=1;
00309 for (int i=1; i+1<x.size(); i++)
00310 if ((x[j-1].max()+o > x[i].min()) ||
00311 (x[i].max()+o > x[i+1].min()))
00312 x[j++]=x[i];
00313 x[j++]=x[x.size()-1];
00314 x.size(j);
00315 }
00316 }
00317 if (x.size() == 2) {
00318 if (o == 0)
00319 return Lq<View,View>::post(home,x[0],x[1]);
00320 else
00321 return Le<View,View>::post(home,x[0],x[1]);
00322 } else if (x.size() >= 2) {
00323 (void) new (home) NaryLqLe<View,o>(home,x);
00324 }
00325 return ES_OK;
00326 }
00327
00328 template<class View, int o>
00329 forceinline
00330 NaryLqLe<View,o>::NaryLqLe(Space& home, bool share, NaryLqLe<View,o>& p)
00331 : NaryPropagator<View,PC_INT_NONE>(home,share,p),
00332 pos(NULL), run(false), n_subsumed(p.n_subsumed) {
00333 assert(p.pos == NULL);
00334 c.update(home, share, p.c);
00335 }
00336
00337 template<class View, int o>
00338 Actor*
00339 NaryLqLe<View,o>::copy(Space& home, bool share) {
00340 if (n_subsumed > n_threshold) {
00341 Region r(home);
00342
00343 Support::BitSet<Region> a(r,static_cast<unsigned int>(x.size()));
00344 for (Advisors<Index> as(c); as(); ++as)
00345 a.set(static_cast<unsigned int>(as.advisor().i));
00346
00347 int* m = r.alloc<int>(x.size());
00348 int j=0;
00349 for (int i=0; i<x.size(); i++)
00350 if (a.get(static_cast<unsigned int>(i))) {
00351 m[i] = j; x[j++] = x[i];
00352 }
00353 x.size(j);
00354
00355 for (Advisors<Index> as(c); as(); ++as)
00356 as.advisor().i = m[as.advisor().i];
00357
00358 n_subsumed = 0;
00359 }
00360 return new (home) NaryLqLe<View,o>(home,share,*this);
00361 }
00362
00363 template<class View, int o>
00364 PropCost
00365 NaryLqLe<View,o>::cost(const Space&, const ModEventDelta&) const {
00366 return PropCost::binary(PropCost::HI);
00367 }
00368
00369 template<class View, int o>
00370 forceinline size_t
00371 NaryLqLe<View,o>::dispose(Space& home) {
00372 for (Advisors<Index> as(c); as(); ++as)
00373 x[as.advisor().i].cancel(home,as.advisor());
00374 c.dispose(home);
00375 while (!empty())
00376 (void) pop(home);
00377 (void) NaryPropagator<View,PC_INT_NONE>::dispose(home);
00378 return sizeof(*this);
00379 }
00380
00381
00382 template<class View, int o>
00383 ExecStatus
00384 NaryLqLe<View,o>::advise(Space& home, Advisor& _a, const Delta& d) {
00385 Index& a = static_cast<Index&>(_a);
00386 const int i = a.i;
00387 switch (View::modevent(d)) {
00388 case ME_INT_VAL:
00389 a.dispose(home,c);
00390 n_subsumed++;
00391 break;
00392 case ME_INT_BND:
00393 if (((i == 0) || (x[i-1].max()+o <= x[i].min())) &&
00394 ((i == x.size()-1) || (x[i].max()+o <= x[i+1].min()))) {
00395 x[i].cancel(home,a);
00396 a.dispose(home,c);
00397 n_subsumed++;
00398 return (run || (n_subsumed + 1 < x.size())) ? ES_FIX : ES_NOFIX;
00399 }
00400 break;
00401 default:
00402 return ES_FIX;
00403 }
00404 if (run)
00405 return ES_FIX;
00406 if (((i < x.size()-1) && (x[i+1].min() < x[i].min()+o)) ||
00407 ((i > 0) && (x[i-1].max() > x[i].max()-o))) {
00408 push(home,i);
00409 return ES_NOFIX;
00410 }
00411 return (n_subsumed+1 >= x.size()) ? ES_NOFIX : ES_FIX;
00412 }
00413
00414 template<class View, int o>
00415 void
00416 NaryLqLe<View,o>::reschedule(Space& home) {
00417 View::schedule(home, *this, ME_INT_BND);
00418 }
00419
00420 template<class View, int o>
00421 ExecStatus
00422 NaryLqLe<View,o>::propagate(Space& home, const ModEventDelta&) {
00423 run = true;
00424 int n = x.size();
00425 while (!empty()) {
00426 int p = pop(home);
00427 for (int i=p; i<n-1; i++) {
00428 ModEvent me = x[i+1].gq(home,x[i].min()+o);
00429 if (me_failed(me))
00430 return ES_FAILED;
00431 if (!me_modified(me))
00432 break;
00433 }
00434 for (int i=p; i>0; i--) {
00435 ModEvent me = x[i-1].lq(home,x[i].max()-o);
00436 if (me_failed(me))
00437 return ES_FAILED;
00438 if (!me_modified(me))
00439 break;
00440 }
00441 }
00442 #ifdef GECODE_AUDIT
00443 for (int i=0; i<n-1; i++)
00444 assert(!me_modified(x[i+1].gq(home,x[i].min()+o)));
00445 for (int i=n-1; i>0; i--)
00446 assert(!me_modified(x[i-1].lq(home,x[i].max()-o)));
00447 #endif
00448 if (n_subsumed+1 >= n)
00449 return home.ES_SUBSUMED(*this);
00450 run = false;
00451 return ES_FIX;
00452 }
00453
00454
00455
00456
00457
00458
00459
00460
00461 template<class View, class CtrlView, ReifyMode rm>
00462 forceinline
00463 ReLq<View,CtrlView,rm>::ReLq(Home home, View x0, View x1, CtrlView b)
00464 : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,x0,x1,b) {}
00465
00466 template<class View, class CtrlView, ReifyMode rm>
00467 ExecStatus
00468 ReLq<View,CtrlView,rm>::post(Home home, View x0, View x1, CtrlView b) {
00469 if (b.one()) {
00470 if (rm == RM_PMI)
00471 return ES_OK;
00472 return Lq<View,View>::post(home,x0,x1);
00473 }
00474 if (b.zero()) {
00475 if (rm == RM_IMP)
00476 return ES_OK;
00477 return Le<View,View>::post(home,x1,x0);
00478 }
00479 if (!same(x0,x1)) {
00480 switch (rtest_lq(x0,x1)) {
00481 case RT_TRUE:
00482 if (rm != RM_IMP)
00483 GECODE_ME_CHECK(b.one_none(home));
00484 break;
00485 case RT_FALSE:
00486 if (rm != RM_PMI)
00487 GECODE_ME_CHECK(b.zero_none(home));
00488 break;
00489 case RT_MAYBE:
00490 (void) new (home) ReLq<View,CtrlView,rm>(home,x0,x1,b);
00491 break;
00492 default: GECODE_NEVER;
00493 }
00494 } else if (rm != RM_IMP) {
00495 GECODE_ME_CHECK(b.one_none(home));
00496 }
00497 return ES_OK;
00498 }
00499
00500 template<class View, class CtrlView, ReifyMode rm>
00501 forceinline
00502 ReLq<View,CtrlView,rm>::ReLq(Space& home, bool share, ReLq& p)
00503 : ReBinaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p) {}
00504
00505 template<class View, class CtrlView, ReifyMode rm>
00506 Actor*
00507 ReLq<View,CtrlView,rm>::copy(Space& home, bool share) {
00508 return new (home) ReLq<View,CtrlView,rm>(home,share,*this);
00509 }
00510
00511 template<class View, class CtrlView, ReifyMode rm>
00512 ExecStatus
00513 ReLq<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00514 if (b.one()) {
00515 if (rm != RM_PMI)
00516 GECODE_REWRITE(*this,(Lq<View,View>::post(home(*this),x0,x1)));
00517 } else if (b.zero()) {
00518 if (rm != RM_IMP)
00519 GECODE_REWRITE(*this,(Le<View,View>::post(home(*this),x1,x0)));
00520 } else {
00521 switch (rtest_lq(x0,x1)) {
00522 case RT_TRUE:
00523 if (rm != RM_IMP)
00524 GECODE_ME_CHECK(b.one_none(home));
00525 break;
00526 case RT_FALSE:
00527 if (rm != RM_PMI)
00528 GECODE_ME_CHECK(b.zero_none(home));
00529 break;
00530 case RT_MAYBE:
00531 return ES_FIX;
00532 default: GECODE_NEVER;
00533 }
00534 }
00535 return home.ES_SUBSUMED(*this);
00536 }
00537
00538
00539
00540
00541
00542
00543 template<class View, class CtrlView, ReifyMode rm>
00544 forceinline
00545 ReLqInt<View,CtrlView,rm>::ReLqInt(Home home, View x, int c0, CtrlView b)
00546 : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,x,b), c(c0) {}
00547
00548 template<class View, class CtrlView, ReifyMode rm>
00549 ExecStatus
00550 ReLqInt<View,CtrlView,rm>::post(Home home, View x, int c, CtrlView b) {
00551 if (b.one()) {
00552 if (rm != RM_PMI)
00553 GECODE_ME_CHECK(x.lq(home,c));
00554 } else if (b.zero()) {
00555 if (rm != RM_IMP)
00556 GECODE_ME_CHECK(x.gr(home,c));
00557 } else {
00558 switch (rtest_lq(x,c)) {
00559 case RT_TRUE:
00560 if (rm != RM_IMP)
00561 GECODE_ME_CHECK(b.one_none(home));
00562 break;
00563 case RT_FALSE:
00564 if (rm != RM_PMI)
00565 GECODE_ME_CHECK(b.zero_none(home));
00566 break;
00567 case RT_MAYBE:
00568 (void) new (home) ReLqInt<View,CtrlView,rm>(home,x,c,b);
00569 break;
00570 default: GECODE_NEVER;
00571 }
00572 }
00573 return ES_OK;
00574 }
00575
00576
00577 template<class View, class CtrlView, ReifyMode rm>
00578 forceinline
00579 ReLqInt<View,CtrlView,rm>::ReLqInt(Space& home, bool share, ReLqInt& p)
00580 : ReUnaryPropagator<View,PC_INT_BND,CtrlView>(home,share,p), c(p.c) {}
00581
00582 template<class View, class CtrlView, ReifyMode rm>
00583 Actor*
00584 ReLqInt<View,CtrlView,rm>::copy(Space& home, bool share) {
00585 return new (home) ReLqInt<View,CtrlView,rm>(home,share,*this);
00586 }
00587
00588 template<class View, class CtrlView, ReifyMode rm>
00589 ExecStatus
00590 ReLqInt<View,CtrlView,rm>::propagate(Space& home, const ModEventDelta&) {
00591 if (b.one()) {
00592 if (rm != RM_PMI)
00593 GECODE_ME_CHECK(x0.lq(home,c));
00594 } else if (b.zero()) {
00595 if (rm != RM_IMP)
00596 GECODE_ME_CHECK(x0.gr(home,c));
00597 } else {
00598 switch (rtest_lq(x0,c)) {
00599 case RT_TRUE:
00600 if (rm != RM_IMP)
00601 GECODE_ME_CHECK(b.one_none(home));
00602 break;
00603 case RT_FALSE:
00604 if (rm != RM_PMI)
00605 GECODE_ME_CHECK(b.zero_none(home));
00606 break;
00607 case RT_MAYBE:
00608 return ES_FIX;
00609 default: GECODE_NEVER;
00610 }
00611 }
00612 return home.ES_SUBSUMED(*this);
00613 }
00614
00615 }}}
00616
00617
00618