minmax.hpp gecode/set.hh gecode/int.hh /usr/include/gecode/set/int.hh Gecode Gecode::Set Gecode::Set::Int /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *GuidoTack<tack@gecode.org> *ChristianSchulte<schulte@gecode.org> *GaborSzokoli<szokoli@gecode.org> *DenysDuchier<denys.duchier@univ-orleans.fr> * *Copyright: *GuidoTack,2004 *ChristianSchulte,2004 *GaborSzokoli,2004 * *Lastmodified: *$Date:2012-10-1905:58:26+0200(Fri,19Oct2012)$by$Author:tack$ *$Revision:13156$ * *ThisfileispartofGecode,thegenericconstraint *developmentenvironment: *http://www.gecode.org * *Permissionisherebygranted,freeofcharge,toanypersonobtaining *acopyofthissoftwareandassociateddocumentationfiles(the *"Software"),todealintheSoftwarewithoutrestriction,including *withoutlimitationtherightstouse,copy,modify,merge,publish, *distribute,sublicense,and/orsellcopiesoftheSoftware,andto *permitpersonstowhomtheSoftwareisfurnishedtodoso,subjectto *thefollowingconditions: * *Theabovecopyrightnoticeandthispermissionnoticeshallbe *includedinallcopiesorsubstantialportionsoftheSoftware. * *THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND, *EXPRESSORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOF *MERCHANTABILITY,FITNESSFORAPARTICULARPURPOSEAND *NONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSORCOPYRIGHTHOLDERSBE *LIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHERINANACTION *OFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORINCONNECTION *WITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. * */ #include<gecode/set.hh> #include<gecode/int.hh> namespaceGecode{namespaceSet{namespaceInt{ template<classView> forceinline MinElement<View>::MinElement(Homehome,Viewy0,Gecode::Int::IntViewy1) :MixBinaryPropagator<View,PC_SET_ANY,Gecode::Int::IntView,Gecode::Int::PC_INT_BND>(home,y0,y1){} template<classView> forceinlineExecStatus MinElement<View>::post(Homehome,Viewx0,Gecode::Int::IntViewx1){ GECODE_ME_CHECK(x0.cardMin(home,1)); (void)new(home)MinElement(home,x0,x1); returnES_OK; } template<classView> forceinline MinElement<View>::MinElement(Space&home,boolshare,MinElement&p) :MixBinaryPropagator<View,PC_SET_ANY,Gecode::Int::IntView,Gecode::Int::PC_INT_BND>(home,share,p){} template<classView> Actor* MinElement<View>::copy(Space&home,boolshare){ returnnew(home)MinElement(home,share,*this); } template<classView> ExecStatus MinElement<View>::propagate(Space&home,constModEventDelta&){ //x1isanelementofx0.ub //x1=<smallestelementofx0.lb //x1=<x0.cardinialityMin-estlargestelementofx0.ub //(these2takecareofdeterminedx0) //Noelementinx0issmallerthanx1 //ifx1isdetermined,itispartoftheub. //Consequently: //Thedomainofx1isasubsetofx0.ubuptothefirstelementinx0.lb. //x0lackseverythingsmallerthansmallestpossiblex1. { LubRanges<View>ub(x0); GECODE_ME_CHECK(x1.inter_r(home,ub,false)); } GECODE_ME_CHECK(x1.lq(home,x0.glbMin())); //ifcardMin>lbSize? assert(x0.cardMin()>=1); { unsignedintsize=0; intmaxN=BndSet::MAX_OF_EMPTY; for(LubRanges<View>ubr(x0);ubr();++ubr,++size){} Regionr(home); int*ub=r.alloc<int>(size*2); inti=0; for(LubRanges<View>ubr(x0);ubr();++ubr,++i){ ub[2*i]=ubr.min(); ub[2*i+1]=ubr.max(); } unsignedintx0cm=x0.cardMin()-1; for(unsignedinti=size;i--;){ unsignedintwidth=static_cast<unsignedint>(ub[2*i+1]-ub[2*i]+1); if(width>x0cm){ maxN=static_cast<int>(ub[2*i+1]-x0cm); break; } x0cm-=width; } GECODE_ME_CHECK(x1.lq(home,maxN)); } GECODE_ME_CHECK(x0.exclude(home, Limits::min,x1.min()-1)); if(x1.assigned()){ GECODE_ME_CHECK(x0.include(home,x1.val())); GECODE_ME_CHECK(x0.exclude(home, Limits::min,x1.val()-1)); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } template<classView> forceinline NotMinElement<View>::NotMinElement(Homehome,Viewy0, Gecode::Int::IntViewy1) :MixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM>(home,y0,y1){} template<classView> forceinlineExecStatus NotMinElement<View>::post(Homehome,Viewx0,Gecode::Int::IntViewx1){ (void)new(home)NotMinElement(home,x0,x1); returnES_OK; } template<classView> forceinline NotMinElement<View>::NotMinElement(Space&home,boolshare, NotMinElement&p) :MixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM>(home,share,p){} template<classView> Actor* NotMinElement<View>::copy(Space&home,boolshare){ returnnew(home)NotMinElement(home,share,*this); } template<classView> ExecStatus NotMinElement<View>::propagate(Space&home,constModEventDelta&){ //cheaptestsforentailment: //ifx0isempty,thenentailed //ifmax(x1)<min(x0.lub)ormin(x1)>max(x0.lub),thenentailed //ifmin(x0.glb)<min(x1),thenentailed if((x0.cardMax()==0)|| ((x1.max()<x0.lubMin())||(x1.min()>x0.lubMax()))|| ((x0.glbSize()>0)&&(x0.glbMin()<x1.min()))) returnhome.ES_SUBSUMED(*this); //ifx1isdeterminedand=x0.lub.min:removeitfromx0, //thenentailed if(x1.assigned()&&x1.val()==x0.lubMin()){ GECODE_ME_CHECK(x0.exclude(home,x1.val())); returnhome.ES_SUBSUMED(*this); } //ifmin(x0)isdecided:removemin(x0)fromthedomainofx1 //thenentailed if(x0.glbMin()==x0.lubMin()){ GECODE_ME_CHECK(x1.nq(home,x0.glbMin())); returnhome.ES_SUBSUMED(*this); } //ifx1isdeterminedand=x0.glb.min,thenweneedatleast //onemoreelement;ifthereisonlyonebelow,thenwemust //takeit. if(x1.assigned()&&x0.glbSize()>0&&x1.val()==x0.glbMin()){ unsignedintoldGlbSize=x0.glbSize(); //ifthereisonly1unknownbelowx1,thenwemusttakeit UnknownRanges<View>ur(x0); assert(ur()); //theiteratorisnotempty:otherwisex0wouldbedetermined //andmin(x0)wouldhavebeendecidedandtheprecedingif //wouldhavecaughtit.Also,thefirstrangeisnotabove //x1otherwisetheveryfirstifwouldhavecaughtit. //solet'scheckiftheveryfirstrangeofunknownsisof //size1andthereisnosecondoneoritstartsabovex1. if(ur.width()==1){ inti=ur.min(); ++ur; if(!ur()||ur.min()>x1.val()){ GECODE_ME_CHECK(x0.include(home,i)); returnhome.ES_SUBSUMED(*this); } } GECODE_ME_CHECK(x0.cardMin(home,oldGlbSize+1)); } //ifdom(x1)andlub(x0)aredisjoint,thenentailed; { LubRanges<View>ub(x0); Gecode::Int::ViewRanges<Gecode::Int::IntView>d(x1); Gecode::Iter::Ranges::Inter<LubRanges<View>, Gecode::Int::ViewRanges<Gecode::Int::IntView>>ir(ub,d); if(!ir())returnhome.ES_SUBSUMED(*this); } //x0isfatedtoeventuallycontainatleastx0.cardMinelements. //thereforemin(x0)<=x0.cardMin-thlargestelementofx0.lub //ifx1>thanthat,thenentailed. { //tofindthex0.cardMin-thlargestelementofx0.lub,weneed //somesortofreverserangeiterator.wewillneedtofakeone //bystoringtherangesoftheforwarditeratorinanarray. //firstweneedtoknowhowlargethearrayneedstobe.so,let's //counttheranges: intnum_ranges=0; for(LubRanges<View>ur(x0);ur();++ur,++num_ranges){} //createanarrayforstoringminandmaxofeachrange Regionr(home); int*_ur=r.alloc<int>(num_ranges*2); //now,wefillthearray: inti=0; for(LubRanges<View>ur(x0);ur();++ur,++i){ _ur[2*i]=ur.min(); _ur[2*i+1]=ur.max(); } //nowwesearchfromthetoptherangethatcontainsthe //nthlargestvalue. unsignedintn=x0.cardMin(); intnth_largest=BndSet::MAX_OF_EMPTY; for(inti=num_ranges;i--;){ //numberofvaluesinrange unsignedintnum_values=static_cast<unsignedint>(_ur[2*i+1]-_ur[2*i]+1); //doestherangecontainthevalue? if(num_values>=n){ //recorditandexittheloop nth_largest=static_cast<int>(_ur[2*i+1]-n+1); break; } //otherwise,weskippednum_values n-=num_values; } //ifx1.min>nth_largest,thenentailed if(x1.min()>nth_largest) returnhome.ES_SUBSUMED(*this); } returnES_FIX; } template<classView,ReifyModerm> forceinline ReMinElement<View,rm>::ReMinElement(Homehome,Viewy0, Gecode::Int::IntViewy1, Gecode::Int::BoolViewb2) :Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM, Gecode::Int::BoolView>(home,y0,y1,b2){} template<classView,ReifyModerm> forceinlineExecStatus ReMinElement<View,rm>::post(Homehome,Viewx0,Gecode::Int::IntViewx1, Gecode::Int::BoolViewb2){ (void)new(home)ReMinElement(home,x0,x1,b2); returnES_OK; } template<classView,ReifyModerm> forceinline ReMinElement<View,rm>::ReMinElement(Space&home,boolshare, ReMinElement&p) :Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM, Gecode::Int::BoolView>(home,share,p){} template<classView,ReifyModerm> Actor* ReMinElement<View,rm>::copy(Space&home,boolshare){ returnnew(home)ReMinElement(home,share,*this); } template<classView,ReifyModerm> ExecStatus ReMinElement<View,rm>::propagate(Space&home,constModEventDelta&){ //checkifbisdetermined if(b.one()){ if(rm==RM_PMI) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(MinElement<View>::post(home(*this),x0,x1))); } if(b.zero()){ if(rm==RM_IMP) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(NotMinElement<View>::post(home(*this),x0,x1))); } //cheaptestsfor=>b=0 //ifx0isempty,thenb=0andentailed //ifmax(x1)<min(x0.lub)ormin(x1)>max(x0.lub),thenb=0andentailed //ifmin(x0.glb)<min(x1),thenb=0andentailed if((x0.cardMax()==0)|| ((x1.max()<x0.lubMin())||(x1.min()>x0.lubMax()))|| ((x0.glbSize()>0)&&(x0.glbMin()<x1.min()))) { if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); returnhome.ES_SUBSUMED(*this); } //ifmin(x0)isdecided if(x0.glbMin()==x0.lubMin()){ //ifx1isdet:checkif=min(x0),assignb,entailed if(x1.assigned()){ if(x1.val()==x0.glbMin()){ if(rm!=RM_IMP) GECODE_ME_CHECK(b.one(home)); }else{ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); } returnhome.ES_SUBSUMED(*this); } //ifmin(x0)notindom(x1):b=0,entailed elseif((x0.glbMin()<x1.min())|| (x0.glbMin()>x1.max())|| !x1.in(x0.glbMin())) { if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); returnhome.ES_SUBSUMED(*this); } } ////ifdom(x1)andlub(x0)aredisjoint,thenb=0,entailed; //{ //LubRanges<View>ub(x0); //Gecode::Int::ViewRanges<Gecode::Int::IntView>d(x1); //Gecode::Iter::Ranges::Inter<LubRanges<View>, //Gecode::Int::ViewRanges<Gecode::Int::IntView>>ir(ub,d); //if(!ir()){ //GECODE_ME_CHECK(b.zero(home)); //returnhome.ES_SUBSUMED(*this); //} //} ////x0isfatedtoeventuallycontainatleastx0.cardMinelements. ////thereforemin(x0)<=x0.cardMin-thlargestelementofx0.lub ////ifx1>thanthat,thenb=0andentailed. //{ ////tofindthex0.cardMin-thlargestelementofx0.lub,weneed ////somesortofreverserangeiterator.wewillneedtofakeone ////bystoringtherangesoftheforwarditeratorinanarray. ////firstweneedtoknowhowlargethearrayneedstobe.so,let's ////counttheranges: //intnum_ranges=0; //for(LubRanges<View>ur(x0);ur();++ur,++num_ranges){} ////createanarrayforstoringminandmaxofeachrange //Regionre(home); //int*_ur=re.alloc<int>(num_ranges*2); ////now,wefillthearray: //inti=0; //for(LubRanges<View>ur(x0);ur();++ur,++i){ //_ur[2*i]=ur.min(); //_ur[2*i+1]=ur.max(); //} ////nowwesearchfromthetoptherangethatcontainsthe ////nthlargestvalue. //intn=x0.cardMin(); //intnth_largest=BndSet::MAX_OF_EMPTY; //for(inti=num_ranges;i--;){ ////numberofvaluesinrange //intnum_values=_ur[2*i+1]-_ur[2*i]+1; ////doestherangecontainthevalue? //if(num_values>=n) //{ ////recorditandexittheloop //nth_largest=_ur[2*i+1]-n+1; //break; //} ////otherwise,weskippednum_values //n-=num_values; //} ////ifx1.min>nth_largest,thenentailed //if(x1.min()>nth_largest){ //GECODE_ME_CHECK(b.zero(home)); //returnhome.ES_SUBSUMED(*this); //} //} returnES_FIX; } template<classView> forceinline MaxElement<View>::MaxElement(Homehome,Viewy0,Gecode::Int::IntViewy1) :MixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_BND>(home,y0,y1){} template<classView> forceinline MaxElement<View>::MaxElement(Space&home,boolshare,MaxElement&p) :MixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_BND>(home,share,p){} template<classView> ExecStatus MaxElement<View>::post(Homehome,Viewx0, Gecode::Int::IntViewx1){ GECODE_ME_CHECK(x0.cardMin(home,1)); (void)new(home)MaxElement(home,x0,x1); returnES_OK; } template<classView> Actor* MaxElement<View>::copy(Space&home,boolshare){ returnnew(home)MaxElement(home,share,*this); } template<classView> ExecStatus MaxElement<View>::propagate(Space&home,constModEventDelta&){ LubRanges<View>ub(x0); GECODE_ME_CHECK(x1.inter_r(home,ub,false)); GECODE_ME_CHECK(x1.gq(home,x0.glbMax())); assert(x0.cardMin()>=1); GECODE_ME_CHECK(x1.gq(home,x0.lubMinN(x0.cardMin()-1))); GECODE_ME_CHECK(x0.exclude(home, x1.max()+1,Limits::max)); if(x1.assigned()){ GECODE_ME_CHECK(x0.include(home,x1.val())); GECODE_ME_CHECK(x0.exclude(home, x1.val()+1,Limits::max)); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } template<classView> forceinline NotMaxElement<View>::NotMaxElement(Homehome,Viewy0, Gecode::Int::IntViewy1) :MixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM>(home,y0,y1){} template<classView> forceinline NotMaxElement<View>::NotMaxElement(Space&home,boolshare, NotMaxElement&p) :MixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM>(home,share,p){} template<classView> ExecStatus NotMaxElement<View>::post(Homehome,Viewx0,Gecode::Int::IntViewx1){ (void)new(home)NotMaxElement(home,x0,x1); returnES_OK; } template<classView> Actor* NotMaxElement<View>::copy(Space&home,boolshare){ returnnew(home)NotMaxElement(home,share,*this); } template<classView> ExecStatus NotMaxElement<View>::propagate(Space&home,constModEventDelta&){ //cheaptestsforentailment: //ifx0isempty,thenentailed //ifmax(x1)<min(x0.lub)ormin(x1)>max(x0.lub),thenentailed //ifmax(x0.glb)>max(x1),thenentailed if((x0.cardMax()==0)|| ((x1.max()<x0.lubMin())||(x1.min()>x0.lubMax()))|| ((x0.glbSize()>0)&&(x0.glbMax()>x1.max()))) returnhome.ES_SUBSUMED(*this); //ifx1isdeterminedand=max(x0.lub):removeitfromx0, //thenentailed if(x1.assigned()&&x1.val()==x0.lubMax()){ GECODE_ME_CHECK(x0.exclude(home,x1.val())); returnhome.ES_SUBSUMED(*this); } //ifmax(x0)isdecided:removemax(x0)fromthedomainofx1 //thenentailed if(x0.glbMax()==x0.lubMax()){ GECODE_ME_CHECK(x1.nq(home,x0.glbMax())); returnhome.ES_SUBSUMED(*this); } //ifx1isdeterminedand=max(x0.glb),thenweneedatleast //onemoreelement;ifthereisonlyoneabove,thenwemust //takeit. if(x1.assigned()&&x0.glbSize()>0&&x1.val()==x0.glbMax()){ unsignedintoldGlbSize=x0.glbSize(); //ifthereisonly1unknownabovex1,thenwemusttakeit UnknownRanges<View>ur(x0); //thereisatleastoneunknownabovex1otherwiseitwould //havebeencaughtbytheifforx1=max(x0.lub) while(ur.max()<x1.val()){ assert(ur()); ++ur; }; //ifthefirstrangeabovex1containsjust1element, //andisthelastrange,thentakethatelement if(ur.width()==1){ inti=ur.min(); ++ur; if(!ur()){ //lastrange GECODE_ME_CHECK(x0.include(home,i)); returnhome.ES_SUBSUMED(*this); } } GECODE_ME_CHECK(x0.cardMin(home,oldGlbSize+1)); } //ifdom(x1)andlub(x0)aredisjoint,thenentailed { LubRanges<View>ub(x0); Gecode::Int::ViewRanges<Gecode::Int::IntView>d(x1); Gecode::Iter::Ranges::Inter<LubRanges<View>, Gecode::Int::ViewRanges<Gecode::Int::IntView>>ir(ub,d); if(!ir())returnhome.ES_SUBSUMED(*this); } //x0isfatedtoeventuallycontainatleastx0.cardMinelements. //thereforemax(x0)>=x0.cardMin-thsmallestelementofx0.lub. //ifx1<thanthat,thenentailed. { unsignedintn=x0.cardMin(); intnth_smallest=BndSet::MIN_OF_EMPTY; for(LubRanges<View>ur(x0);ur();++ur){ if(ur.width()>=n){ //recorditandexittheloop nth_smallest=static_cast<int>(ur.min()+n-1); break; } //otherwise,weskippedur.width()values n-=ur.width(); } //ifx1.max<nth_smallest,thenentailed if(x1.max()<nth_smallest) returnhome.ES_SUBSUMED(*this); } returnES_FIX; } template<classView,ReifyModerm> forceinline ReMaxElement<View,rm>::ReMaxElement(Homehome,Viewy0, Gecode::Int::IntViewy1, Gecode::Int::BoolViewb2) :Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM, Gecode::Int::BoolView>(home,y0,y1,b2){} template<classView,ReifyModerm> forceinline ReMaxElement<View,rm>::ReMaxElement(Space&home,boolshare, ReMaxElement&p) :Gecode::Int::ReMixBinaryPropagator<View,PC_SET_ANY, Gecode::Int::IntView,Gecode::Int::PC_INT_DOM, Gecode::Int::BoolView>(home,share,p){} template<classView,ReifyModerm> ExecStatus ReMaxElement<View,rm>::post(Homehome,Viewx0, Gecode::Int::IntViewx1, Gecode::Int::BoolViewb2){ (void)new(home)ReMaxElement(home,x0,x1,b2); returnES_OK; } template<classView,ReifyModerm> Actor* ReMaxElement<View,rm>::copy(Space&home,boolshare){ returnnew(home)ReMaxElement(home,share,*this); } template<classView,ReifyModerm> ExecStatus ReMaxElement<View,rm>::propagate(Space&home,constModEventDelta&){ //checkifbisdetermined if(b.one()){ if(rm==RM_PMI) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(MaxElement<View>::post(home(*this),x0,x1))); } if(b.zero()){ if(rm==RM_IMP) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(NotMaxElement<View>::post(home(*this),x0,x1))); } //cheaptestsfor=>b=0 //ifx0isempty,thenb=0andentailed //ifmax(x1)<min(x0.lub)ormin(x1)>max(x0.lub),thenb=0andentailed //ifmax(x0.glb)>max(x1),thenb=0andentailed if((x0.cardMax()==0)|| ((x1.max()<x0.lubMin())||(x1.min()>x0.lubMax()))|| ((x0.glbSize()>0)&&(x0.glbMax()>x1.max()))) { if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); returnhome.ES_SUBSUMED(*this); } //ifmax(x0)isdecided if(x0.glbMax()==x0.lubMax()){ //ifx1isdet:checkif=max(x0),assignb,entailed if(x1.assigned()){ if(x1.val()==x0.glbMax()){ if(rm!=RM_IMP) GECODE_ME_CHECK(b.one(home)); }else{ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); } returnhome.ES_SUBSUMED(*this); } //ifmax(x0)notindom(x1):b=0,entailed elseif((x0.glbMax()<x1.min())|| (x0.glbMax()>x1.max())|| !x1.in(x0.glbMax())) { if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); returnhome.ES_SUBSUMED(*this); } } //ifdom(x1)andlub(x0)aredisjoint,thenb=0,entailed { LubRanges<View>ub(x0); Gecode::Int::ViewRanges<Gecode::Int::IntView>d(x1); Gecode::Iter::Ranges::Inter<LubRanges<View>, Gecode::Int::ViewRanges<Gecode::Int::IntView>>ir(ub,d); if(!ir()){ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); returnhome.ES_SUBSUMED(*this); } } //x0isfatedtoeventuallycontainatleastx0.cardMinelements. //thereforemax(x0)>=x0.cardMin-thsmallestelementofx0.lub. //ifx1<thanthat,thenb=0,entailed. { unsignedintn=x0.cardMin(); intnth_smallest=BndSet::MIN_OF_EMPTY; for(LubRanges<View>ur(x0);ur();++ur){ if(ur.width()>=n) { //recorditandexittheloop nth_smallest=static_cast<int>(ur.min()+n-1); break; } //otherwise,weskippedur.width()values n-=ur.width(); } //ifx1.max<nth_smallest,thenentailed if(x1.max()<nth_smallest){ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero(home)); returnhome.ES_SUBSUMED(*this); } } returnES_FIX; } }}} //STATISTICS:set-prop