int-ter.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: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{ /* *Ternarylinearpropagators * */ template<classVal,classA,classB,classC,PropCondpc> forceinline LinTer<Val,A,B,C,pc>::LinTer(Homehome,Ay0,By1,Cy2,Valc0) :Propagator(home),x0(y0),x1(y1),x2(y2),c(c0){ x0.subscribe(home,*this,pc); x1.subscribe(home,*this,pc); x2.subscribe(home,*this,pc); } template<classVal,classA,classB,classC,PropCondpc> forceinline LinTer<Val,A,B,C,pc>::LinTer(Space&home,boolshare, LinTer<Val,A,B,C,pc>&p) :Propagator(home,share,p),c(p.c){ x0.update(home,share,p.x0); x1.update(home,share,p.x1); x2.update(home,share,p.x2); } template<classVal,classA,classB,classC,PropCondpc> forceinline LinTer<Val,A,B,C,pc>::LinTer(Space&home,boolshare,Propagator&p, Ay0,By1,Cy2,Valc0) :Propagator(home,share,p),c(c0){ x0.update(home,share,y0); x1.update(home,share,y1); x2.update(home,share,y2); } template<classVal,classA,classB,classC,PropCondpc> PropCost LinTer<Val,A,B,C,pc>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::ternary(PropCost::LO); } template<classVal,classA,classB,classC,PropCondpc> forceinlinesize_t LinTer<Val,A,B,C,pc>::dispose(Space&home){ x0.cancel(home,*this,pc); x1.cancel(home,*this,pc); x2.cancel(home,*this,pc); (void)Propagator::dispose(home); returnsizeof(*this); } /* *Equalitypropagator * */ template<classVal,classA,classB,classC> forceinline EqTer<Val,A,B,C>::EqTer(Homehome,Ax0,Bx1,Cx2,Valc) :LinTer<Val,A,B,C,PC_INT_BND>(home,x0,x1,x2,c){} template<classVal,classA,classB,classC> ExecStatus EqTer<Val,A,B,C>::post(Homehome,Ax0,Bx1,Cx2,Valc){ (void)new(home)EqTer<Val,A,B,C>(home,x0,x1,x2,c); returnES_OK; } template<classVal,classA,classB,classC> forceinline EqTer<Val,A,B,C>::EqTer(Space&home,boolshare,EqTer<Val,A,B,C>&p) :LinTer<Val,A,B,C,PC_INT_BND>(home,share,p){} template<classVal,classA,classB,classC> forceinline EqTer<Val,A,B,C>::EqTer(Space&home,boolshare,Propagator&p, Ax0,Bx1,Cx2,Valc) :LinTer<Val,A,B,C,PC_INT_BND>(home,share,p,x0,x1,x2,c){} template<classVal,classA,classB,classC> Actor* EqTer<Val,A,B,C>::copy(Space&home,boolshare){ returnnew(home)EqTer<Val,A,B,C>(home,share,*this); } enumTerMod{ TM_X0_MIN=1<<0, TM_X0_MAX=1<<1, TM_X1_MIN=1<<2, TM_X1_MAX=1<<3, TM_X2_MIN=1<<4, TM_X2_MAX=1<<5, TM_ALL=TM_X0_MIN|TM_X0_MAX|TM_X1_MIN|TM_X1_MAX|TM_X2_MIN|TM_X2_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,classC> ExecStatus EqTer<Val,A,B,C>::propagate(Space&home,constModEventDelta&){ intbm=TM_ALL; do{ GECODE_INT_PV(TM_X0_MIN,x0.gq(home,c-x1.max()-x2.max()), TM_X1_MAX|TM_X2_MAX); GECODE_INT_PV(TM_X1_MIN,x1.gq(home,c-x0.max()-x2.max()), TM_X0_MAX|TM_X2_MAX); GECODE_INT_PV(TM_X2_MIN,x2.gq(home,c-x0.max()-x1.max()), TM_X0_MAX|TM_X1_MAX); GECODE_INT_PV(TM_X0_MAX,x0.lq(home,c-x1.min()-x2.min()), TM_X1_MIN|TM_X2_MIN); GECODE_INT_PV(TM_X1_MAX,x1.lq(home,c-x0.min()-x2.min()), TM_X0_MIN|TM_X2_MIN); GECODE_INT_PV(TM_X2_MAX,x2.lq(home,c-x0.min()-x1.min()), TM_X0_MIN|TM_X1_MIN); }while(bm); return(x0.assigned()&&x1.assigned())? home.ES_SUBSUMED(*this):ES_FIX; } #undefGECODE_INT_PV /* *Disequalitypropagator * */ template<classVal,classA,classB,classC> forceinline NqTer<Val,A,B,C>::NqTer(Homehome,Ax0,Bx1,Cx2,Valc) :LinTer<Val,A,B,C,PC_INT_VAL>(home,x0,x1,x2,c){} template<classVal,classA,classB,classC> ExecStatus NqTer<Val,A,B,C>::post(Homehome,Ax0,Bx1,Cx2,Valc){ (void)new(home)NqTer<Val,A,B,C>(home,x0,x1,x2,c); returnES_OK; } template<classVal,classA,classB,classC> forceinline NqTer<Val,A,B,C>::NqTer(Space&home,boolshare,NqTer<Val,A,B,C>&p) :LinTer<Val,A,B,C,PC_INT_VAL>(home,share,p){} template<classVal,classA,classB,classC> Actor* NqTer<Val,A,B,C>::copy(Space&home,boolshare){ returnnew(home)NqTer<Val,A,B,C>(home,share,*this); } template<classVal,classA,classB,classC> forceinline NqTer<Val,A,B,C>::NqTer(Space&home,boolshare,Propagator&p, Ax0,Bx1,Cx2,Valc) :LinTer<Val,A,B,C,PC_INT_VAL>(home,share,p,x0,x1,x2,c){} template<classVal,classA,classB,classC> ExecStatus NqTer<Val,A,B,C>::propagate(Space&home,constModEventDelta&){ if(x0.assigned()&&x1.assigned()){ GECODE_ME_CHECK(x2.nq(home,c-x0.val()-x1.val())); returnhome.ES_SUBSUMED(*this); } if(x0.assigned()&&x2.assigned()){ GECODE_ME_CHECK(x1.nq(home,c-x0.val()-x2.val())); returnhome.ES_SUBSUMED(*this); } if(x1.assigned()&&x2.assigned()){ GECODE_ME_CHECK(x0.nq(home,c-x1.val()-x2.val())); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } /* *Inequalitypropagator * */ template<classVal,classA,classB,classC> forceinline LqTer<Val,A,B,C>::LqTer(Homehome,Ax0,Bx1,Cx2,Valc) :LinTer<Val,A,B,C,PC_INT_BND>(home,x0,x1,x2,c){} template<classVal,classA,classB,classC> ExecStatus LqTer<Val,A,B,C>::post(Homehome,Ax0,Bx1,Cx2,Valc){ (void)new(home)LqTer<Val,A,B,C>(home,x0,x1,x2,c); returnES_OK; } template<classVal,classA,classB,classC> forceinline LqTer<Val,A,B,C>::LqTer(Space&home,boolshare,LqTer<Val,A,B,C>&p) :LinTer<Val,A,B,C,PC_INT_BND>(home,share,p){} template<classVal,classA,classB,classC> Actor* LqTer<Val,A,B,C>::copy(Space&home,boolshare){ returnnew(home)LqTer<Val,A,B,C>(home,share,*this); } template<classVal,classA,classB,classC> forceinline LqTer<Val,A,B,C>::LqTer(Space&home,boolshare,Propagator&p, Ax0,Bx1,Cx2,Valc) :LinTer<Val,A,B,C,PC_INT_BND>(home,share,p,x0,x1,x2,c){} template<classVal,classA,classB,classC> ExecStatus LqTer<Val,A,B,C>::propagate(Space&home,constModEventDelta&){ GECODE_ME_CHECK(x0.lq(home,c-x1.min()-x2.min())); GECODE_ME_CHECK(x1.lq(home,c-x0.min()-x2.min())); GECODE_ME_CHECK(x2.lq(home,c-x0.min()-x1.min())); return(x0.max()+x1.max()+x2.max()<=c)? home.ES_SUBSUMED(*this):ES_FIX; } }}} //STATISTICS:int-prop