int-bin.hpp /usr/include/gecode/int/linear.hh Gecode Gecode::Int Gecode::Int::Linear GECODE_INT_PV CASE TELL UPDATE if (bm & (CASE)) { \ bm -= (CASE); ModEvent me = (TELL); \ if (me_failed(me)) return ES_FAILED; \ if (me_modified(me)) bm |= (UPDATE); \ } /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> * *Copyright: *ChristianSchulte,2003 * *Lastmodified: *$Date:2012-10-1816:02:42+0200(Thu,18Oct2012)$by$Author:schulte$ *$Revision:13154$ * *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{ /* *Binarylinearpropagators * */ template<classVal,classA,classB,PropCondpc> forceinline LinBin<Val,A,B,pc>::LinBin(Homehome,Ay0,By1,Valc0) :Propagator(home),x0(y0),x1(y1),c(c0){ x0.subscribe(home,*this,pc); x1.subscribe(home,*this,pc); } template<classVal,classA,classB,PropCondpc> forceinline LinBin<Val,A,B,pc>::LinBin(Space&home,boolshare,LinBin<Val,A,B,pc>&p) :Propagator(home,share,p),c(p.c){ x0.update(home,share,p.x0); x1.update(home,share,p.x1); } template<classVal,classA,classB,PropCondpc> forceinline LinBin<Val,A,B,pc>::LinBin(Space&home,boolshare,Propagator&p, Ay0,By1,Valc0) :Propagator(home,share,p),c(c0){ x0.update(home,share,y0); x1.update(home,share,y1); } template<classVal,classA,classB,PropCondpc> PropCost LinBin<Val,A,B,pc>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::binary(PropCost::LO); } template<classVal,classA,classB,PropCondpc> forceinlinesize_t LinBin<Val,A,B,pc>::dispose(Space&home){ x0.cancel(home,*this,pc); x1.cancel(home,*this,pc); (void)Propagator::dispose(home); returnsizeof(*this); } /* *Binaryreifiedlinearpropagators * */ template<classVal,classA,classB,PropCondpc,classCtrl> forceinline ReLinBin<Val,A,B,pc,Ctrl>::ReLinBin(Homehome,Ay0,By1,Valc0,Ctrlb0) :Propagator(home),x0(y0),x1(y1),c(c0),b(b0){ x0.subscribe(home,*this,pc); x1.subscribe(home,*this,pc); b.subscribe(home,*this,PC_INT_VAL); } template<classVal,classA,classB,PropCondpc,classCtrl> forceinline ReLinBin<Val,A,B,pc,Ctrl>::ReLinBin(Space&home,boolshare, ReLinBin<Val,A,B,pc,Ctrl>&p) :Propagator(home,share,p),c(p.c){ x0.update(home,share,p.x0); x1.update(home,share,p.x1); b.update(home,share,p.b); } template<classVal,classA,classB,PropCondpc,classCtrl> PropCost ReLinBin<Val,A,B,pc,Ctrl>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::binary(PropCost::LO); } template<classVal,classA,classB,PropCondpc,classCtrl> forceinlinesize_t ReLinBin<Val,A,B,pc,Ctrl>::dispose(Space&home){ x0.cancel(home,*this,pc); x1.cancel(home,*this,pc); b.cancel(home,*this,PC_BOOL_VAL); (void)Propagator::dispose(home); returnsizeof(*this); } /* *Binaryboundsconsistentlinearequality * */ template<classVal,classA,classB> forceinline EqBin<Val,A,B>::EqBin(Homehome,Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c){} template<classVal,classA,classB> ExecStatus EqBin<Val,A,B>::post(Homehome,Ax0,Bx1,Valc){ (void)new(home)EqBin<Val,A,B>(home,x0,x1,c); returnES_OK; } template<classVal,classA,classB> forceinline EqBin<Val,A,B>::EqBin(Space&home,boolshare,EqBin<Val,A,B>&p) :LinBin<Val,A,B,PC_INT_BND>(home,share,p){} template<classVal,classA,classB> forceinline EqBin<Val,A,B>::EqBin(Space&home,boolshare,Propagator&p, Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c){} template<classVal,classA,classB> Actor* EqBin<Val,A,B>::copy(Space&home,boolshare){ returnnew(home)EqBin<Val,A,B>(home,share,*this); } enumBinMod{ BM_X0_MIN=1<<0, BM_X0_MAX=1<<1, BM_X1_MIN=1<<2, BM_X1_MAX=1<<3, BM_ALL=BM_X0_MIN|BM_X0_MAX|BM_X1_MIN|BM_X1_MAX }; #defineGECODE_INT_PV(CASE,TELL,UPDATE)\ if(bm&(CASE)){\ bm-=(CASE);ModEventme=(TELL);\ if(me_failed(me))returnES_FAILED;\ if(me_modified(me))bm|=(UPDATE);\ } template<classVal,classA,classB> ExecStatus EqBin<Val,A,B>::propagate(Space&home,constModEventDelta&){ intbm=BM_ALL; do{ GECODE_INT_PV(BM_X0_MIN,x0.gq(home,c-x1.max()),BM_X1_MAX); GECODE_INT_PV(BM_X1_MIN,x1.gq(home,c-x0.max()),BM_X0_MAX); GECODE_INT_PV(BM_X0_MAX,x0.lq(home,c-x1.min()),BM_X1_MIN); GECODE_INT_PV(BM_X1_MAX,x1.lq(home,c-x0.min()),BM_X0_MIN); }while(bm); returnx0.assigned()?home.ES_SUBSUMED(*this):ES_FIX; } #undefGECODE_INT_PV /* *Reifiedbinaryboundsconsistentlinearequality * */ template<classVal,classA,classB,classCtrl,ReifyModerm> forceinline ReEqBin<Val,A,B,Ctrl,rm>::ReEqBin(Homehome,Ax0,Bx1,Valc,Ctrlb) :ReLinBin<Val,A,B,PC_INT_BND,Ctrl>(home,x0,x1,c,b){} template<classVal,classA,classB,classCtrl,ReifyModerm> ExecStatus ReEqBin<Val,A,B,Ctrl,rm>::post(Homehome,Ax0,Bx1,Valc,Ctrlb){ (void)new(home)ReEqBin<Val,A,B,Ctrl,rm>(home,x0,x1,c,b); returnES_OK; } template<classVal,classA,classB,classCtrl,ReifyModerm> forceinline ReEqBin<Val,A,B,Ctrl,rm>::ReEqBin(Space&home,boolshare, ReEqBin<Val,A,B,Ctrl,rm>&p) :ReLinBin<Val,A,B,PC_INT_BND,Ctrl>(home,share,p){} template<classVal,classA,classB,classCtrl,ReifyModerm> Actor* ReEqBin<Val,A,B,Ctrl,rm>::copy(Space&home,boolshare){ returnnew(home)ReEqBin<Val,A,B,Ctrl,rm>(home,share,*this); } template<classVal,classA,classB,classCtrl,ReifyModerm> ExecStatus ReEqBin<Val,A,B,Ctrl,rm>::propagate(Space&home,constModEventDelta&){ if(b.zero()){ if(rm==RM_IMP) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(NqBin<Val,A,B>::post(home(*this),x0,x1,c))); } if(b.one()){ if(rm==RM_PMI) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(EqBin<Val,A,B>::post(home(*this),x0,x1,c))); } if((x0.min()+x1.min()>c)||(x0.max()+x1.max()<c)){ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero_none(home)); returnhome.ES_SUBSUMED(*this); } if(x0.assigned()&&x1.assigned()){ assert(x0.val()+x1.val()==c); if(rm!=RM_IMP) GECODE_ME_CHECK(b.one_none(home)); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } /* *Binarydomainconsistentlineardisequality * */ template<classVal,classA,classB> forceinline NqBin<Val,A,B>::NqBin(Homehome,Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_VAL>(home,x0,x1,c){} template<classVal,classA,classB> ExecStatus NqBin<Val,A,B>::post(Homehome,Ax0,Bx1,Valc){ (void)new(home)NqBin<Val,A,B>(home,x0,x1,c); returnES_OK; } template<classVal,classA,classB> forceinline NqBin<Val,A,B>::NqBin(Space&home,boolshare,NqBin<Val,A,B>&p) :LinBin<Val,A,B,PC_INT_VAL>(home,share,p){} template<classVal,classA,classB> Actor* NqBin<Val,A,B>::copy(Space&home,boolshare){ returnnew(home)NqBin<Val,A,B>(home,share,*this); } template<classVal,classA,classB> forceinline NqBin<Val,A,B>::NqBin(Space&home,boolshare,Propagator&p, Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_VAL>(home,share,p,x0,x1,c){} template<classVal,classA,classB> PropCost NqBin<Val,A,B>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::unary(PropCost::LO); } template<classVal,classA,classB> ExecStatus NqBin<Val,A,B>::propagate(Space&home,constModEventDelta&){ if(x0.assigned()){ GECODE_ME_CHECK(x1.nq(home,c-x0.val())); }else{ assert(x1.assigned()); GECODE_ME_CHECK(x0.nq(home,c-x1.val())); } returnhome.ES_SUBSUMED(*this); } /* *Binarydomainconsistentlessequal * */ template<classVal,classA,classB> forceinline LqBin<Val,A,B>::LqBin(Homehome,Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c){} template<classVal,classA,classB> ExecStatus LqBin<Val,A,B>::post(Homehome,Ax0,Bx1,Valc){ (void)new(home)LqBin<Val,A,B>(home,x0,x1,c); returnES_OK; } template<classVal,classA,classB> forceinline LqBin<Val,A,B>::LqBin(Space&home,boolshare,LqBin<Val,A,B>&p) :LinBin<Val,A,B,PC_INT_BND>(home,share,p){} template<classVal,classA,classB> Actor* LqBin<Val,A,B>::copy(Space&home,boolshare){ returnnew(home)LqBin<Val,A,B>(home,share,*this); } template<classVal,classA,classB> forceinline LqBin<Val,A,B>::LqBin(Space&home,boolshare,Propagator&p, Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c){} template<classVal,classA,classB> ExecStatus LqBin<Val,A,B>::propagate(Space&home,constModEventDelta&){ GECODE_ME_CHECK(x0.lq(home,c-x1.min())); GECODE_ME_CHECK(x1.lq(home,c-x0.min())); return(x0.max()+x1.max()<=c)?home.ES_SUBSUMED(*this):ES_FIX; } /* *Binarydomainconsistentgreaterequal * */ template<classVal,classA,classB> forceinline GqBin<Val,A,B>::GqBin(Homehome,Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_BND>(home,x0,x1,c){} template<classVal,classA,classB> ExecStatus GqBin<Val,A,B>::post(Homehome,Ax0,Bx1,Valc){ (void)new(home)GqBin<Val,A,B>(home,x0,x1,c); returnES_OK; } template<classVal,classA,classB> forceinline GqBin<Val,A,B>::GqBin(Space&home,boolshare,GqBin<Val,A,B>&p) :LinBin<Val,A,B,PC_INT_BND>(home,share,p){} template<classVal,classA,classB> Actor* GqBin<Val,A,B>::copy(Space&home,boolshare){ returnnew(home)GqBin<Val,A,B>(home,share,*this); } template<classVal,classA,classB> forceinline GqBin<Val,A,B>::GqBin(Space&home,boolshare,Propagator&p, Ax0,Bx1,Valc) :LinBin<Val,A,B,PC_INT_BND>(home,share,p,x0,x1,c){} template<classVal,classA,classB> ExecStatus GqBin<Val,A,B>::propagate(Space&home,constModEventDelta&){ GECODE_ME_CHECK(x0.gq(home,c-x1.max())); GECODE_ME_CHECK(x1.gq(home,c-x0.max())); return(x0.min()+x1.min()>=c)?home.ES_SUBSUMED(*this):ES_FIX; } /* *Reifiedbinarydomainconsistentlessequal * */ template<classVal,classA,classB,ReifyModerm> forceinline ReLqBin<Val,A,B,rm>::ReLqBin(Homehome,Ax0,Bx1,Valc,BoolViewb) :ReLinBin<Val,A,B,PC_INT_BND,BoolView>(home,x0,x1,c,b){} template<classVal,classA,classB,ReifyModerm> ExecStatus ReLqBin<Val,A,B,rm>::post(Homehome,Ax0,Bx1,Valc,BoolViewb){ (void)new(home)ReLqBin<Val,A,B,rm>(home,x0,x1,c,b); returnES_OK; } template<classVal,classA,classB,ReifyModerm> forceinline ReLqBin<Val,A,B,rm>::ReLqBin(Space&home,boolshare,ReLqBin<Val,A,B,rm>&p) :ReLinBin<Val,A,B,PC_INT_BND,BoolView>(home,share,p){} template<classVal,classA,classB,ReifyModerm> Actor* ReLqBin<Val,A,B,rm>::copy(Space&home,boolshare){ returnnew(home)ReLqBin<Val,A,B,rm>(home,share,*this); } template<classVal,classA,classB,ReifyModerm> ExecStatus ReLqBin<Val,A,B,rm>::propagate(Space&home,constModEventDelta&){ if(b.one()){ if(rm==RM_PMI) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(LqBin<Val,A,B>::post(home(*this),x0,x1,c))); } if(b.zero()){ if(rm==RM_IMP) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(GqBin<Val,A,B>::post(home(*this),x0,x1,c+1))); } if(x0.max()+x1.max()<=c){ if(rm!=RM_IMP) GECODE_ME_CHECK(b.one_none(home)); returnhome.ES_SUBSUMED(*this); } if(x0.min()+x1.min()>c){ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero_none(home)); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } }}} //STATISTICS:int-prop