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