abs.hpp algorithm /usr/include/gecode/int/arithmetic.hh Gecode Gecode::Int Gecode::Int::Arithmetic /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> *GuidoTack<tack@gecode.org> * *Copyright: *ChristianSchulte,2004 *GuidoTack,2006 * *Lastmodified: *$Date:2012-09-0717:31:22+0200(Fri,07Sep2012)$by$Author:schulte$ *$Revision:13068$ * *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<algorithm> namespaceGecode{namespaceInt{namespaceArithmetic{ template<classView,template<classView0,classView1>classEq> ExecStatus prop_abs_bnd(Space&home,Propagator&p,Viewx0,Viewx1){ if(x0.assigned()){ GECODE_ME_CHECK(x1.eq(home,(x0.val()<0)?-x0.val():x0.val())); returnhome.ES_SUBSUMED(p); } if(x1.assigned()){ if(x0.min()>=0){ GECODE_ME_CHECK(x0.eq(home,x1.val())); returnhome.ES_SUBSUMED(p); }elseif(x0.max()<=0){ GECODE_ME_CHECK(x0.eq(home,-x1.val())); returnhome.ES_SUBSUMED(p); }elseif(x1.val()==0){ GECODE_ME_CHECK(x0.eq(home,0)); returnhome.ES_SUBSUMED(p); }else{ intmp[2]={-x1.val(),x1.val()}; Iter::Values::Arrayi(mp,2); GECODE_ME_CHECK(x0.inter_v(home,i,false)); returnhome.ES_SUBSUMED(p); } } if(x0.min()>=0) GECODE_REWRITE(p,(Eq<View,View>::post(home(p),x0,x1))); if(x0.max()<=0) GECODE_REWRITE(p,(Eq<MinusView,View>::post(home(p),MinusView(x0),x1))); GECODE_ME_CHECK(x1.lq(home,std::max(x0.max(),-x0.min()))); GECODE_ME_CHECK(x0.lq(home,x1.max())); GECODE_ME_CHECK(x0.gq(home,-x1.max())); returnES_NOFIX; } template<classView> forceinline AbsBnd<View>::AbsBnd(Homehome,Viewx0,Viewx1) :BinaryPropagator<View,PC_INT_BND>(home,x0,x1){} template<classView> ExecStatus AbsBnd<View>::post(Homehome,Viewx0,Viewx1){ if(x0.min()>=0){ returnRel::EqBnd<View,View>::post(home,x0,x1); }elseif(x0.max()<=0){ returnRel::EqBnd<MinusView,View>::post(home,MinusView(x0),x1); }else{ assert(!x0.assigned()); GECODE_ME_CHECK(x1.gq(home,0)); if(x1.assigned()){ intmp[2]={-x1.val(),x1.val()}; Iter::Values::Arrayi(mp,2); GECODE_ME_CHECK(x0.inter_v(home,i,false)); }elseif(!same(x0,x1)){ GECODE_ME_CHECK(x1.lq(home,std::max(-x0.min(),x0.max()))); (void)new(home)AbsBnd<View>(home,x0,x1); } } returnES_OK; } template<classView> forceinline AbsBnd<View>::AbsBnd(Space&home,boolshare,AbsBnd<View>&p) :BinaryPropagator<View,PC_INT_BND>(home,share,p){} template<classView> Actor* AbsBnd<View>::copy(Space&home,boolshare){ returnnew(home)AbsBnd<View>(home,share,*this); } template<classView> PropCost AbsBnd<View>::cost(constSpace&,constModEventDelta&med)const{ if(View::me(med)==ME_INT_VAL) returnPropCost::unary(PropCost::LO); else returnPropCost::binary(PropCost::LO); } template<classView> ExecStatus AbsBnd<View>::propagate(Space&home,constModEventDelta&){ returnprop_abs_bnd<View,Rel::EqBnd>(home,*this,x0,x1); } template<classView> forceinline AbsDom<View>::AbsDom(Homehome,Viewx0,Viewx1) :BinaryPropagator<View,PC_INT_DOM>(home,x0,x1){} template<classView> ExecStatus AbsDom<View>::post(Homehome,Viewx0,Viewx1){ if(x0.min()>=0){ returnRel::EqDom<View,View>::post(home,x0,x1); }elseif(x0.max()<=0){ returnRel::EqDom<MinusView,View>::post(home,MinusView(x0),x1); }else{ assert(!x0.assigned()); GECODE_ME_CHECK(x1.gq(home,0)); if(x1.assigned()){ intmp[2]={-x1.val(),x1.val()}; Iter::Values::Arrayi(mp,2); GECODE_ME_CHECK(x0.inter_v(home,i,false)); }elseif(!same(x0,x1)){ GECODE_ME_CHECK(x1.lq(home,std::max(-x0.min(),x0.max()))); (void)new(home)AbsDom<View>(home,x0,x1); } } returnES_OK; } template<classView> forceinline AbsDom<View>::AbsDom(Space&home,boolshare,AbsDom<View>&p) :BinaryPropagator<View,PC_INT_DOM>(home,share,p){} template<classView> Actor* AbsDom<View>::copy(Space&home,boolshare){ returnnew(home)AbsDom<View>(home,share,*this); } template<classView> PropCost AbsDom<View>::cost(constSpace&,constModEventDelta&med)const{ if(View::me(med)==ME_INT_VAL) returnPropCost::unary(PropCost::LO); else returnPropCost::binary((View::me(med)==ME_INT_DOM)? PropCost::HI:PropCost::LO); } template<classView> ExecStatus AbsDom<View>::propagate(Space&home,constModEventDelta&med){ if(View::me(med)!=ME_INT_DOM){ GECODE_ES_CHECK((prop_abs_bnd<View,Rel::EqDom>(home,*this,x0,x1))); returnhome.ES_NOFIX_PARTIAL(*this,View::med(ME_INT_DOM)); } Regionr(home); { ViewRanges<View>i(x0),j(x0); usingnamespaceIter::Ranges; Positive<ViewRanges<View>>p(i); Negative<ViewRanges<View>>n(j); Minusm(r,n); Union<Positive<ViewRanges<View>>,Minus>u(p,m); GECODE_ME_CHECK(x1.inter_r(home,u,false)); } { ViewRanges<View>i(x1),j(x1); usingnamespaceIter::Ranges; Minusm(r,j); Union<ViewRanges<View>,Minus>u(i,m); GECODE_ME_CHECK(x0.inter_r(home,u,false)); } if(x1.assigned()) returnhome.ES_SUBSUMED(*this); if(x0.min()>=0) GECODE_REWRITE(*this,(Rel::EqDom<View,View>::post(home(*this),x0,x1))); if(x0.max()<=0){ MinusViewmx0(x0); GECODE_REWRITE(*this,(Rel::EqDom<MinusView,View>::post(home(*this),mx0,x1))); } returnES_FIX; } }}} //STATISTICS:int-prop