Generated on Mon Aug 25 11:35:44 2008 for Gecode by doxygen 1.5.6

common.icc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *     Christian Schulte <schulte@gecode.org>
00006  *
00007  *  Contributing authors:
00008  *     Gabor Szokoli <szokoli@gecode.org>
00009  *
00010  *  Copyright:
00011  *     Guido Tack, 2004
00012  *     Christian Schulte, 2004
00013  *     Gabor Szokoli, 2004
00014  *
00015  *  Last modified:
00016  *     $Date: 2008-07-11 09:29:47 +0200 (Fri, 11 Jul 2008) $ by $Author: tack $
00017  *     $Revision: 7286 $
00018  *
00019  *  This file is part of Gecode, the generic constraint
00020  *  development environment:
00021  *     http://www.gecode.org
00022  *
00023  *  Permission is hereby granted, free of charge, to any person obtaining
00024  *  a copy of this software and associated documentation files (the
00025  *  "Software"), to deal in the Software without restriction, including
00026  *  without limitation the rights to use, copy, modify, merge, publish,
00027  *  distribute, sublicense, and/or sell copies of the Software, and to
00028  *  permit persons to whom the Software is furnished to do so, subject to
00029  *  the following conditions:
00030  *
00031  *  The above copyright notice and this permission notice shall be
00032  *  included in all copies or substantial portions of the Software.
00033  *
00034  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00035  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00036  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00037  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00038  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00039  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00040  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    * Detect sharing between 3 variables
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         // unsigned int res = std::max(x0.cardMin()+
00114         //                             (x1.cardMin()<s1 ?
00115         //                              0 : x1.cardMin()-s1),
00116         //                             std::max(x0.cardMin(),
00117         //                                      x1.cardMin()));
00118         // GECODE_ME_CHECK_MODIFIED(modified, x2.cardMin(home,res));
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     // Max(Xi.cardMin) <= y.card <= Sum(Xi.cardMax)
00202     // Xi.card <=y.cardMax
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; } //overflow
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     //y.cardMin - Sum(Xj.cardMax) <= Xi.card
00215 
00216     if (x.size() == 0)
00217       return ES_NOFIX;
00218 
00219     //TODO: overflow management is a waste now.
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           //overflow, fill the rest of the array.
00228           for (int j=i; j>0;j--) {
00229             rightSum[j]=Limits::card;
00230           }
00231           break;
00232         }
00233       }
00234 
00235       //Size of union of determied vars missing from x sneaked in here:
00236       unsigned int leftAcc=unionOfDets.size();
00237 
00238       for (int i=0; i<xsize;i++) {
00239         unsigned int jsum = leftAcc+rightSum[i];
00240         //If jsum did not overflow and is less than y.cardMin:
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     //y.cardMin - |U(Xj.ub)| <= Xi.card
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       //union of determied vars missing from x sneaked in here:
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     //no need for this: |y.lb - U(Xj.cardMax)| <= S.card
00286 
00287     return ES_NOFIX;
00288 
00289   }
00290 
00291   /*
00292    * Xi UB is subset of YUB
00293    * Subscribes to Y UB
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   // cardinality rules for PartitionN constraint
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         //sum of mins overflows: fail the space.
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         //sum of maxes overflows: no useful information to tell.
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     //Cardinality of each x[i] limited by cardinality of y minus all x[j]s:
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           //overflow, fill the rest of the array.
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           //overflow, fail the space
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         //If maxSum did not overflow and is less than y.cardMin:
00371         if (maxSum >= leftMaxAcc &&  maxSum < y.cardMin()) {
00372           GECODE_ME_CHECK_MODIFIED(modified, x[i].cardMin(home,y.cardMin()-maxSum));
00373         }
00374 
00375         //Overflow, fail.
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   // Xi LB includes YLB minus union Xj UB
00396   // Xi UB is subset of YUB minus union of Xj LBs
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   // Xi UB is subset of YUB minus union of Xj LBs
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   // Xi LB includes YLB minus union Xj UB
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       //The union of previously determined x[j]-s is added to the mix here:
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   // Y LB contains union of X LBs
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   // Y UB is subset of union of X UBs
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 // STATISTICS: set-prop