clause.hpp /usr/include/gecode/int/bool.hh Gecode Gecode::Int Gecode::Int::Bool /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> * *Copyright: *ChristianSchulte,2008 * *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. * */ namespaceGecode{namespaceInt{namespaceBool{ /* *Booleanclausepropagator(disjunctive,true) * */ template<classVX,classVY> forceinline ClauseTrue<VX,VY>::ClauseTrue(Homehome, ViewArray<VX>&x0,ViewArray<VY>&y0) :MixBinaryPropagator<VX,PC_BOOL_VAL,VY,PC_BOOL_VAL> (home,x0[x0.size()-1],y0[y0.size()-1]),x(x0),y(y0){ assert((x.size()>0)&&(y.size()>0)); x.size(x.size()-1);y.size(y.size()-1); } template<classVX,classVY> PropCost ClauseTrue<VX,VY>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::binary(PropCost::LO); } template<classVX,classVY> forceinline ClauseTrue<VX,VY>::ClauseTrue(Space&home,boolshare,ClauseTrue<VX,VY>&p) :MixBinaryPropagator<VX,PC_BOOL_VAL,VY,PC_BOOL_VAL>(home,share,p){ x.update(home,share,p.x); y.update(home,share,p.y); } template<classVX,classVY> Actor* ClauseTrue<VX,VY>::copy(Space&home,boolshare){ { intn=x.size(); if(n>0){ //Eliminateallzerosandfindaone for(inti=n;i--;) if(x[i].one()){ //Onlykeeptheone x[0]=x[i];n=1;break; }elseif(x[i].zero()){ //Eliminatethezero x[i]=x[--n]; } x.size(n); } } { intn=y.size(); if(n>0){ //Eliminateallzerosandfindaone for(inti=n;i--;) if(y[i].one()){ //Onlykeeptheone y[0]=y[i];n=1;break; }elseif(y[i].zero()){ //Eliminatethezero y[i]=y[--n]; } y.size(n); } } if((x.size()==0)&&(y.size()==0)) returnnew(home)BinOrTrue<VX,VY>(home,share,*this,x0,x1); else returnnew(home)ClauseTrue<VX,VY>(home,share,*this); } template<classVX,classVY> inlineExecStatus ClauseTrue<VX,VY>::post(Homehome,ViewArray<VX>&x,ViewArray<VY>&y){ for(inti=x.size();i--;) if(x[i].one()) returnES_OK; elseif(x[i].zero()) x.move_lst(i); if(x.size()==0) returnNaryOrTrue<VY>::post(home,y); for(inti=y.size();i--;) if(y[i].one()) returnES_OK; elseif(y[i].zero()) y.move_lst(i); if(y.size()==0) returnNaryOrTrue<VX>::post(home,x); if((x.size()==1)&&(y.size()==1)){ returnBinOrTrue<VX,VY>::post(home,x[0],y[0]); }elseif(!x.shared(home,y)){ (void)new(home)ClauseTrue(home,x,y); } returnES_OK; } template<classVX,classVY> forceinlinesize_t ClauseTrue<VX,VY>::dispose(Space&home){ (void)MixBinaryPropagator<VX,PC_BOOL_VAL,VY,PC_BOOL_VAL>::dispose(home); returnsizeof(*this); } template<classVX,classVY> forceinlineExecStatus resubscribe(Space&home,Propagator&p, VX&x0,ViewArray<VX>&x, VY&x1,ViewArray<VY>&y){ if(x0.zero()){ intn=x.size(); for(inti=n;i--;) if(x[i].one()){ x.size(n); returnhome.ES_SUBSUMED(p); }elseif(x[i].zero()){ x[i]=x[--n]; }else{ //Rewriteifthereisjustoneviewleft if((i==0)&&(y.size()==0)){ VXz=x[0];x.size(0); GECODE_REWRITE(p,(BinOrTrue<VX,VY>::post(home(p),z,x1))); } //Movetox0andsubscribe x0=x[i];x[i]=x[--n]; x.size(n); x0.subscribe(home,p,PC_BOOL_VAL,false); returnES_FIX; } //Allx-viewshavebeenassigned! ViewArray<VY>z(home,y.size()+1); for(inti=y.size();i--;) z[i]=y[i]; z[y.size()]=x1; GECODE_REWRITE(p,(NaryOrTrue<VY>::post(home(p),z))); } returnES_FIX; } template<classVX,classVY> ExecStatus ClauseTrue<VX,VY>::propagate(Space&home,constModEventDelta&){ if(x0.one()||x1.one()) returnhome.ES_SUBSUMED(*this); GECODE_ES_CHECK(resubscribe(home,*this,x0,x,x1,y)); GECODE_ES_CHECK(resubscribe(home,*this,x1,y,x0,x)); returnES_FIX; } /* *Booleanclausepropagator(disjunctive) * */ /* *Indexadvisors * */ template<classVX,classVY> forceinline Clause<VX,VY>::Tagged::Tagged(Space&home,Propagator&p, Council<Tagged>&c,boolx0) :Advisor(home,p,c),x(x0){} template<classVX,classVY> forceinline Clause<VX,VY>::Tagged::Tagged(Space&home,boolshare,Tagged&a) :Advisor(home,share,a),x(a.x){} template<classVX,classVY> forceinline Clause<VX,VY>::Clause(Homehome,ViewArray<VX>&x0,ViewArray<VY>&y0, VXz0) :Propagator(home),x(x0),y(y0),z(z0),n_zero(0),c(home){ x.subscribe(home,*new(home)Tagged(home,*this,c,true)); y.subscribe(home,*new(home)Tagged(home,*this,c,false)); z.subscribe(home,*this,PC_BOOL_VAL); } template<classVX,classVY> forceinline Clause<VX,VY>::Clause(Space&home,boolshare,Clause<VX,VY>&p) :Propagator(home,share,p),n_zero(p.n_zero){ x.update(home,share,p.x); y.update(home,share,p.y); z.update(home,share,p.z); c.update(home,share,p.c); } template<classVX> forceinlinevoid eliminate_zero(ViewArray<VX>&x,int&n_zero){ if(n_zero>0){ intn=x.size(); //Eliminateallzeros for(inti=n;i--;) if(x[i].zero()){ x[i]=x[--n];n_zero--; } x.size(n); } } template<classVX,classVY> Actor* Clause<VX,VY>::copy(Space&home,boolshare){ eliminate_zero(x,n_zero); eliminate_zero(y,n_zero); returnnew(home)Clause<VX,VY>(home,share,*this); } template<classVX,classVY> inlineExecStatus Clause<VX,VY>::post(Homehome,ViewArray<VX>&x,ViewArray<VY>&y,VXz){ assert(!x.shared(home)&&!y.shared(home)); if(z.one()) returnClauseTrue<VX,VY>::post(home,x,y); if(z.zero()){ for(inti=x.size();i--;) GECODE_ME_CHECK(x[i].zero(home)); for(inti=y.size();i--;) GECODE_ME_CHECK(y[i].zero(home)); returnES_OK; } for(inti=x.size();i--;) if(x[i].one()){ GECODE_ME_CHECK(z.one_none(home)); returnES_OK; }elseif(x[i].zero()){ x.move_lst(i); } if(x.size()==0) returnNaryOr<VY,VX>::post(home,y,z); for(inti=y.size();i--;) if(y[i].one()){ GECODE_ME_CHECK(z.one_none(home)); returnES_OK; }elseif(y[i].zero()){ y.move_lst(i); } if(y.size()==0) returnNaryOr<VX,VX>::post(home,x,z); if((x.size()==1)&&(y.size()==1)){ returnOr<VX,VY,VX>::post(home,x[0],y[0],z); }elseif(x.shared(home,y)){ GECODE_ME_CHECK(z.one_none(home)); }else{ (void)new(home)Clause<VX,VY>(home,x,y,z); } returnES_OK; } template<classVX,classVY> PropCost Clause<VX,VY>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::unary(PropCost::LO); } template<classVX,classVY> forceinlinevoid Clause<VX,VY>::cancel(Space&home){ for(Advisors<Tagged>as(c);as();++as){ if(as.advisor().x) x.cancel(home,as.advisor()); else y.cancel(home,as.advisor()); as.advisor().dispose(home,c); } c.dispose(home); z.cancel(home,*this,PC_BOOL_VAL); } template<classVX,classVY> forceinlinesize_t Clause<VX,VY>::dispose(Space&home){ cancel(home); (void)Propagator::dispose(home); returnsizeof(*this); } template<classVX,classVY> ExecStatus Clause<VX,VY>::advise(Space&,Advisor&_a,constDelta&d){ Tagged&a=static_cast<Tagged&>(_a); //Decideswhetherthepropagatormustberun if((a.x&&VX::zero(d))||(!a.x&&VY::zero(d))) if(++n_zero<x.size()+y.size()) returnES_FIX; returnES_NOFIX; } template<classVX,classVY> ExecStatus Clause<VX,VY>::propagate(Space&home,constModEventDelta&){ if(z.one()) GECODE_REWRITE(*this,(ClauseTrue<VX,VY>::post(home(*this),x,y))); if(z.zero()){ for(inti=x.size();i--;) GECODE_ME_CHECK(x[i].zero(home)); for(inti=y.size();i--;) GECODE_ME_CHECK(y[i].zero(home)); c.dispose(home); }elseif(n_zero==x.size()+y.size()){ GECODE_ME_CHECK(z.zero_none(home)); c.dispose(home); }else{ //Thereisexactlyoneviewwhichisone GECODE_ME_CHECK(z.one_none(home)); } returnhome.ES_SUBSUMED(*this); } }}} //STATISTICS:int-prop