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 namespace Gecode { namespace Int { namespace Rel {
00039
00040
00041
00042
00043 template<class VX, class VY>
00044 inline
00045 LexLqLe<VX,VY>::LexLqLe(Home home,
00046 ViewArray<VX>& x0, ViewArray<VY>& y0, bool s)
00047 : Propagator(home), x(x0), y(y0), strict(s) {
00048 x.subscribe(home, *this, PC_INT_BND);
00049 y.subscribe(home, *this, PC_INT_BND);
00050 }
00051
00052 template<class VX, class VY>
00053 forceinline
00054 LexLqLe<VX,VY>::LexLqLe(Space& home, bool share, LexLqLe<VX,VY>& p)
00055 : Propagator(home,share,p), strict(p.strict) {
00056 x.update(home,share,p.x);
00057 y.update(home,share,p.y);
00058 }
00059
00060 template<class VX, class VY>
00061 Actor*
00062 LexLqLe<VX,VY>::copy(Space& home, bool share) {
00063 return new (home) LexLqLe<VX,VY>(home,share,*this);
00064 }
00065
00066 template<class VX, class VY>
00067 PropCost
00068 LexLqLe<VX,VY>::cost(const Space&, const ModEventDelta&) const {
00069 return PropCost::linear(PropCost::LO, x.size());
00070 }
00071
00072 template<class VX, class VY>
00073 void
00074 LexLqLe<VX,VY>::reschedule(Space& home) {
00075 x.reschedule(home,*this,PC_INT_BND);
00076 y.reschedule(home,*this,PC_INT_BND);
00077 }
00078
00079 template<class VX, class VY>
00080 forceinline size_t
00081 LexLqLe<VX,VY>::dispose(Space& home) {
00082 assert(!home.failed());
00083 x.cancel(home,*this,PC_INT_BND);
00084 y.cancel(home,*this,PC_INT_BND);
00085 (void) Propagator::dispose(home);
00086 return sizeof(*this);
00087 }
00088
00089 template<class VX, class VY>
00090 ExecStatus
00091 LexLqLe<VX,VY>::propagate(Space& home, const ModEventDelta&) {
00092
00093
00094
00095
00096 {
00097 int i = 0;
00098 int n = x.size();
00099
00100 while ((i < n) && (x[i].min() == y[i].max())) {
00101
00102 GECODE_ME_CHECK(x[i].lq(home,y[i].max()));
00103 GECODE_ME_CHECK(y[i].gq(home,x[i].min()));
00104 i++;
00105 }
00106
00107 if (i == n)
00108 return strict ? ES_FAILED : home.ES_SUBSUMED(*this);
00109
00110
00111 GECODE_ME_CHECK(x[i].lq(home,y[i].max()));
00112 GECODE_ME_CHECK(y[i].gq(home,x[i].min()));
00113
00114 if (x[i].max() < y[i].min())
00115 return home.ES_SUBSUMED(*this);
00116
00117
00118 assert(!(x[i].assigned() && y[i].assigned() &&
00119 x[i].val() == y[i].val()));
00120
00121 x.drop_fst(i); y.drop_fst(i);
00122
00123 }
00124
00125
00126
00127
00128
00129
00130 {
00131 int i = 1;
00132 int n = x.size();
00133
00134 while ((i < n) &&
00135 (x[i].min() == y[i].max()) &&
00136 (x[i].max() == y[i].min())) {
00137 assert(x[i].assigned() && y[i].assigned() &&
00138 (x[i].val() == y[i].val()));
00139 i++;
00140 }
00141
00142 if (i == n) {
00143 if (strict)
00144 goto rewrite_le;
00145 else
00146 goto rewrite_lq;
00147 }
00148
00149 if (x[i].max() < y[i].min())
00150 goto rewrite_lq;
00151
00152 if (x[i].min() > y[i].max())
00153 goto rewrite_le;
00154
00155 if (i > 1) {
00156
00157 x[i-1]=x[0]; x.drop_fst(i-1);
00158 y[i-1]=y[0]; y.drop_fst(i-1);
00159 }
00160 }
00161
00162 if (x[1].max() <= y[1].min()) {
00163
00164
00165
00166
00167
00168
00169 int i = 2;
00170 int n = x.size();
00171
00172 while ((i < n) && (x[i].max() == y[i].min()))
00173 i++;
00174
00175 if (i == n) {
00176 if (strict)
00177 return ES_FIX;
00178 else
00179 goto rewrite_lq;
00180 }
00181
00182 if (x[i].max() < y[i].min())
00183 goto rewrite_lq;
00184
00185 if (x[i].min() > y[i].max()) {
00186
00187 for (int j=i; j<n; j++) {
00188 x[j].cancel(home,*this,PC_INT_BND);
00189 y[j].cancel(home,*this,PC_INT_BND);
00190 }
00191 x.size(i); y.size(i);
00192 strict = true;
00193 }
00194
00195 return ES_FIX;
00196 }
00197
00198 if (x[1].min() >= y[1].max()) {
00199
00200
00201
00202
00203
00204
00205 int i = 2;
00206 int n = x.size();
00207
00208 while ((i < n) && (x[i].min() == y[i].max()))
00209
00210 i++;
00211
00212 if (i == n) {
00213 if (strict)
00214 goto rewrite_le;
00215 else
00216 return ES_FIX;
00217 }
00218
00219 if (x[i].min() > y[i].max())
00220 goto rewrite_le;
00221
00222 if (x[i].max() < y[i].min()) {
00223
00224 for (int j=i; j<n; j++) {
00225 x[j].cancel(home,*this,PC_INT_BND);
00226 y[j].cancel(home,*this,PC_INT_BND);
00227 }
00228 x.size(i); y.size(i);
00229 strict = false;
00230 }
00231
00232 return ES_FIX;
00233 }
00234
00235 return ES_FIX;
00236
00237 rewrite_le:
00238 GECODE_REWRITE(*this,(Le<VX,VY>::post(home(*this),x[0],y[0])));
00239 rewrite_lq:
00240 GECODE_REWRITE(*this,(Lq<VX,VY>::post(home(*this),x[0],y[0])));
00241 }
00242
00243 template<class VX, class VY>
00244 ExecStatus
00245 LexLqLe<VX,VY>::post(Home home,
00246 ViewArray<VX>& x, ViewArray<VY>& y, bool strict) {
00247 if (x.size() < y.size()) {
00248 y.size(x.size()); strict=false;
00249 } else if (x.size() > y.size()) {
00250 x.size(y.size()); strict=true;
00251 }
00252 if (x.size() == 0)
00253 return strict ? ES_FAILED : ES_OK;
00254 if (x.size() == 1) {
00255 if (strict)
00256 return Le<VX,VY>::post(home,x[0],y[0]);
00257 else
00258 return Lq<VX,VY>::post(home,x[0],y[0]);
00259 }
00260 (void) new (home) LexLqLe<VX,VY>(home,x,y,strict);
00261 return ES_OK;
00262 }
00263
00264
00265
00266
00267
00268 template<class VX, class VY>
00269 forceinline
00270 LexNq<VX,VY>::LexNq(Home home, ViewArray<VX>& xv, ViewArray<VY>& yv)
00271 : Propagator(home),
00272 x0(xv[xv.size()-2]), y0(yv[xv.size()-2]),
00273 x1(xv[xv.size()-1]), y1(yv[xv.size()-1]),
00274 x(xv), y(yv) {
00275 int n = x.size();
00276 assert(n > 1);
00277 assert(n == y.size());
00278 x.size(n-2); y.size(n-2);
00279 x0.subscribe(home,*this,PC_INT_VAL); y0.subscribe(home,*this,PC_INT_VAL);
00280 x1.subscribe(home,*this,PC_INT_VAL); y1.subscribe(home,*this,PC_INT_VAL);
00281 }
00282
00283 template<class VX, class VY>
00284 PropCost
00285 LexNq<VX,VY>::cost(const Space&, const ModEventDelta&) const {
00286 return PropCost::binary(PropCost::HI);
00287 }
00288
00289 template<class VX, class VY>
00290 void
00291 LexNq<VX,VY>::reschedule(Space& home) {
00292 x0.reschedule(home,*this,PC_INT_VAL);
00293 y0.reschedule(home,*this,PC_INT_VAL);
00294 x1.reschedule(home,*this,PC_INT_VAL);
00295 y1.reschedule(home,*this,PC_INT_VAL);
00296 }
00297
00298 template<class VX, class VY>
00299 forceinline
00300 LexNq<VX,VY>::LexNq(Space& home, bool share, LexNq<VX,VY>& p)
00301 : Propagator(home,share,p) {
00302 x0.update(home,share,p.x0); y0.update(home,share,p.y0);
00303 x1.update(home,share,p.x1); y1.update(home,share,p.y1);
00304 x.update(home,share,p.x); y.update(home,share,p.y);
00305 }
00306
00307 template<class VX, class VY>
00308 Actor*
00309 LexNq<VX,VY>::copy(Space& home, bool share) {
00310 int n = x.size();
00311 if (n > 0) {
00312
00313 for (int i=n; i--; )
00314 switch (rtest_eq_bnd(x[i],y[i])) {
00315 case RT_TRUE:
00316
00317 n--; x[i]=x[n]; y[i]=y[n];
00318 break;
00319 case RT_FALSE:
00320
00321 n=1; x[0]=x[i]; y[0]=y[i];
00322 goto done;
00323 case RT_MAYBE:
00324 break;
00325 default:
00326 GECODE_NEVER;
00327 }
00328 done:
00329 x.size(n); y.size(n);
00330 }
00331 return new (home) LexNq<VX,VY>(home,share,*this);
00332 }
00333
00334 template<class VX, class VY>
00335 inline ExecStatus
00336 LexNq<VX,VY>::post(Home home, ViewArray<VX>& x, ViewArray<VY>& y) {
00337 if (x.size() != y.size())
00338 return ES_OK;
00339 int n = x.size();
00340 if (n > 0) {
00341
00342 for (int i=n; i--; )
00343 switch (rtest_eq_dom(x[i],y[i])) {
00344 case RT_TRUE:
00345
00346 n--; x[i]=x[n]; y[i]=y[n];
00347 break;
00348 case RT_FALSE:
00349 return ES_OK;
00350 case RT_MAYBE:
00351 if (same(x[i],y[i])) {
00352
00353 n--; x[i]=x[n]; y[i]=y[n];
00354 }
00355 break;
00356 default:
00357 GECODE_NEVER;
00358 }
00359 x.size(n); y.size(n);
00360 }
00361 if (n == 0)
00362 return ES_FAILED;
00363 if (n == 1)
00364 return Nq<VX,VY>::post(home,x[0],y[0]);
00365 (void) new (home) LexNq<VX,VY>(home,x,y);
00366 return ES_OK;
00367 }
00368
00369 template<class VX, class VY>
00370 forceinline size_t
00371 LexNq<VX,VY>::dispose(Space& home) {
00372 x0.cancel(home,*this,PC_INT_VAL); y0.cancel(home,*this,PC_INT_VAL);
00373 x1.cancel(home,*this,PC_INT_VAL); y1.cancel(home,*this,PC_INT_VAL);
00374 (void) Propagator::dispose(home);
00375 return sizeof(*this);
00376 }
00377
00378 template<class VX, class VY>
00379 forceinline ExecStatus
00380 LexNq<VX,VY>::resubscribe(Space& home,
00381 RelTest rt, VX& x0, VY& y0, VX x1, VY y1) {
00382 if (rt == RT_TRUE) {
00383 assert(x0.assigned() && y0.assigned());
00384 assert(x0.val() == y0.val());
00385 int n = x.size();
00386 for (int i=n; i--; )
00387 switch (rtest_eq_dom(x[i],y[i])) {
00388 case RT_TRUE:
00389
00390 n--; x[i]=x[n]; y[i]=y[n];
00391 break;
00392 case RT_FALSE:
00393 return home.ES_SUBSUMED(*this);
00394 case RT_MAYBE:
00395
00396 x0=x[i]; y0=y[i];
00397 n--; x[i]=x[n]; y[i]=y[n];
00398 x.size(n); y.size(n);
00399 x0.subscribe(home,*this,PC_INT_VAL,false);
00400 y0.subscribe(home,*this,PC_INT_VAL,false);
00401 return ES_FIX;
00402 default:
00403 GECODE_NEVER;
00404 }
00405
00406 GECODE_REWRITE(*this,(Nq<VX,VY>::post(home(*this),x1,y1)));
00407 }
00408 return ES_FIX;
00409 }
00410
00411 template<class VX, class VY>
00412 ExecStatus
00413 LexNq<VX,VY>::propagate(Space& home, const ModEventDelta&) {
00414 RelTest rt0 = rtest_eq_dom(x0,y0);
00415 if (rt0 == RT_FALSE)
00416 return home.ES_SUBSUMED(*this);
00417 RelTest rt1 = rtest_eq_dom(x1,y1);
00418 if (rt1 == RT_FALSE)
00419 return home.ES_SUBSUMED(*this);
00420 GECODE_ES_CHECK(resubscribe(home,rt0,x0,y0,x1,y1));
00421 GECODE_ES_CHECK(resubscribe(home,rt1,x1,y1,x0,y0));
00422 return ES_FIX;
00423 }
00424
00425
00426 }}}
00427
00428