00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 namespace Gecode { namespace Int { namespace Count {
00023
00024
00025
00026
00027
00028
00029 template <class VX, class VY>
00030 forceinline
00031 BaseInt<VX,VY>::BaseInt(Space* home,
00032 ViewArray<VX>& x0, int n_s0, VY y0, int c0)
00033 : Propagator(home), x(x0), n_s(n_s0), y(y0), c(c0) {
00034 for (int i=n_s; i--; )
00035 x[i].subscribe(home,this,PC_INT_DOM);
00036 y.subscribe(home,this,PC_INT_DOM);
00037 }
00038
00039 template <class VX, class VY>
00040 size_t
00041 BaseInt<VX,VY>::dispose(Space* home) {
00042 assert(!home->failed());
00043 for (int i=n_s; i--; )
00044 x[i].cancel(home,this,PC_INT_DOM);
00045 y.cancel(home,this,PC_INT_DOM);
00046 (void) Propagator::dispose(home);
00047 return sizeof(*this);
00048 }
00049
00050 template <class VX, class VY>
00051 forceinline
00052 BaseInt<VX,VY>::BaseInt(Space* home, bool share, BaseInt<VX,VY>& p)
00053 : Propagator(home,share,p), n_s(p.n_s), c(p.c) {
00054 x.update(home,share,p.x);
00055 y.update(home,share,p.y);
00056 }
00057
00058 template <class VX, class VY>
00059 PropCost
00060 BaseInt<VX,VY>::cost(void) const {
00061 return cost_lo(x.size(),PC_LINEAR_LO);
00062 }
00063
00064
00065
00066
00067
00068 template <class VX, class VY>
00069 forceinline
00070 EqInt<VX,VY>::EqInt(Space* home, ViewArray<VX>& x, int n_s, VY y, int c)
00071 : BaseInt<VX,VY>(home,x,n_s,y,c) {}
00072
00073 template <class VX, class VY>
00074 ExecStatus
00075 EqInt<VX,VY>::post(Space* home, ViewArray<VX>& x, VY y, int c) {
00076
00077 int n_x = x.size();
00078 for (int i=n_x; i--; )
00079 switch (holds(x[i],y)) {
00080 case RT_FALSE:
00081 x[i] = x[--n_x]; break;
00082 case RT_TRUE:
00083 x[i] = x[--n_x]; c--; break;
00084 case RT_MAYBE:
00085 break;
00086 default:
00087 GECODE_NEVER;
00088 }
00089 x.size(n_x);
00090
00091 if ((c < 0) || (c > n_x))
00092 return ES_FAILED;
00093
00094 if (c == 0) {
00095 ExecStatus es = post_false(home,x,y);
00096 return (es == ES_SUBSUMED) ? ES_OK : es;
00097 }
00098
00099 if (c == n_x) {
00100 ExecStatus es = post_true(home,x,y);
00101 return (es == ES_SUBSUMED) ? ES_OK : es;
00102 }
00103
00104 int n_s = std::max(c,n_x-c)+1;
00105 assert(n_s <= n_x);
00106 (void) new (home) EqInt<VX,VY>(home,x,n_s,y,c);
00107 return ES_OK;
00108 }
00109
00110 template <class VX, class VY>
00111 forceinline
00112 EqInt<VX,VY>::EqInt(Space* home, bool share, EqInt<VX,VY>& p)
00113 : BaseInt<VX,VY>(home,share,p) {}
00114
00115 template <class VX, class VY>
00116 Actor*
00117 EqInt<VX,VY>::copy(Space* home, bool share) {
00118 return new (home) EqInt<VX,VY>(home,share,*this);
00119 }
00120
00121 template <class VX, class VY>
00122 ExecStatus
00123 EqInt<VX,VY>::propagate(Space* home) {
00124
00125 int n_x = x.size();
00126 for (int i=n_s; i--; )
00127 switch (holds(x[i],y)) {
00128 case RT_FALSE:
00129 x[i].cancel(home,this,PC_INT_DOM);
00130 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00131 break;
00132 case RT_TRUE:
00133 x[i].cancel(home,this,PC_INT_DOM);
00134 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00135 break;
00136 case RT_MAYBE:
00137 break;
00138 default:
00139 GECODE_NEVER;
00140 }
00141 x.size(n_x);
00142 if ((c < 0) || (c > n_x))
00143 return ES_FAILED;
00144
00145 for (int i=n_x; i-- > n_s; )
00146 switch (holds(x[i],y)) {
00147 case RT_FALSE: x[i]=x[--n_x]; break;
00148 case RT_TRUE: x[i]=x[--n_x]; c--; break;
00149 case RT_MAYBE: break;
00150 default: GECODE_NEVER;
00151 }
00152 x.size(n_x);
00153 if ((c < 0) || (c > n_x))
00154 return ES_FAILED;
00155 if (c == 0)
00156
00157 return post_false(home,x,y);
00158 if (c == n_x)
00159
00160 return post_true(home,x,y);
00161 int m = std::max(c,n_x-c)+1;
00162 assert(m <= n_x);
00163
00164 while (n_s < m)
00165 x[n_s++].subscribe(home,this,PC_INT_DOM,false);
00166 return ES_FIX;
00167 }
00168
00169
00170
00171
00172
00173 template <class VX, class VY>
00174 forceinline
00175 GqInt<VX,VY>::GqInt(Space* home, ViewArray<VX>& x, int n_s, VY y, int c)
00176 : BaseInt<VX,VY>(home,x,n_s,y,c) {}
00177
00178 template <class VX, class VY>
00179 ExecStatus
00180 GqInt<VX,VY>::post(Space* home, ViewArray<VX>& x, VY y, int c) {
00181
00182 int n_x = x.size();
00183 for (int i=n_x; i--; )
00184 switch (holds(x[i],y)) {
00185 case RT_FALSE:
00186 x[i] = x[--n_x]; break;
00187 case RT_TRUE:
00188 x[i] = x[--n_x]; c--; break;
00189 case RT_MAYBE:
00190 break;
00191 default:
00192 GECODE_NEVER;
00193 }
00194 x.size(n_x);
00195
00196 if (n_x < c)
00197 return ES_FAILED;
00198
00199 if (c <= 0)
00200 return ES_OK;
00201
00202 if (c == n_x) {
00203 ExecStatus es = post_true(home,x,y);
00204 return (es == ES_SUBSUMED) ? ES_OK : es;
00205 }
00206 (void) new (home) GqInt<VX,VY>(home,x,c+1,y,c);
00207 return ES_OK;
00208 }
00209
00210 template <class VX, class VY>
00211 forceinline
00212 GqInt<VX,VY>::GqInt(Space* home, bool share, GqInt<VX,VY>& p)
00213 : BaseInt<VX,VY>(home,share,p) {}
00214
00215 template <class VX, class VY>
00216 Actor*
00217 GqInt<VX,VY>::copy(Space* home, bool share) {
00218 return new (home) GqInt<VX,VY>(home,share,*this);
00219 }
00220
00221 template <class VX, class VY>
00222 ExecStatus
00223 GqInt<VX,VY>::propagate(Space* home) {
00224
00225 int n_x = x.size();
00226 for (int i=n_s; i--; )
00227 switch (holds(x[i],y)) {
00228 case RT_FALSE:
00229 x[i].cancel(home,this,PC_INT_DOM);
00230 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00231 break;
00232 case RT_TRUE:
00233 x[i].cancel(home,this,PC_INT_DOM);
00234 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00235 break;
00236 case RT_MAYBE:
00237 break;
00238 default:
00239 GECODE_NEVER;
00240 }
00241 x.size(n_x);
00242 if (n_x < c)
00243 return ES_FAILED;
00244 if (c <= 0)
00245 return ES_SUBSUMED;
00246
00247 for (int i=n_x; i-- > n_s; )
00248 switch (holds(x[i],y)) {
00249 case RT_FALSE: x[i]=x[--n_x]; break;
00250 case RT_TRUE: x[i]=x[--n_x]; c--; break;
00251 case RT_MAYBE: break;
00252 default: GECODE_NEVER;
00253 }
00254 x.size(n_x);
00255 if (n_x < c)
00256 return ES_FAILED;
00257 if (c <= 0)
00258 return ES_SUBSUMED;
00259 if (c == n_x)
00260
00261 return post_true(home,x,y);
00262
00263 while (n_s <= c)
00264 x[n_s++].subscribe(home,this,PC_INT_DOM,false);
00265 return ES_FIX;
00266 }
00267
00268
00269
00270
00271
00272 template <class VX, class VY>
00273 forceinline
00274 LqInt<VX,VY>::LqInt(Space* home, ViewArray<VX>& x, int n_s, VY y, int c)
00275 : BaseInt<VX,VY>(home,x,n_s,y,c) {}
00276
00277 template <class VX, class VY>
00278 ExecStatus
00279 LqInt<VX,VY>::post(Space* home, ViewArray<VX>& x, VY y, int c) {
00280
00281 int n_x = x.size();
00282 for (int i=n_x; i--; )
00283 switch (holds(x[i],y)) {
00284 case RT_FALSE:
00285 x[i] = x[--n_x]; break;
00286 case RT_TRUE:
00287 x[i] = x[--n_x]; c--; break;
00288 case RT_MAYBE:
00289 break;
00290 default:
00291 GECODE_NEVER;
00292 }
00293 x.size(n_x);
00294 if (c < 0)
00295 return ES_FAILED;
00296 if (c >= n_x)
00297 return ES_OK;
00298
00299 if (c == 0) {
00300 ExecStatus es = post_false(home,x,y);
00301 return (es == ES_SUBSUMED) ? ES_OK : es;
00302 }
00303 (void) new (home) LqInt<VX,VY>(home,x,n_x-c+1,y,c);
00304 return ES_OK;
00305 }
00306
00307 template <class VX, class VY>
00308 forceinline
00309 LqInt<VX,VY>::LqInt(Space* home, bool share, LqInt<VX,VY>& p)
00310 : BaseInt<VX,VY>(home,share,p) {}
00311
00312 template <class VX, class VY>
00313 Actor*
00314 LqInt<VX,VY>::copy(Space* home, bool share) {
00315 return new (home) LqInt<VX,VY>(home,share,*this);
00316 }
00317
00318 template <class VX, class VY>
00319 ExecStatus
00320 LqInt<VX,VY>::propagate(Space* home) {
00321
00322 int n_x = x.size();
00323 for (int i=n_s; i--; )
00324 switch (holds(x[i],y)) {
00325 case RT_FALSE:
00326 x[i].cancel(home,this,PC_INT_DOM);
00327 x[i]=x[--n_s]; x[n_s]=x[--n_x];
00328 break;
00329 case RT_TRUE:
00330 x[i].cancel(home,this,PC_INT_DOM);
00331 x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--;
00332 break;
00333 case RT_MAYBE:
00334 break;
00335 default:
00336 GECODE_NEVER;
00337 }
00338 x.size(n_x);
00339 if (c < 0)
00340 return ES_FAILED;
00341 if (c >= n_x)
00342 return ES_SUBSUMED;
00343
00344 for (int i=n_x; i-- > n_s; )
00345 switch (holds(x[i],y)) {
00346 case RT_FALSE: x[i]=x[--n_x]; break;
00347 case RT_TRUE: x[i]=x[--n_x]; c--; break;
00348 case RT_MAYBE: break;
00349 default: GECODE_NEVER;
00350 }
00351 x.size(n_x);
00352 if (c < 0)
00353 return ES_FAILED;
00354 if (c >= n_x)
00355 return ES_SUBSUMED;
00356 if (c == 0)
00357
00358 return post_false(home,x,y);
00359
00360 int m = n_x-c;
00361 while (n_s <= m)
00362 x[n_s++].subscribe(home,this,PC_INT_DOM,false);
00363 return ES_FIX;
00364 }
00365
00366
00367
00368
00369
00370 template<class VX, class VY>
00371 forceinline
00372 NqInt<VX,VY>::NqInt(Space* home, ViewArray<VX>& x0, VY y0, int c0)
00373 : BinaryPropagator<VX,PC_INT_DOM>(home,
00374 x0[x0.size()-2],
00375 x0[x0.size()-1]), x(x0), y(y0), c(c0) {
00376 assert(x.size() >= 2);
00377 x.size(x.size()-2);
00378 y.subscribe(home,this,PC_INT_DOM);
00379 }
00380
00381 template <class VX, class VY>
00382 size_t
00383 NqInt<VX,VY>::dispose(Space* home) {
00384 assert(!home->failed());
00385 y.cancel(home,this,PC_INT_DOM);
00386 (void) BinaryPropagator<VX,PC_INT_DOM>::dispose(home);
00387 return sizeof(*this);
00388 }
00389
00390 template<class VX, class VY>
00391 forceinline
00392 NqInt<VX,VY>::NqInt(Space* home, bool share, NqInt<VX,VY>& p)
00393 : BinaryPropagator<VX,PC_INT_DOM>(home,share,p), c(p.c) {
00394 x.update(home,share,p.x);
00395 y.update(home,share,p.y);
00396 }
00397
00398 template<class VX, class VY>
00399 forceinline ExecStatus
00400 NqInt<VX,VY>::post(Space* home, ViewArray<VX>& x, VY y, int c) {
00401 int n = x.size();
00402 for (int i=n; i--; )
00403 switch (holds(x[i],y)) {
00404 case RT_FALSE: x[i]=x[--n]; break;
00405 case RT_TRUE: x[i]=x[--n]; c--; break;
00406 case RT_MAYBE: break;
00407 default: GECODE_NEVER;
00408 }
00409 x.size(n);
00410 if ((n < c) || (c < 0))
00411 return ES_OK;
00412 if (n == 0)
00413 return (c == 0) ? ES_FAILED : ES_OK;
00414 if (n == 1) {
00415 ExecStatus es = (c == 1) ?
00416 post_false(home,x[0],y) : post_true(home,x[0],y);
00417 return (es == ES_SUBSUMED) ? ES_OK : es;
00418 }
00419 (void) new (home) NqInt(home,x,y,c);
00420 return ES_OK;
00421 }
00422
00423 template<class VX, class VY>
00424 Actor*
00425 NqInt<VX,VY>::copy(Space* home, bool share) {
00426 return new (home) NqInt<VX,VY>(home,share,*this);
00427 }
00428
00429 template<class VX, class VY>
00430 PropCost
00431 NqInt<VX,VY>::cost(void) const {
00432 return PC_LINEAR_LO;
00433 }
00434
00435 template<class VX, class VY>
00436 forceinline bool
00437 NqInt<VX,VY>::resubscribe(Space* home, VX& z) {
00438 switch (holds(z,y)) {
00439 case RT_FALSE: break;
00440 case RT_TRUE: c--; break;
00441 case RT_MAYBE: return true;
00442 default: GECODE_NEVER;
00443 }
00444 int n = x.size();
00445 for (int i=n; i--; )
00446 switch (holds(x[i],y)) {
00447 case RT_FALSE:
00448 x[i]=x[--n];
00449 break;
00450 case RT_TRUE:
00451 x[i]=x[--n]; c--;
00452 break;
00453 case RT_MAYBE:
00454
00455 z.cancel(home,this,PC_INT_DOM);
00456 z=x[i]; x[i]=x[--n];
00457 x.size(n);
00458 z.subscribe(home,this,PC_INT_DOM,false);
00459 return true;
00460 default:
00461 GECODE_NEVER;
00462 }
00463
00464 x.size(0);
00465 return false;
00466 }
00467
00468 template<class VX, class VY>
00469 ExecStatus
00470 NqInt<VX,VY>::propagate(Space* home) {
00471 bool s0 = resubscribe(home,x0);
00472 bool s1 = resubscribe(home,x1);
00473 int n = x.size() + s0 + s1;
00474 if ((n < c) || (c < 0))
00475 return ES_SUBSUMED;
00476 if (n == 0)
00477 return (c == 0) ? ES_FAILED : ES_SUBSUMED;
00478 if (n == 1) {
00479 if (s0) {
00480 return (c == 1) ?
00481 post_false(home,x0,y) : post_true(home,x0,y);
00482 } else {
00483 assert(s1);
00484 return (c == 1) ?
00485 post_false(home,x1,y) : post_true(home,x1,y);
00486 }
00487 return ES_SUBSUMED;
00488 }
00489 return ES_FIX;
00490 }
00491
00492 }}}
00493
00494
00495