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 namespace Gecode {
00029
00030 template <class View0, class View1>
00031 forceinline bool
00032 viewarrayshared(const ViewArray<View0>& va,
00033 const View1& y) {
00034 return va.shared(y);
00035 }
00036
00037 template <>
00038 forceinline bool
00039 viewarrayshared<Set::SingletonView,Set::SetView>
00040 (const ViewArray<Set::SingletonView>& va, const Set::SetView& y) {
00041 return false;
00042 }
00043
00044 template <>
00045 forceinline bool
00046 viewarrayshared<Set::ComplementView<Set::SingletonView>,Set::SetView>
00047 (const ViewArray<Set::ComplementView<Set::SingletonView> >& va,
00048 const Set::SetView& y) {
00049 return false;
00050 }
00051
00052 template <>
00053 forceinline bool
00054 viewarrayshared<Set::ComplementView<Set::SingletonView>,
00055 Set::ComplementView<Set::SetView> >
00056 (const ViewArray<Set::ComplementView<Set::SingletonView> >& va,
00057 const Set::ComplementView<Set::SetView>& y) {
00058 return false;
00059 }
00060
00061
00062 namespace Set { namespace RelOp {
00063
00064
00065
00066
00067
00068 template <class View0, class View1, class View2>
00069 forceinline bool
00070 shared(View0 v0, View1 v1, View2 v2) {
00071 return shared(v0,v1) || shared(v0,v2) || shared(v1,v2);
00072 }
00073
00074 template <class View0, class View1, class View2>
00075 ExecStatus unionCard(Space* home,
00076 bool& retmodified, View0& x0, View1& x1, View2& x2) {
00077 bool modified = false;
00078 do {
00079 retmodified |= modified;
00080 modified = false;
00081
00082 {
00083 LubRanges<View0> x0ub(x0);
00084 LubRanges<View1> x1ub(x1);
00085 Iter::Ranges::Inter<LubRanges<View0>, LubRanges<View1> > i1(x0ub,x1ub);
00086 unsigned int s1 = Iter::Ranges::size(i1);
00087 unsigned int res = std::max(x0.cardMin()+
00088 (x1.cardMin()<s1 ?
00089 0 : x1.cardMin()-s1),
00090 std::max(x0.cardMin(),
00091 x1.cardMin()));
00092 GECODE_ME_CHECK_MODIFIED(modified, x2.cardMin(home,res));
00093 }
00094
00095 {
00096 LubRanges<View0> x0ub(x0);
00097 LubRanges<View1> x1ub(x1);
00098 Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u1(x0ub,x1ub);
00099 unsigned int s1 = Iter::Ranges::size(u1);
00100 GECODE_ME_CHECK_MODIFIED(modified,
00101 x2.cardMax(home,
00102 std::min(x0.cardMax()+x1.cardMax(),s1)));
00103 }
00104
00105 if (x2.cardMin() > x1.cardMax())
00106 GECODE_ME_CHECK_MODIFIED(modified,
00107 x0.cardMin(home,x2.cardMin() - x1.cardMax()));
00108
00109 if (x2.cardMin() > x0.cardMax())
00110 GECODE_ME_CHECK_MODIFIED(modified,
00111 x1.cardMin(home,x2.cardMin() - x0.cardMax()));
00112
00113 GECODE_ME_CHECK_MODIFIED(modified,
00114 x0.cardMax(home,x2.cardMax()));
00115 GECODE_ME_CHECK_MODIFIED(modified,
00116 x1.cardMax(home,x2.cardMax()));
00117 } while(modified);
00118 return ES_FIX;
00119 }
00120
00121 template <class View0, class View1>
00122 ExecStatus
00123 unionNCard(Space* home, bool& modified, ViewArray<View0>& x,
00124 View1& y, GLBndSet& unionOfDets) {
00125 int xsize = x.size();
00126
00127
00128 unsigned int cardMaxSum=unionOfDets.size();
00129 bool maxValid = true;
00130 for (int i=xsize; i--; ){
00131 cardMaxSum+=x[i].cardMax();
00132 if (cardMaxSum < x[i].cardMax()) { maxValid = false; }
00133 GECODE_ME_CHECK_MODIFIED(modified, y.cardMin(home,x[i].cardMin()) );
00134 GECODE_ME_CHECK_MODIFIED(modified, x[i].cardMax(home,y.cardMax()) );
00135 }
00136 if (maxValid) {
00137 GECODE_ME_CHECK_MODIFIED(modified, y.cardMax(home,cardMaxSum));
00138 }
00139
00140
00141
00142 {
00143 GECODE_AUTOARRAY(unsigned int, rightSum, xsize);
00144 rightSum[xsize-1]=0;
00145
00146 for (int i=x.size()-1;i--;) {
00147 rightSum[i] = rightSum[i+1] + x[i+1].cardMax();
00148 if (rightSum[i] < rightSum[i+1]) {
00149
00150 for (int j=i; j>0;j--) {
00151 rightSum[j]=Limits::Set::card_max;
00152 }
00153 break;
00154 }
00155 }
00156
00157
00158 unsigned int leftAcc=unionOfDets.size();
00159
00160 for (int i=0; i<xsize;i++) {
00161 unsigned int jsum = leftAcc+rightSum[i];
00162
00163 if (jsum >= leftAcc && jsum < y.cardMin()) {
00164 GECODE_ME_CHECK_MODIFIED(modified, x[i].cardMin(home,y.cardMin()-jsum));
00165 }
00166 leftAcc += x[i].cardMax();
00167 if (leftAcc < x[i].cardMax()) {leftAcc = Limits::Set::card_max;}
00168 }
00169 }
00170
00171
00172
00173 {
00174 GECODE_AUTOARRAY(GLBndSet, rightUnion, xsize);
00175 rightUnion[xsize-1].init(home);
00176 for (int i=xsize-1;i--;){
00177 BndSetRanges prev(rightUnion[i+1]);
00178 LubRanges<View0> prevX(x[i+1]);
00179 Iter::Ranges::Union< BndSetRanges,LubRanges<View0> >
00180 iter(prev,prevX);
00181 rightUnion[i].init(home);
00182 rightUnion[i].includeI(home, iter);
00183 }
00184
00185
00186 GLBndSet leftAcc;
00187 leftAcc.update(home,unionOfDets);
00188 for (int i=0; i<xsize; i++) {
00189 BndSetRanges left(leftAcc);
00190 BndSetRanges right(rightUnion[i]);
00191 Iter::Ranges::Union<BndSetRanges,
00192 BndSetRanges> iter(left, right);
00193 unsigned int unionSize = Iter::Ranges::size(iter);
00194 if (y.cardMin() > unionSize) {
00195 GECODE_ME_CHECK_MODIFIED(modified,
00196 x[i].cardMin(home, y.cardMin() - unionSize) );
00197 }
00198 LubRanges<View0> xiub(x[i]);
00199 leftAcc.includeI(home, xiub);
00200 }
00201
00202 for (int i=xsize; i--;)
00203 rightUnion[i].dispose(home);
00204 leftAcc.dispose(home);
00205 }
00206
00207
00208
00209 return ES_NOFIX;
00210
00211 }
00212
00213
00214
00215
00216
00217 template <class View0, class View1>
00218 ExecStatus
00219 unionNXiUB(Space* home,
00220 bool& modified, ViewArray<View0>& x, View1& y,
00221 GLBndSet & unionOfDets) {
00222 int xsize = x.size();
00223 for (int i=xsize; i--; ) {
00224 LubRanges<View1> yub(y);
00225 GECODE_ME_CHECK_MODIFIED(modified, x[i].intersectI(home, yub));
00226 }
00227 return ES_FIX;
00228 }
00229
00230
00231 template <class View0, class View1>
00232 ExecStatus
00233 partitionNCard(Space* home,
00234 bool& modified, ViewArray<View0>& x, View1& y,
00235 GLBndSet& unionOfDets) {
00236 unsigned int cardMinSum=unionOfDets.size();
00237 unsigned int cardMaxSum=unionOfDets.size();
00238 int xsize = x.size();
00239 for (int i=xsize; i--; ) {
00240 cardMinSum+=x[i].cardMin();
00241 if (cardMinSum < x[i].cardMin()) {
00242
00243 GECODE_ME_CHECK(ME_SET_FAILED);
00244 }
00245 }
00246 GECODE_ME_CHECK_MODIFIED(modified, y.cardMin(home,cardMinSum));
00247 for (int i=xsize; i--; ) {
00248 cardMaxSum+=x[i].cardMax();
00249 if (cardMaxSum < x[i].cardMax()) {
00250
00251 goto overflow;
00252 }
00253 }
00254 GECODE_ME_CHECK_MODIFIED(modified, y.cardMax(home,cardMaxSum));
00255 overflow:
00256
00257
00258
00259 {
00260 GECODE_AUTOARRAY(unsigned int, rightMinSum, xsize);
00261 GECODE_AUTOARRAY(unsigned int, rightMaxSum, xsize);
00262 rightMinSum[xsize-1]=0;
00263 rightMaxSum[xsize-1]=0;
00264
00265 for (int i=x.size()-1;i--;) {
00266 rightMaxSum[i] = rightMaxSum[i+1] + x[i+1].cardMax();
00267 if (rightMaxSum[i] < rightMaxSum[i+1]) {
00268
00269 for (int j=i; j>0;j--) {
00270 rightMaxSum[j]=Limits::Set::card_max;
00271 }
00272 break;
00273 }
00274
00275 rightMinSum[i] = rightMinSum[i+1] + x[i+1].cardMin();
00276 if (rightMinSum[i] < rightMinSum[i+1]) {
00277
00278 GECODE_ME_CHECK(ME_SET_FAILED);
00279 }
00280
00281
00282 }
00283 unsigned int leftMinAcc=unionOfDets.size();
00284 unsigned int leftMaxAcc=unionOfDets.size();
00285
00286 for (int i=0; i<xsize;i++) {
00287 unsigned int maxSum = leftMaxAcc+rightMaxSum[i];
00288 unsigned int minSum = leftMinAcc+rightMinSum[i];
00289
00290 if (maxSum >= leftMaxAcc && maxSum < y.cardMin()) {
00291 GECODE_ME_CHECK_MODIFIED(modified, x[i].cardMin(home,y.cardMin()-maxSum));
00292 }
00293
00294
00295 if (minSum < leftMinAcc || y.cardMax() < minSum) {
00296 GECODE_ME_CHECK(ME_SET_FAILED);
00297 }
00298 else {
00299 GECODE_ME_CHECK_MODIFIED(modified, x[i].cardMax(home,y.cardMax()-minSum));
00300 }
00301
00302 leftMaxAcc += x[i].cardMax();
00303 if (leftMaxAcc < x[i].cardMax()) {leftMaxAcc = Limits::Set::card_max;}
00304 leftMinAcc += x[i].cardMin();
00305 if (leftMinAcc < x[i].cardMin()) {GECODE_ME_CHECK(ME_SET_FAILED);}
00306 }
00307 }
00308
00309 return ES_NOFIX;
00310 }
00311
00312
00313
00314 template <class View0, class View1>
00315 ExecStatus
00316 partitionNXi(Space* home,
00317 bool& modified, ViewArray<View0>& x, View1& y) {
00318 int xsize = x.size();
00319 GECODE_AUTOARRAY(GLBndSet, afterUB, xsize);
00320 GECODE_AUTOARRAY(GLBndSet, afterLB, xsize);
00321
00322 {
00323 GLBndSet sofarAfterUB;
00324 GLBndSet sofarAfterLB;
00325 for (int i=xsize; i--;) {
00326 afterUB[i].init(home);
00327 afterLB[i].init(home);
00328 afterUB[i].update(home,sofarAfterUB);
00329 afterLB[i].update(home,sofarAfterLB);
00330 LubRanges<View0> xiub(x[i]);
00331 GlbRanges<View0> xilb(x[i]);
00332 sofarAfterUB.includeI(home,xiub);
00333 sofarAfterLB.includeI(home,xilb);
00334 }
00335 sofarAfterUB.dispose(home);
00336 sofarAfterLB.dispose(home);
00337 }
00338
00339 {
00340 GLBndSet sofarBeforeUB;
00341 GLBndSet sofarBeforeLB;
00342 for (int i=0; i<xsize; i++) {
00343 LubRanges<View1> yub(y);
00344 BndSetRanges slb(sofarBeforeLB);
00345 BndSetRanges afterlb(afterLB[i]);
00346 Iter::Ranges::Union<BndSetRanges,
00347 BndSetRanges> xjlb(slb, afterlb);
00348 Iter::Ranges::Diff<LubRanges<View1>,
00349 Iter::Ranges::Union<BndSetRanges,
00350 BndSetRanges> > diff1(yub, xjlb);
00351 GECODE_ME_CHECK_MODIFIED(modified, x[i].intersectI(home,diff1));
00352
00353 GlbRanges<View1> ylb(y);
00354 BndSetRanges sub(sofarBeforeUB);
00355 BndSetRanges afterub(afterUB[i]);
00356 Iter::Ranges::Union<BndSetRanges,
00357 BndSetRanges> xjub(sub, afterub);
00358 Iter::Ranges::Diff<GlbRanges<View1>,
00359 Iter::Ranges::Union<BndSetRanges,
00360 BndSetRanges> > diff2(ylb, xjub);
00361 GECODE_ME_CHECK_MODIFIED(modified, x[i].includeI(home,diff2));
00362
00363 LubRanges<View0> xiub(x[i]);
00364 GlbRanges<View0> xilb(x[i]);
00365 sofarBeforeUB.includeI(home,xiub);
00366 sofarBeforeLB.includeI(home,xilb);
00367 }
00368 sofarBeforeLB.dispose(home);
00369 sofarBeforeUB.dispose(home);
00370 }
00371
00372 for (int i=xsize;i--;) {
00373 afterUB[i].dispose(home);
00374 afterLB[i].dispose(home);
00375 }
00376
00377 return ES_NOFIX;
00378 }
00379
00380
00381 template <class View0, class View1>
00382 ExecStatus
00383 partitionNXiUB(Space* home,
00384 bool& modified, ViewArray<View0>& x, View1& y,
00385 GLBndSet& unionOfDets) {
00386 int xsize = x.size();
00387 GECODE_AUTOARRAY(GLBndSet, afterLB, xsize);
00388
00389 {
00390 GLBndSet sofarAfterLB;
00391 for (int i=xsize; i--;) {
00392 afterLB[i].init(home);
00393 afterLB[i].update(home,sofarAfterLB);
00394 GlbRanges<View0> xilb(x[i]);
00395 sofarAfterLB.includeI(home,xilb);
00396 }
00397 sofarAfterLB.dispose(home);
00398 }
00399
00400 {
00401 GLBndSet sofarBeforeLB;
00402 sofarBeforeLB.update(home,unionOfDets);
00403 for (int i=0; i<xsize; i++) {
00404 LubRanges<View1> yub(y);
00405 BndSetRanges slb(sofarBeforeLB);
00406 BndSetRanges afterlb(afterLB[i]);
00407 Iter::Ranges::Union<BndSetRanges,
00408 BndSetRanges> xjlb(slb, afterlb);
00409 Iter::Ranges::Diff<LubRanges<View1>,
00410 Iter::Ranges::Union<BndSetRanges,
00411 BndSetRanges> > diff1(yub, xjlb);
00412 GECODE_ME_CHECK_MODIFIED(modified, x[i].intersectI(home,diff1));
00413
00414 GlbRanges<View0> xilb(x[i]);
00415 sofarBeforeLB.includeI(home,xilb);
00416 }
00417 sofarBeforeLB.dispose(home);
00418 }
00419 for (int i=xsize; i--;)
00420 afterLB[i].dispose(home);
00421 return ES_NOFIX;
00422 }
00423
00424
00425 template <class View0, class View1>
00426 ExecStatus
00427 partitionNXiLB(Space* home,
00428 bool& modified, ViewArray<View0>& x, View1& y,
00429 GLBndSet& unionOfDets) {
00430 int xsize = x.size();
00431 GECODE_AUTOARRAY(GLBndSet, afterUB, xsize);
00432
00433 {
00434 GLBndSet sofarAfterUB;
00435 for (int i=xsize; i--;) {
00436 afterUB[i].init(home);
00437 afterUB[i].update(home,sofarAfterUB);
00438 LubRanges<View0> xiub(x[i]);
00439 sofarAfterUB.includeI(home,xiub);
00440 }
00441 sofarAfterUB.dispose(home);
00442 }
00443
00444 {
00445
00446 GLBndSet sofarBeforeUB;
00447 sofarBeforeUB.update(home,unionOfDets);
00448 for (int i=0; i<xsize; i++) {
00449 GlbRanges<View1> ylb(y);
00450 BndSetRanges sub(sofarBeforeUB);
00451 BndSetRanges afterub(afterUB[i]);
00452 Iter::Ranges::Union<BndSetRanges,
00453 BndSetRanges> xjub(sub, afterub);
00454 Iter::Ranges::Diff<GlbRanges<View1>,
00455 Iter::Ranges::Union<BndSetRanges,
00456 BndSetRanges> > diff2(ylb, xjub);
00457 GECODE_ME_CHECK_MODIFIED(modified, x[i].includeI(home,diff2));
00458
00459 LubRanges<View0> xiub(x[i]);
00460 sofarBeforeUB.includeI(home,xiub);
00461 }
00462 sofarBeforeUB.dispose(home);
00463 }
00464 for (int i=xsize;i--;)
00465 afterUB[i].dispose(home);
00466 return ES_NOFIX;
00467 }
00468
00469
00470 template <class View0, class View1>
00471 ExecStatus
00472 partitionNYLB(Space* home,
00473 bool& modified, ViewArray<View0>& x, View1& y,
00474 GLBndSet& unionOfDets) {
00475 assert(unionOfDets.isConsistent());
00476 int xsize = x.size();
00477 GECODE_AUTOARRAY(GlbRanges<View0>,xLBs,xsize);
00478 int nonEmptyCounter=0;
00479 for (int i = xsize; i--; ) {
00480 GlbRanges<View0> r(x[i]);
00481 if (r()) {
00482 xLBs[nonEmptyCounter] = r;
00483 nonEmptyCounter++;
00484 }
00485 }
00486 if (nonEmptyCounter !=0) {
00487 Iter::Ranges::NaryUnion<GlbRanges<View0> >
00488 xLBUnion(xLBs,nonEmptyCounter);
00489 BndSetRanges dets(unionOfDets);
00490 Iter::Ranges::Union<Iter::Ranges::NaryUnion<GlbRanges<View0> >,
00491 BndSetRanges>
00492 allUnion(xLBUnion,dets);
00493 GECODE_ME_CHECK_MODIFIED(modified, y.includeI(home,allUnion));
00494 }
00495 return ES_FIX;
00496 }
00497
00498
00499 template <class View0, class View1>
00500 ExecStatus
00501 partitionNYUB(Space* home,
00502 bool& modified, ViewArray<View0>& x, View1& y,
00503 GLBndSet& unionOfDets) {
00504 int xsize = x.size();
00505 GECODE_AUTOARRAY(LubRanges<View0>,xUBs,xsize);
00506 int nonEmptyCounter=0;
00507 for (int i = xsize; i--; ) {
00508 LubRanges<View0> r(x[i]);
00509 if (r()) {
00510 xUBs[nonEmptyCounter] = r;
00511 nonEmptyCounter++;
00512 }
00513 }
00514 if (nonEmptyCounter !=0) {
00515 Iter::Ranges::NaryUnion<LubRanges<View0> >
00516 xUBUnion(xUBs,nonEmptyCounter);
00517 BndSetRanges dets(unionOfDets);
00518 Iter::Ranges::Union<Iter::Ranges::NaryUnion<LubRanges<View0> >,
00519 BndSetRanges>
00520 fullUnion(xUBUnion, dets);
00521 GECODE_ME_CHECK_MODIFIED(modified, y.intersectI(home,fullUnion));
00522 }
00523 return ES_FIX;
00524 }
00525
00526 }}}
00527
00528