int-nary.hpp gecode/int/linear/int-noview.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,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. * */ #include<gecode/int/linear/int-noview.hpp> namespaceGecode{namespaceInt{namespaceLinear{ template<classP,classN> forceinlinebool isunit(ViewArray<P>&,ViewArray<N>&){returnfalse;} template<> forceinlinebool isunit(ViewArray<IntView>&,ViewArray<IntView>&){returntrue;} template<> forceinlinebool isunit(ViewArray<IntView>&,ViewArray<NoView>&){returntrue;} template<> forceinlinebool isunit(ViewArray<NoView>&,ViewArray<IntView>&){returntrue;} /* *Linearpropagators * */ template<classVal,classP,classN,PropCondpc> forceinline Lin<Val,P,N,pc>::Lin(Homehome,ViewArray<P>&x0,ViewArray<N>&y0,Valc0) :Propagator(home),x(x0),y(y0),c(c0){ x.subscribe(home,*this,pc); y.subscribe(home,*this,pc); } template<classVal,classP,classN,PropCondpc> forceinline Lin<Val,P,N,pc>::Lin(Space&home,boolshare,Lin<Val,P,N,pc>&p) :Propagator(home,share,p),c(p.c){ x.update(home,share,p.x); y.update(home,share,p.y); } template<classVal,classP,classN,PropCondpc> PropCost Lin<Val,P,N,pc>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::linear(PropCost::LO,x.size()+y.size()); } template<classVal,classP,classN,PropCondpc> forceinlinesize_t Lin<Val,P,N,pc>::dispose(Space&home){ x.cancel(home,*this,pc); y.cancel(home,*this,pc); (void)Propagator::dispose(home); returnsizeof(*this); } /* *Reifiedlinearpropagators * */ template<classVal,classP,classN,PropCondpc,classCtrl> forceinline ReLin<Val,P,N,pc,Ctrl>::ReLin (Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc,Ctrlb0) :Lin<Val,P,N,pc>(home,x,y,c),b(b0){ b.subscribe(home,*this,PC_INT_VAL); } template<classVal,classP,classN,PropCondpc,classCtrl> forceinline ReLin<Val,P,N,pc,Ctrl>::ReLin (Space&home,boolshare,ReLin<Val,P,N,pc,Ctrl>&p) :Lin<Val,P,N,pc>(home,share,p){ b.update(home,share,p.b); } template<classVal,classP,classN,PropCondpc,classCtrl> forceinlinesize_t ReLin<Val,P,N,pc,Ctrl>::dispose(Space&home){ b.cancel(home,*this,PC_BOOL_VAL); (void)Lin<Val,P,N,pc>::dispose(home); returnsizeof(*this); } /* *Computingbounds * */ template<classVal,classView> void bounds_p(ModEventDeltamed,ViewArray<View>&x,Val&c,Val&sl,Val&su){ intn=x.size(); if(IntView::me(med)==ME_INT_VAL){ for(inti=n;i--;){ Valm=x[i].min(); if(x[i].assigned()){ c-=m;x[i]=x[--n]; }else{ sl-=m;su-=x[i].max(); } } x.size(n); }else{ for(inti=n;i--;){ sl-=x[i].min();su-=x[i].max(); } } } template<classVal,classView> void bounds_n(ModEventDeltamed,ViewArray<View>&y,Val&c,Val&sl,Val&su){ intn=y.size(); if(IntView::me(med)==ME_INT_VAL){ for(inti=n;i--;){ Valm=y[i].max(); if(y[i].assigned()){ c+=m;y[i]=y[--n]; }else{ sl+=m;su+=y[i].min(); } } y.size(n); }else{ for(inti=n;i--;){ sl+=y[i].max();su+=y[i].min(); } } } template<classVal,classP,classN> ExecStatus prop_bnd(Space&home,ModEventDeltamed,Propagator&p, ViewArray<P>&x,ViewArray<N>&y,Val&c){ //Eliminatesingletons Valsl=0; Valsu=0; bounds_p<Val,P>(med,x,c,sl,su); bounds_n<Val,N>(med,y,c,sl,su); if((IntView::me(med)==ME_INT_VAL)&&((x.size()+y.size())<=1)){ if(x.size()==1){ GECODE_ME_CHECK(x[0].eq(home,c)); returnhome.ES_SUBSUMED(p); } if(y.size()==1){ GECODE_ME_CHECK(y[0].eq(home,-c)); returnhome.ES_SUBSUMED(p); } return(c==static_cast<Val>(0))? home.ES_SUBSUMED(p):ES_FAILED; } sl+=c;su+=c; constintmod_sl=1; constintmod_su=2; intmod=mod_sl|mod_su; do{ if(mod&mod_sl){ mod-=mod_sl; //Propagateupperboundforpositivevariables for(inti=x.size();i--;){ constValxi_max=x[i].max(); ModEventme=x[i].lq(home,sl+x[i].min()); if(me_failed(me)) returnES_FAILED; if(me_modified(me)){ su+=xi_max-x[i].max(); mod|=mod_su; } } //Propagatelowerboundfornegativevariables for(inti=y.size();i--;){ constValyi_min=y[i].min(); ModEventme=y[i].gq(home,y[i].max()-sl); if(me_failed(me)) returnES_FAILED; if(me_modified(me)){ su+=y[i].min()-yi_min; mod|=mod_su; } } } if(mod&mod_su){ mod-=mod_su; //Propagatelowerboundforpositivevariables for(inti=x.size();i--;){ constValxi_min=x[i].min(); ModEventme=x[i].gq(home,su+x[i].max()); if(me_failed(me)) returnES_FAILED; if(me_modified(me)){ sl+=xi_min-x[i].min(); mod|=mod_sl; } } //Propagateupperboundfornegativevariables for(inti=y.size();i--;){ constValyi_max=y[i].max(); ModEventme=y[i].lq(home,y[i].min()-su); if(me_failed(me)) returnES_FAILED; if(me_modified(me)){ sl+=y[i].max()-yi_max; mod|=mod_sl; } } } }while(mod); return(sl==su)?home.ES_SUBSUMED(p):ES_FIX; } /* *Boundconsistentlinearequation * */ template<classVal,classP,classN> forceinline Eq<Val,P,N>::Eq(Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc) :Lin<Val,P,N,PC_INT_BND>(home,x,y,c){} template<classVal,classP,classN> ExecStatus Eq<Val,P,N>::post(Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc){ ViewArray<NoView>nva; if(y.size()==0){ (void)new(home)Eq<Val,P,NoView>(home,x,nva,c); }elseif(x.size()==0){ (void)new(home)Eq<Val,N,NoView>(home,y,nva,-c); }else{ (void)new(home)Eq<Val,P,N>(home,x,y,c); } returnES_OK; } template<classVal,classP,classN> forceinline Eq<Val,P,N>::Eq(Space&home,boolshare,Eq<Val,P,N>&p) :Lin<Val,P,N,PC_INT_BND>(home,share,p){} template<classVal,classP,classN> forceinlineActor* eqtobin(Space&,bool,Propagator&,ViewArray<P>&,ViewArray<N>&,Val){ returnNULL; } template<classVal> forceinlineActor* eqtobin(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<NoView>&,Valc){ assert(x.size()==2); returnnew(home)EqBin<Val,IntView,IntView> (home,share,p,x[0],x[1],c); } template<classVal> forceinlineActor* eqtobin(Space&home,boolshare,Propagator&p, ViewArray<NoView>&,ViewArray<IntView>&y,Valc){ assert(y.size()==2); returnnew(home)EqBin<Val,IntView,IntView> (home,share,p,y[0],y[1],-c); } template<classVal> forceinlineActor* eqtobin(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<IntView>&y,Valc){ if(x.size()==2) returnnew(home)EqBin<Val,IntView,IntView> (home,share,p,x[0],x[1],c); if(x.size()==1) returnnew(home)EqBin<Val,IntView,MinusView> (home,share,p,x[0],MinusView(y[0]),c); returnnew(home)EqBin<Val,IntView,IntView> (home,share,p,y[0],y[1],-c); } template<classVal,classP,classN> forceinlineActor* eqtoter(Space&,bool,Propagator&,ViewArray<P>&,ViewArray<N>&,Val){ returnNULL; } template<classVal> forceinlineActor* eqtoter(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<NoView>&,Valc){ assert(x.size()==3); returnnew(home)EqTer<Val,IntView,IntView,IntView> (home,share,p,x[0],x[1],x[2],c); } template<classVal> forceinlineActor* eqtoter(Space&home,boolshare,Propagator&p, ViewArray<NoView>&,ViewArray<IntView>&y,Valc){ assert(y.size()==3); returnnew(home)EqTer<Val,IntView,IntView,IntView> (home,share,p,y[0],y[1],y[2],-c); } template<classVal> forceinlineActor* eqtoter(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<IntView>&y,Valc){ if(x.size()==3) returnnew(home)EqTer<Val,IntView,IntView,IntView> (home,share,p,x[0],x[1],x[2],c); if(x.size()==2) returnnew(home)EqTer<Val,IntView,IntView,MinusView> (home,share,p,x[0],x[1],MinusView(y[0]),c); if(x.size()==1) returnnew(home)EqTer<Val,IntView,IntView,MinusView> (home,share,p,y[0],y[1],MinusView(x[0]),-c); returnnew(home)EqTer<Val,IntView,IntView,IntView> (home,share,p,y[0],y[1],y[2],-c); } template<classVal,classP,classN> Actor* Eq<Val,P,N>::copy(Space&home,boolshare){ if(isunit(x,y)){ //Checkwhetherrewritingispossible if(x.size()+y.size()==2) returneqtobin(home,share,*this,x,y,c); if(x.size()+y.size()==3) returneqtoter(home,share,*this,x,y,c); } returnnew(home)Eq<Val,P,N>(home,share,*this); } template<classVal,classP,classN> ExecStatus Eq<Val,P,N>::propagate(Space&home,constModEventDelta&med){ returnprop_bnd<Val,P,N>(home,med,*this,x,y,c); } /* *Reifiedboundconsistentlinearequation * */ template<classVal,classP,classN,classCtrl,ReifyModerm> forceinline ReEq<Val,P,N,Ctrl,rm>::ReEq(Homehome, ViewArray<P>&x,ViewArray<N>&y,Valc,Ctrlb) :ReLin<Val,P,N,PC_INT_BND,Ctrl>(home,x,y,c,b){} template<classVal,classP,classN,classCtrl,ReifyModerm> ExecStatus ReEq<Val,P,N,Ctrl,rm>::post(Homehome, ViewArray<P>&x,ViewArray<N>&y,Valc,Ctrlb){ ViewArray<NoView>nva; if(y.size()==0){ (void)new(home)ReEq<Val,P,NoView,Ctrl,rm>(home,x,nva,c,b); }elseif(x.size()==0){ (void)new(home)ReEq<Val,N,NoView,Ctrl,rm>(home,y,nva,-c,b); }else{ (void)new(home)ReEq<Val,P,N,Ctrl,rm>(home,x,y,c,b); } returnES_OK; } template<classVal,classP,classN,classCtrl,ReifyModerm> forceinline ReEq<Val,P,N,Ctrl,rm>::ReEq(Space&home,boolshare, ReEq<Val,P,N,Ctrl,rm>&p) :ReLin<Val,P,N,PC_INT_BND,Ctrl>(home,share,p){} template<classVal,classP,classN,classCtrl,ReifyModerm> Actor* ReEq<Val,P,N,Ctrl,rm>::copy(Space&home,boolshare){ returnnew(home)ReEq<Val,P,N,Ctrl,rm>(home,share,*this); } template<classVal,classP,classN,classCtrl,ReifyModerm> ExecStatus ReEq<Val,P,N,Ctrl,rm>::propagate(Space&home,constModEventDelta&med){ if(b.zero()){ if(rm==RM_IMP) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(Nq<Val,P,N>::post(home(*this),x,y,c))); } if(b.one()){ if(rm==RM_PMI) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(Eq<Val,P,N>::post(home(*this),x,y,c))); } Valsl=0; Valsu=0; bounds_p<Val,P>(med,x,c,sl,su); bounds_n<Val,N>(med,y,c,sl,su); if((-sl==c)&&(-su==c)){ if(rm!=RM_IMP) GECODE_ME_CHECK(b.one_none(home)); returnhome.ES_SUBSUMED(*this); } if((-sl>c)||(-su<c)){ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero_none(home)); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } /* *Domainconsistentlineardisequation * */ template<classVal,classP,classN> forceinline Nq<Val,P,N>::Nq(Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc) :Lin<Val,P,N,PC_INT_VAL>(home,x,y,c){} template<classVal,classP,classN> ExecStatus Nq<Val,P,N>::post(Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc){ ViewArray<NoView>nva; if(y.size()==0){ (void)new(home)Nq<Val,P,NoView>(home,x,nva,c); }elseif(x.size()==0){ (void)new(home)Nq<Val,N,NoView>(home,y,nva,-c); }else{ (void)new(home)Nq<Val,P,N>(home,x,y,c); } returnES_OK; } template<classVal,classP,classN> forceinline Nq<Val,P,N>::Nq(Space&home,boolshare,Nq<Val,P,N>&p) :Lin<Val,P,N,PC_INT_VAL>(home,share,p){} template<classVal,classP,classN> forceinlineActor* nqtobin(Space&,bool,Propagator&,ViewArray<P>&,ViewArray<N>&,Val){ returnNULL; } template<classVal> forceinlineActor* nqtobin(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<NoView>&,Valc){ assert(x.size()==2); returnnew(home)NqBin<Val,IntView,IntView> (home,share,p,x[0],x[1],c); } template<classVal> forceinlineActor* nqtobin(Space&home,boolshare,Propagator&p, ViewArray<NoView>&,ViewArray<IntView>&y,Valc){ assert(y.size()==2); returnnew(home)NqBin<Val,IntView,IntView> (home,share,p,y[0],y[1],-c); } template<classVal> forceinlineActor* nqtobin(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<IntView>&y,Valc){ if(x.size()==2) returnnew(home)NqBin<Val,IntView,IntView> (home,share,p,x[0],x[1],c); if(x.size()==1) returnnew(home)NqBin<Val,IntView,MinusView> (home,share,p,x[0],MinusView(y[0]),c); returnnew(home)NqBin<Val,IntView,IntView> (home,share,p,y[0],y[1],-c); } template<classVal,classP,classN> forceinlineActor* nqtoter(Space&,bool,Propagator&,ViewArray<P>&,ViewArray<N>&,Val){ returnNULL; } template<classVal> forceinlineActor* nqtoter(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<NoView>&,Valc){ assert(x.size()==3); returnnew(home)NqTer<Val,IntView,IntView,IntView> (home,share,p,x[0],x[1],x[2],c); } template<classVal> forceinlineActor* nqtoter(Space&home,boolshare,Propagator&p, ViewArray<NoView>&,ViewArray<IntView>&y,Valc){ assert(y.size()==3); returnnew(home)NqTer<Val,IntView,IntView,IntView> (home,share,p,y[0],y[1],y[2],-c); } template<classVal> forceinlineActor* nqtoter(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<IntView>&y,Valc){ if(x.size()==3) returnnew(home)NqTer<Val,IntView,IntView,IntView> (home,share,p,x[0],x[1],x[2],c); if(x.size()==2) returnnew(home)NqTer<Val,IntView,IntView,MinusView> (home,share,p,x[0],x[1],MinusView(y[0]),c); if(x.size()==1) returnnew(home)NqTer<Val,IntView,IntView,MinusView> (home,share,p,y[0],y[1],MinusView(x[0]),-c); returnnew(home)NqTer<Val,IntView,IntView,IntView> (home,share,p,y[0],y[1],y[2],-c); } template<classVal,classP,classN> Actor* Nq<Val,P,N>::copy(Space&home,boolshare){ if(isunit(x,y)){ //Checkwhetherrewritingispossible if(x.size()+y.size()==2) returnnqtobin(home,share,*this,x,y,c); if(x.size()+y.size()==3) returnnqtoter(home,share,*this,x,y,c); } returnnew(home)Nq<Val,P,N>(home,share,*this); } template<classVal,classP,classN> ExecStatus Nq<Val,P,N>::propagate(Space&home,constModEventDelta&){ for(inti=x.size();i--;) if(x[i].assigned()){ c-=x[i].val();x.move_lst(i); } for(inti=y.size();i--;) if(y[i].assigned()){ c+=y[i].val();y.move_lst(i); } if(x.size()+y.size()<=1){ if(x.size()==1){ GECODE_ME_CHECK(x[0].nq(home,c));returnhome.ES_SUBSUMED(*this); } if(y.size()==1){ GECODE_ME_CHECK(y[0].nq(home,-c));returnhome.ES_SUBSUMED(*this); } return(c==static_cast<Val>(0))? ES_FAILED:home.ES_SUBSUMED(*this); } returnES_FIX; } /* *Boundconsistentlinearinequation * */ template<classVal,classP,classN> forceinline Lq<Val,P,N>::Lq(Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc) :Lin<Val,P,N,PC_INT_BND>(home,x,y,c){} template<classVal,classP,classN> ExecStatus Lq<Val,P,N>::post(Homehome,ViewArray<P>&x,ViewArray<N>&y,Valc){ ViewArray<NoView>nva; if(y.size()==0){ (void)new(home)Lq<Val,P,NoView>(home,x,nva,c); }elseif(x.size()==0){ (void)new(home)Lq<Val,NoView,N>(home,nva,y,c); }else{ (void)new(home)Lq<Val,P,N>(home,x,y,c); } returnES_OK; } template<classVal,classP,classN> forceinline Lq<Val,P,N>::Lq(Space&home,boolshare,Lq<Val,P,N>&p) :Lin<Val,P,N,PC_INT_BND>(home,share,p){} template<classVal,classP,classN> forceinlineActor* lqtobin(Space&,bool,Propagator&,ViewArray<P>&,ViewArray<N>&,Val){ returnNULL; } template<classVal> forceinlineActor* lqtobin(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<NoView>&,Valc){ assert(x.size()==2); returnnew(home)LqBin<Val,IntView,IntView> (home,share,p,x[0],x[1],c); } template<classVal> forceinlineActor* lqtobin(Space&home,boolshare,Propagator&p, ViewArray<NoView>&,ViewArray<IntView>&y,Valc){ assert(y.size()==2); returnnew(home)LqBin<Val,MinusView,MinusView> (home,share,p,MinusView(y[0]),MinusView(y[1]),c); } template<classVal> forceinlineActor* lqtobin(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<IntView>&y,Valc){ if(x.size()==2) returnnew(home)LqBin<Val,IntView,IntView> (home,share,p,x[0],x[1],c); if(x.size()==1) returnnew(home)LqBin<Val,IntView,MinusView> (home,share,p,x[0],MinusView(y[0]),c); returnnew(home)LqBin<Val,MinusView,MinusView> (home,share,p,MinusView(y[0]),MinusView(y[1]),c); } template<classVal,classP,classN> forceinlineActor* lqtoter(Space&,bool,Propagator&,ViewArray<P>&,ViewArray<N>&,Val){ returnNULL; } template<classVal> forceinlineActor* lqtoter(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<NoView>&,Valc){ assert(x.size()==3); returnnew(home)LqTer<Val,IntView,IntView,IntView> (home,share,p,x[0],x[1],x[2],c); } template<classVal> forceinlineActor* lqtoter(Space&home,boolshare,Propagator&p, ViewArray<NoView>&,ViewArray<IntView>&y,Valc){ assert(y.size()==3); returnnew(home)LqTer<Val,MinusView,MinusView,MinusView> (home,share,p,MinusView(y[0]),MinusView(y[1]),MinusView(y[2]),c); } template<classVal> forceinlineActor* lqtoter(Space&home,boolshare,Propagator&p, ViewArray<IntView>&x,ViewArray<IntView>&y,Valc){ if(x.size()==3) returnnew(home)LqTer<Val,IntView,IntView,IntView> (home,share,p,x[0],x[1],x[2],c); if(x.size()==2) returnnew(home)LqTer<Val,IntView,IntView,MinusView> (home,share,p,x[0],x[1],MinusView(y[0]),c); if(x.size()==1) returnnew(home)LqTer<Val,IntView,MinusView,MinusView> (home,share,p,x[0],MinusView(y[0]),MinusView(y[1]),c); returnnew(home)LqTer<Val,MinusView,MinusView,MinusView> (home,share,p,MinusView(y[0]),MinusView(y[1]),MinusView(y[2]),c); } template<classVal,classP,classN> Actor* Lq<Val,P,N>::copy(Space&home,boolshare){ if(isunit(x,y)){ //Checkwhetherrewritingispossible if(x.size()+y.size()==2) returnlqtobin(home,share,*this,x,y,c); if(x.size()+y.size()==3) returnlqtoter(home,share,*this,x,y,c); } returnnew(home)Lq<Val,P,N>(home,share,*this); } template<classVal,classP,classN> ExecStatus Lq<Val,P,N>::propagate(Space&home,constModEventDelta&med){ //Eliminatesingletons Valsl=0; if(IntView::me(med)==ME_INT_VAL){ for(inti=x.size();i--;){ Valm=x[i].min(); if(x[i].assigned()){ c-=m;x.move_lst(i); }else{ sl-=m; } } for(inti=y.size();i--;){ Valm=y[i].max(); if(y[i].assigned()){ c+=m;y.move_lst(i); }else{ sl+=m; } } if((x.size()+y.size())<=1){ if(x.size()==1){ GECODE_ME_CHECK(x[0].lq(home,c)); returnhome.ES_SUBSUMED(*this); } if(y.size()==1){ GECODE_ME_CHECK(y[0].gq(home,-c)); returnhome.ES_SUBSUMED(*this); } return(c>=static_cast<Val>(0))? home.ES_SUBSUMED(*this):ES_FAILED; } }else{ for(inti=x.size();i--;) sl-=x[i].min(); for(inti=y.size();i--;) sl+=y[i].max(); } sl+=c; ExecStatuses=ES_FIX; boolassigned=true; for(inti=x.size();i--;){ assert(!x[i].assigned()); Valslx=sl+x[i].min(); ModEventme=x[i].lq(home,slx); if(me==ME_INT_FAILED) returnES_FAILED; if(me!=ME_INT_VAL) assigned=false; if(me_modified(me)&&(slx!=x[i].max())) es=ES_NOFIX; } for(inti=y.size();i--;){ assert(!y[i].assigned()); Valsly=y[i].max()-sl; ModEventme=y[i].gq(home,sly); if(me==ME_INT_FAILED) returnES_FAILED; if(me!=ME_INT_VAL) assigned=false; if(me_modified(me)&&(sly!=y[i].min())) es=ES_NOFIX; } returnassigned?home.ES_SUBSUMED(*this):es; } /* *Reifiedboundconsistentlinearinequation * */ template<classVal,classP,classN,ReifyModerm> forceinline ReLq<Val,P,N,rm>::ReLq(Homehome, ViewArray<P>&x,ViewArray<N>&y,Valc,BoolViewb) :ReLin<Val,P,N,PC_INT_BND,BoolView>(home,x,y,c,b){} template<classVal,classP,classN,ReifyModerm> ExecStatus ReLq<Val,P,N,rm>::post(Homehome, ViewArray<P>&x,ViewArray<N>&y,Valc,BoolViewb){ ViewArray<NoView>nva; if(y.size()==0){ (void)new(home)ReLq<Val,P,NoView,rm>(home,x,nva,c,b); }elseif(x.size()==0){ (void)new(home)ReLq<Val,NoView,N,rm>(home,nva,y,c,b); }else{ (void)new(home)ReLq<Val,P,N,rm>(home,x,y,c,b); } returnES_OK; } template<classVal,classP,classN,ReifyModerm> forceinline ReLq<Val,P,N,rm>::ReLq(Space&home,boolshare,ReLq<Val,P,N,rm>&p) :ReLin<Val,P,N,PC_INT_BND,BoolView>(home,share,p){} template<classVal,classP,classN,ReifyModerm> Actor* ReLq<Val,P,N,rm>::copy(Space&home,boolshare){ returnnew(home)ReLq<Val,P,N,rm>(home,share,*this); } template<classVal,classP,classN,ReifyModerm> ExecStatus ReLq<Val,P,N,rm>::propagate(Space&home,constModEventDelta&med){ if(b.zero()){ if(rm==RM_IMP) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(Lq<Val,N,P>::post(home(*this),y,x,-c-1))); } if(b.one()){ if(rm==RM_PMI) returnhome.ES_SUBSUMED(*this); GECODE_REWRITE(*this,(Lq<Val,P,N>::post(home(*this),x,y,c))); } //Eliminatesingletons Valsl=0; Valsu=0; bounds_p<Val,P>(med,x,c,sl,su); bounds_n<Val,N>(med,y,c,sl,su); if(-sl>c){ if(rm!=RM_PMI) GECODE_ME_CHECK(b.zero_none(home)); returnhome.ES_SUBSUMED(*this); } if(-su<=c){ if(rm!=RM_IMP) GECODE_ME_CHECK(b.one_none(home)); returnhome.ES_SUBSUMED(*this); } returnES_FIX; } }}} //STATISTICS:int-prop