bool-view.hpp /usr/include/gecode/int/linear.hh Gecode Gecode::Int Gecode::Int::Linear /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> * *Copyright: *ChristianSchulte,2004 * *Lastmodified: *$Date:2010-03-0317:32:21+0100(Wed,03Mar2010)$by$Author:schulte$ *$Revision:10364$ * *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. * */ namespaceGecode{namespaceInt{namespaceLinear{ /* *Base-class * */ template<classXV,classYV> LinBoolView<XV,YV>::LinBoolView(Homehome, ViewArray<XV>&x0,YVy0,intc0) :Propagator(home),x(x0),y(y0),c(c0){ x.subscribe(home,*this,PC_INT_VAL); y.subscribe(home,*this,PC_INT_BND); } template<classXV,classYV> forceinlinesize_t LinBoolView<XV,YV>::dispose(Space&home){ x.cancel(home,*this,PC_INT_VAL); y.cancel(home,*this,PC_INT_BND); (void)Propagator::dispose(home); returnsizeof(*this); } template<classXV,classYV> forceinline LinBoolView<XV,YV>::LinBoolView(Space&home,boolshare,LinBoolView&p) :Propagator(home,share,p),c(p.c){ x.update(home,share,p.x); y.update(home,share,p.y); } template<classXV,classYV> PropCost LinBoolView<XV,YV>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::linear(PropCost::LO,x.size()); } /* *Equalitypropagator * */ template<classXV,classYV> forceinline EqBoolView<XV,YV>::EqBoolView(Homehome,ViewArray<XV>&x,YVy,intc) :LinBoolView<XV,YV>(home,x,y,c){} template<classXV,classYV> ExecStatus EqBoolView<XV,YV>::post(Homehome,ViewArray<XV>&x,YVy,intc){ if(y.assigned()) returnEqBoolInt<XV>::post(home,x,y.val()+c); intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x[i]=x[--n];c--; }elseif(x[i].zero()){ x[i]=x[--n]; } x.size(n); GECODE_ME_CHECK(y.lq(home,n-c)); GECODE_ME_CHECK(y.gq(home,-c)); if(n==0) returnES_OK; if(y.min()+c==n){ assert(y.assigned()); for(inti=n;i--;) GECODE_ME_CHECK(x[i].one_none(home)); returnES_OK; } if(y.max()+c==0){ assert(y.assigned()); for(inti=n;i--;) GECODE_ME_CHECK(x[i].zero_none(home)); returnES_OK; } (void)new(home)EqBoolView<XV,YV>(home,x,y,c); returnES_OK; } template<classXV,classYV> forceinline EqBoolView<XV,YV>::EqBoolView(Space&home,boolshare,EqBoolView<XV,YV>&p) :LinBoolView<XV,YV>(home,share,p){} template<classXV,classYV> Actor* EqBoolView<XV,YV>::copy(Space&home,boolshare){ returnnew(home)EqBoolView<XV,YV>(home,share,*this); } template<classXV,classYV> ExecStatus EqBoolView<XV,YV>::propagate(Space&home,constModEventDelta&){ intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x[i]=x[--n];c--; }elseif(x[i].zero()){ x[i]=x[--n]; } x.size(n); GECODE_ME_CHECK(y.lq(home,n-c)); GECODE_ME_CHECK(y.gq(home,-c)); if(n==0) returnhome.ES_SUBSUMED(*this); if(y.min()+c==n){ assert(y.assigned()); for(inti=n;i--;) GECODE_ME_CHECK(x[i].one_none(home)); returnhome.ES_SUBSUMED(*this); } if(y.max()+c==0){ assert(y.assigned()); for(inti=n;i--;) GECODE_ME_CHECK(x[i].zero_none(home)); returnhome.ES_SUBSUMED(*this); } if(y.assigned()) GECODE_REWRITE(*this,EqBoolInt<XV>::post(home(*this),x,y.val()+c)); returnES_FIX; } /* *Disequalitypropagator * */ template<classXV,classYV> forceinline NqBoolView<XV,YV>::NqBoolView(Homehome,ViewArray<XV>&x,YVy,intc) :LinBoolView<XV,YV>(home,x,y,c){} template<classXV,classYV> ExecStatus NqBoolView<XV,YV>::post(Homehome,ViewArray<XV>&x,YVy,intc){ if(y.assigned()) returnNqBoolInt<XV>::post(home,x,y.val()+c); intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x[i]=x[--n];c--; }elseif(x[i].zero()){ x[i]=x[--n]; } x.size(n); if((n-c<y.min())||(-c>y.max())) returnES_OK; if(n==0){ GECODE_ME_CHECK(y.nq(home,-c)); returnES_OK; } if((n==1)&&y.assigned()){ if(y.val()+c==1){ GECODE_ME_CHECK(x[0].zero_none(home)); }else{ assert(y.val()+c==0); GECODE_ME_CHECK(x[0].one_none(home)); } returnES_OK; } (void)new(home)NqBoolView<XV,YV>(home,x,y,c); returnES_OK; } template<classXV,classYV> forceinline NqBoolView<XV,YV>::NqBoolView(Space&home,boolshare,NqBoolView<XV,YV>&p) :LinBoolView<XV,YV>(home,share,p){} template<classXV,classYV> Actor* NqBoolView<XV,YV>::copy(Space&home,boolshare){ returnnew(home)NqBoolView<XV,YV>(home,share,*this); } template<classXV,classYV> ExecStatus NqBoolView<XV,YV>::propagate(Space&home,constModEventDelta&){ intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x[i]=x[--n];c--; }elseif(x[i].zero()){ x[i]=x[--n]; } x.size(n); if((n-c<y.min())||(-c>y.max())) returnhome.ES_SUBSUMED(*this); if(n==0){ GECODE_ME_CHECK(y.nq(home,-c)); returnhome.ES_SUBSUMED(*this); } if((n==1)&&y.assigned()){ if(y.val()+c==1){ GECODE_ME_CHECK(x[0].zero_none(home)); }else{ assert(y.val()+c==0); GECODE_ME_CHECK(x[0].one_none(home)); } returnhome.ES_SUBSUMED(*this); } returnES_FIX; } /* *Greaterorequalpropagator * */ template<classXV,classYV> forceinline GqBoolView<XV,YV>::GqBoolView(Homehome,ViewArray<XV>&x,YVy,intc) :LinBoolView<XV,YV>(home,x,y,c){} template<classXV,classYV> ExecStatus GqBoolView<XV,YV>::post(Homehome,ViewArray<XV>&x,YVy,intc){ if(y.assigned()) returnGqBoolInt<XV>::post(home,x,y.val()+c); //Eliminateassignedviews intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x[i]=x[--n];c--; }elseif(x[i].zero()){ x[i]=x[--n]; } x.size(n); GECODE_ME_CHECK(y.lq(home,n-c)); if(-c>=y.max()) returnES_OK; if(y.min()+c==n){ for(inti=n;i--;) GECODE_ME_CHECK(x[i].one_none(home)); returnES_OK; } (void)new(home)GqBoolView<XV,YV>(home,x,y,c); returnES_OK; } template<classXV,classYV> forceinline GqBoolView<XV,YV>::GqBoolView(Space&home,boolshare,GqBoolView<XV,YV>&p) :LinBoolView<XV,YV>(home,share,p){} template<classXV,classYV> Actor* GqBoolView<XV,YV>::copy(Space&home,boolshare){ returnnew(home)GqBoolView<XV,YV>(home,share,*this); } template<classXV,classYV> ExecStatus GqBoolView<XV,YV>::propagate(Space&home,constModEventDelta&){ intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x[i]=x[--n];c--; }elseif(x[i].zero()){ x[i]=x[--n]; } x.size(n); GECODE_ME_CHECK(y.lq(home,n-c)); if(-c>=y.max()) returnhome.ES_SUBSUMED(*this); if(y.min()+c==n){ for(inti=n;i--;) GECODE_ME_CHECK(x[i].one_none(home)); returnhome.ES_SUBSUMED(*this); } if(y.assigned()) GECODE_REWRITE(*this,GqBoolInt<XV>::post(home(*this),x,y.val()+c)); returnES_FIX; } }}} //STATISTICS:int-prop