layered-graph.hpp climits algorithm /usr/include/gecode/int/extensional.hh Gecode::Int::Extensional::VarTraits Gecode::Int::Extensional::VarTraits< IntVar > Gecode::Int::Extensional::VarTraits< BoolVar > Gecode Gecode::Int Gecode::Int::Extensional /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> * *Copyright: *ChristianSchulte,2004 * *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<climits> #include<algorithm> namespaceGecode{namespaceInt{namespaceExtensional{ template<classVar> classVarTraits{}; template<> classVarTraits<IntVar>{ public: typedefInt::IntViewView; }; template<> classVarTraits<BoolVar>{ public: typedefInt::BoolViewView; }; /* *States */ template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::State::init(void){ i_deg=o_deg=0; } template<classView,classVal,classDegree,classStateIdx> forceinlinetypenameLayeredGraph<View,Val,Degree,StateIdx>::State& LayeredGraph<View,Val,Degree,StateIdx>::i_state(inti,StateIdxis){ returnlayers[i].states[is]; } template<classView,classVal,classDegree,classStateIdx> forceinlinetypenameLayeredGraph<View,Val,Degree,StateIdx>::State& LayeredGraph<View,Val,Degree,StateIdx>::i_state (inti,consttypenameLayeredGraph<View,Val,Degree,StateIdx>::Edge&e){ returni_state(i,e.i_state); } template<classView,classVal,classDegree,classStateIdx> forceinlinebool LayeredGraph<View,Val,Degree,StateIdx>::i_dec (inti,consttypenameLayeredGraph<View,Val,Degree,StateIdx>::Edge&e){ return--i_state(i,e).o_deg==0; } template<classView,classVal,classDegree,classStateIdx> forceinlinetypenameLayeredGraph<View,Val,Degree,StateIdx>::State& LayeredGraph<View,Val,Degree,StateIdx>::o_state(inti,StateIdxos){ returnlayers[i+1].states[os]; } template<classView,classVal,classDegree,classStateIdx> forceinlinetypenameLayeredGraph<View,Val,Degree,StateIdx>::State& LayeredGraph<View,Val,Degree,StateIdx>::o_state (inti,consttypenameLayeredGraph<View,Val,Degree,StateIdx>::Edge&e){ returno_state(i,e.o_state); } template<classView,classVal,classDegree,classStateIdx> forceinlinebool LayeredGraph<View,Val,Degree,StateIdx>::o_dec (inti,consttypenameLayeredGraph<View,Val,Degree,StateIdx>::Edge&e){ return--o_state(i,e).i_deg==0; } /* *Valueiterator */ template<classView,classVal,classDegree,classStateIdx> forceinline LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::LayerValues(void){} template<classView,classVal,classDegree,classStateIdx> forceinline LayeredGraph<View,Val,Degree,StateIdx>::LayerValues ::LayerValues(constLayer&l) :s1(l.support),s2(l.support+l.size){} template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::init(constLayer&l){ s1=l.support;s2=l.support+l.size; } template<classView,classVal,classDegree,classStateIdx> forceinlinebool LayeredGraph<View,Val,Degree,StateIdx>::LayerValues ::operator ()(void)const{ returns1<s2; } template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::operator ++(void){ s1++; } template<classView,classVal,classDegree,classStateIdx> forceinlineint LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::val(void)const{ returns1->val; } /* *Indexadvisors * */ template<classView,classVal,classDegree,classStateIdx> forceinline LayeredGraph<View,Val,Degree,StateIdx>::Index::Index(Space&home,Propagator&p, Council<Index>&c, inti0) :Advisor(home,p,c),i(i0){} template<classView,classVal,classDegree,classStateIdx> forceinline LayeredGraph<View,Val,Degree,StateIdx>::Index::Index(Space&home,boolshare, Index&a) :Advisor(home,share,a),i(a.i){} /* *Indexranges * */ template<classView,classVal,classDegree,classStateIdx> forceinline LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::IndexRange(void) :_fst(INT_MAX),_lst(INT_MIN){} template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::reset(void){ _fst=INT_MAX;_lst=INT_MIN; } template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::add(inti){ _fst=std::min(_fst,i);_lst=std::max(_lst,i); } template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::add (consttypenameLayeredGraph<View,Val,Degree,StateIdx>::IndexRange&ir){ _fst=std::min(_fst,ir._fst);_lst=std::max(_lst,ir._lst); } template<classView,classVal,classDegree,classStateIdx> forceinlinebool LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::empty(void)const{ return_fst>_lst; } template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::lshift(intn){ if(empty()) return; if(n>_lst){ reset(); }else{ _fst=std::max(0,_fst-n); _lst-=n; } } template<classView,classVal,classDegree,classStateIdx> forceinlineint LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::fst(void)const{ return_fst; } template<classView,classVal,classDegree,classStateIdx> forceinlineint LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::lst(void)const{ return_lst; } /* *Thelayeredgraph * */ template<classView,classVal,classDegree,classStateIdx> template<classVar> forceinline LayeredGraph<View,Val,Degree,StateIdx>::LayeredGraph(Homehome, constVarArgArray<Var>&x, constDFA&dfa) :Propagator(home),c(home),n(x.size()), max_states(static_cast<StateIdx>(dfa.n_states())){ assert(n>0); } template<classView,classVal,classDegree,classStateIdx> forceinlinevoid LayeredGraph<View,Val,Degree,StateIdx>::audit(void){ #ifdefGECODE_AUDIT //Checkstatesandedgeinformationtobeconsistent unsignedintn_e=0;//Numberofedges unsignedintn_s=0;//Numberofstates StateIdxm_s=0;//Maximalnumberofstatesperlayer for(inti=n;i--;){ n_s+=layers[i].n_states; m_s=std::max(m_s,layers[i].n_states); for(ValSizej=layers[i].size;j--;) n_e+=layers[i].support[j].n_edges; } n_s+=layers[n].n_states; m_s=std::max(m_s,layers[n].n_states); assert(n_e==n_edges); assert(n_s<=n_states); assert(m_s<=max_states); #endif } template<classView,classVal,classDegree,classStateIdx> template<classVar> forceinlineExecStatus LayeredGraph<View,Val,Degree,StateIdx>::initialize(Space&home, constVarArgArray<Var>&x, constDFA&dfa){ Regionr(home); //Allocatememoryforlayers layers=home.alloc<Layer>(n+1); //Allocatetemporarymemoryforallpossiblestates State*states=r.alloc<State>(max_states*(n+1)); for(inti=static_cast<int>(max_states)*(n+1);i--;) states[i].init(); for(inti=n+1;i--;) layers[i].states=states+i*max_states; //Allocatetemporarymemoryforedges Edge*edges=r.alloc<Edge>(dfa.max_degree()); //Markinitialstateasbeingreachable i_state(0,0).i_deg=1; //Forwardpass:addtransitions for(inti=0;i<n;i++){ layers[i].x=x[i]; layers[i].support=home.alloc<Support>(layers[i].x.size()); ValSizej=0; //Enterlinksleavingreachablestates(indegree!=0) for(ViewValues<View>nx(layers[i].x);nx();++nx){ Degreen_edges=0; for(DFA::Transitionst(dfa,nx.val());t();++t) if(i_state(i,static_cast<StateIdx>(t.i_state())).i_deg!=0){ i_state(i,static_cast<StateIdx>(t.i_state())).o_deg++; o_state(i,static_cast<StateIdx>(t.o_state())).i_deg++; edges[n_edges].i_state=static_cast<StateIdx>(t.i_state()); edges[n_edges].o_state=static_cast<StateIdx>(t.o_state()); n_edges++; } assert(n_edges<=dfa.max_degree()); //Foundsupportforvalue if(n_edges>0){ Support&s=layers[i].support[j]; s.val=static_cast<Val>(nx.val()); s.n_edges=n_edges; s.edges=Heap::copy(home.alloc<Edge>(n_edges),edges,n_edges); j++; } } if((layers[i].size=j)==0) returnES_FAILED; } //Markfinalstatesasreachable for(ints=dfa.final_fst();s<dfa.final_lst();s++) if(o_state(n-1,static_cast<StateIdx>(s)).i_deg!=0) o_state(n-1,static_cast<StateIdx>(s)).o_deg=1; //Backwardpass:prunealltransitionsthatdonotleadtofinalstate for(inti=n;i--;){ ValSizek=0; for(ValSizej=0;j<layers[i].size;j++){ Support&s=layers[i].support[j]; for(Degreed=s.n_edges;d--;) if(o_state(i,s.edges[d]).o_deg==0){ //Adaptstates i_dec(i,s.edges[d]);o_dec(i,s.edges[d]); //Pruneedge s.edges[d]=s.edges[--s.n_edges]; } //Valuehassupport,copythesupportinformation if(s.n_edges>0) layers[i].support[k++]=s; } if((layers[i].size=k)==0) returnES_FAILED; LayerValueslv(layers[i]); GECODE_ME_CHECK(layers[i].x.narrow_v(home,lv,false)); if(!layers[i].x.assigned()) layers[i].x.subscribe(home,*new(home)Index(home,*this,c,i)); } //Copyandcompressstates,setupotherinformation { //Statemapforin-states StateIdx*i_map=r.alloc<StateIdx>(max_states); //Statemapforout-states StateIdx*o_map=r.alloc<StateIdx>(max_states); //Numberofin-states StateIdxi_n=0; //Initializemapforin-states(specialforlastlayer) //Degreeforsinglefinalstate unsignedintd=0; for(StateIdxj=max_states;j--;) d+=static_cast<unsignedint>(layers[n].states[j].i_deg); //Checkwhetherallfinalstatescanbejoinedtoasinglestate if(d> static_cast<unsignedint> (Gecode::Support::IntTypeTraits<Degree>::max)){ //Initializemapforin-states for(StateIdxj=max_states;j--;) if((layers[n].states[j].o_deg!=0)|| (layers[n].states[j].i_deg!=0)) i_map[j]=i_n++; }else{ i_n=1; for(StateIdxj=max_states;j--;){ layers[n].states[j].init(); i_map[j]=0; } layers[n].states[0].i_deg=static_cast<Degree>(d); layers[n].states[0].o_deg=1; } layers[n].n_states=i_n; //Totalnumberofstates n_states=i_n; //Totalnumberofedges n_edges=0; //Newmaximalnumberofstates StateIdxmax_s=i_n; for(inti=n;i--;){ //In-statesbecomeout-states std::swap(o_map,i_map);i_n=0; //Initializemapforin-states for(StateIdxj=max_states;j--;) if((layers[i].states[j].o_deg!=0)|| (layers[i].states[j].i_deg!=0)) i_map[j]=i_n++; layers[i].n_states=i_n; n_states+=i_n; max_s=std::max(max_s,i_n); //Updatestatesinedges for(ValSizej=layers[i].size;j--;){ Support&s=layers[i].support[j]; n_edges+=s.n_edges; for(Degreed=s.n_edges;d--;){ s.edges[d].i_state=i_map[s.edges[d].i_state]; s.edges[d].o_state=o_map[s.edges[d].o_state]; } } } //Allocateandcopystates State*a_states=home.alloc<State>(n_states); for(inti=n+1;i--;){ StateIdxk=0; for(StateIdxj=max_states;j--;) if((layers[i].states[j].o_deg!=0)|| (layers[i].states[j].i_deg!=0)) a_states[k++]=layers[i].states[j]; assert(k==layers[i].n_states); layers[i].states=a_states; a_states+=layers[i].n_states; } //Updatemaximalnumberofstates max_states=max_s; } //Scheduleifsubsumptionisneeded if(c.empty()) View::schedule(home,*this,ME_INT_VAL); audit(); returnES_OK; } template<classView,classVal,classDegree,classStateIdx> ExecStatus LayeredGraph<View,Val,Degree,StateIdx>::advise(Space&home, Advisor&_a,constDelta&d){ //Checkwhetherstateinformationhasalreadybeencreated if(layers[0].states==NULL){ State*states=home.alloc<State>(n_states); for(unsignedinti=n_states;i--;) states[i].init(); layers[n].states=states; states+=layers[n].n_states; for(inti=n;i--;){ layers[i].states=states; states+=layers[i].n_states; for(ValSizej=layers[i].size;j--;){ Support&s=layers[i].support[j]; for(Degreed=s.n_edges;d--;){ i_state(i,s.edges[d]).o_deg++; o_state(i,s.edges[d]).i_deg++; } } } } Index&a=static_cast<Index&>(_a); constinti=a.i; if(layers[i].size<=layers[i].x.size()){ //Propagatorhasalreadydoneeverything if(View::modevent(d)==ME_INT_VAL){ a.dispose(home,c); returnc.empty()?ES_NOFIX:ES_FIX; }else{ returnES_FIX; } } booli_mod=false; boolo_mod=false; if(View::modevent(d)==ME_INT_VAL){ Valn=static_cast<Val>(layers[i].x.val()); ValSizej=0; for(;layers[i].support[j].val<n;j++){ Support&s=layers[i].support[j]; n_edges-=s.n_edges; //Supportedvaluenotanylongerinview for(Degreed=s.n_edges;d--;){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); i_mod|=o_dec(i,s.edges[d]); } } assert(layers[i].support[j].val==n); layers[i].support[0]=layers[i].support[j++]; ValSizes=layers[i].size; layers[i].size=1; for(;j<s;j++){ Support&s=layers[i].support[j]; n_edges-=s.n_edges; for(Degreed=s.n_edges;d--;){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); i_mod|=o_dec(i,s.edges[d]); } } }elseif(layers[i].x.any(d)){ ValSizej=0; ValSizek=0; ValSizes=layers[i].size; for(ViewRanges<View>rx(layers[i].x);rx()&&(j<s);){ Support&s=layers[i].support[j]; if(s.val<static_cast<Val>(rx.min())){ //Supportedvaluenotanylongerinview n_edges-=s.n_edges; for(Degreed=s.n_edges;d--;){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); i_mod|=o_dec(i,s.edges[d]); } ++j; }elseif(s.val>static_cast<Val>(rx.max())){ ++rx; }else{ layers[i].support[k++]=s; ++j; } } assert(k>0); layers[i].size=k; //Removeremainingvalues for(;j<s;j++){ Support&s=layers[i].support[j]; n_edges-=s.n_edges; for(Degreed=s.n_edges;d--;){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); i_mod|=o_dec(i,s.edges[d]); } } }else{ Valmin=static_cast<Val>(layers[i].x.min(d)); ValSizej=0; //Skipvaluessmallerthanmin(tokeep) for(;layers[i].support[j].val<min;j++){} Valmax=static_cast<Val>(layers[i].x.max(d)); ValSizek=j; ValSizes=layers[i].size; //Removeprunedvalues for(;(j<s)&&(layers[i].support[j].val<=max);j++){ Support&s=layers[i].support[j]; n_edges-=s.n_edges; for(Degreed=s.n_edges;d--;){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); i_mod|=o_dec(i,s.edges[d]); } } //Keepremainingvalues while(j<s) layers[i].support[k++]=layers[i].support[j++]; layers[i].size=k; assert(k>0); } audit(); boolfix=true; if(o_mod&&(i>0)){ o_ch.add(i-1);fix=false; } if(i_mod&&(i+1<n)){ i_ch.add(i+1);fix=false; } if(fix){ if(View::modevent(d)==ME_INT_VAL){ a.dispose(home,c); returnc.empty()?ES_NOFIX:ES_FIX; } returnES_FIX; }else{ return(View::modevent(d)==ME_INT_VAL) ?home.ES_NOFIX_DISPOSE(c,a):ES_NOFIX; } } template<classView,classVal,classDegree,classStateIdx> forceinlinesize_t LayeredGraph<View,Val,Degree,StateIdx>::dispose(Space&home){ c.dispose(home); (void)Propagator::dispose(home); returnsizeof(*this); } template<classView,classVal,classDegree,classStateIdx> ExecStatus LayeredGraph<View,Val,Degree,StateIdx>::propagate(Space&home, constModEventDelta&){ //Forwardpass for(inti=i_ch.fst();i<=i_ch.lst();i++){ booli_mod=false; boolo_mod=false; ValSizej=0; ValSizek=0; ValSizes=layers[i].size; do{ Support&s=layers[i].support[j]; n_edges-=s.n_edges; for(Degreed=s.n_edges;d--;) if(i_state(i,s.edges[d]).i_deg==0){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); i_mod|=o_dec(i,s.edges[d]); //Removeedge s.edges[d]=s.edges[--s.n_edges]; } n_edges+=s.n_edges; //Checkwhethervalueisstillsupported if(s.n_edges==0){ layers[i].size--; GECODE_ME_CHECK(layers[i].x.nq(home,s.val)); }else{ layers[i].support[k++]=s; } }while(++j<s); assert(k>0); //Updatemodificationinformation if(o_mod&&(i>0)) o_ch.add(i-1); if(i_mod&&(i+1<n)) i_ch.add(i+1); } //Backwardpass for(inti=o_ch.lst();i>=o_ch.fst();i--){ boolo_mod=false; ValSizej=0; ValSizek=0; ValSizes=layers[i].size; do{ Support&s=layers[i].support[j]; n_edges-=s.n_edges; for(Degreed=s.n_edges;d--;) if(o_state(i,s.edges[d]).o_deg==0){ //Adaptstates o_mod|=i_dec(i,s.edges[d]); (void)o_dec(i,s.edges[d]); //Removeedge s.edges[d]=s.edges[--s.n_edges]; } n_edges+=s.n_edges; //Checkwhethervalueisstillsupported if(s.n_edges==0){ layers[i].size--; GECODE_ME_CHECK(layers[i].x.nq(home,s.val)); }else{ layers[i].support[k++]=s; } }while(++j<s); assert(k>0); //Updatemodificationinformation if(o_mod&&(i>0)) o_ch.add(i-1); } a_ch.add(i_ch);i_ch.reset(); a_ch.add(o_ch);o_ch.reset(); audit(); //Checksubsumption if(c.empty()) returnhome.ES_SUBSUMED(*this); else returnES_FIX; } template<classView,classVal,classDegree,classStateIdx> template<classVar> ExecStatus LayeredGraph<View,Val,Degree,StateIdx>::post(Homehome, constVarArgArray<Var>&x, constDFA&dfa){ if(x.size()==0){ //Checkwhetherthestartstate0isalsoafinalstate if((dfa.final_fst()<=0)&&(dfa.final_lst()>=0)) returnES_OK; returnES_FAILED; } assert(x.size()>0); for(inti=x.size();i--;){ DFA::Symbolss(dfa); typenameVarTraits<Var>::Viewxi(x[i]); GECODE_ME_CHECK(xi.inter_v(home,s,false)); } LayeredGraph<View,Val,Degree,StateIdx>*p= new(home)LayeredGraph<View,Val,Degree,StateIdx>(home,x,dfa); returnp->initialize(home,x,dfa); } template<classView,classVal,classDegree,classStateIdx> forceinline LayeredGraph<View,Val,Degree,StateIdx> ::LayeredGraph(Space&home,boolshare, LayeredGraph<View,Val,Degree,StateIdx>&p) :Propagator(home,share,p), n(p.n),layers(home.alloc<Layer>(n+1)), max_states(p.max_states),n_states(p.n_states),n_edges(p.n_edges){ c.update(home,share,p.c); //Donotallocatestates,postponetoadvise! layers[n].n_states=p.layers[n].n_states; layers[n].states=NULL; //Allocatememoryforedges Edge*edges=home.alloc<Edge>(n_edges); //Copylayers for(inti=n;i--;){ layers[i].x.update(home,share,p.layers[i].x); assert(layers[i].x.size()==p.layers[i].size); layers[i].size=p.layers[i].size; layers[i].support=home.alloc<Support>(layers[i].size); for(ValSizej=layers[i].size;j--;){ layers[i].support[j].val=p.layers[i].support[j].val; layers[i].support[j].n_edges=p.layers[i].support[j].n_edges; assert(layers[i].support[j].n_edges>0); layers[i].support[j].edges= Heap::copy(edges,p.layers[i].support[j].edges, layers[i].support[j].n_edges); edges+=layers[i].support[j].n_edges; } layers[i].n_states=p.layers[i].n_states; layers[i].states=NULL; } audit(); } template<classView,classVal,classDegree,classStateIdx> PropCost LayeredGraph<View,Val,Degree,StateIdx>::cost(constSpace&, constModEventDelta&)const{ returnPropCost::linear(PropCost::HI,n); } template<classView,classVal,classDegree,classStateIdx> Actor* LayeredGraph<View,Val,Degree,StateIdx>::copy(Space&home,boolshare){ //Eliminateanassignedprefix { intk=0; while(layers[k].size==1){ assert(layers[k].support[0].n_edges==1); n_states-=layers[k].n_states; k++; } if(k>0){ /* *Thestateinformationisalwaysavailable:eitherthepropagator *hasbeencreated(hence,alsothestateinformationhasbeen *created),orthefirstvariablebecomeassignedandhence *anadvisormusthavebeenrun(whichthenhascreatedthestate *information). */ //Eliminateassignedlayers n-=k;layers+=k; //Eliminateedges n_edges-=static_cast<unsignedint>(k); //Updateadvisorindices for(Advisors<Index>as(c);as();++as) as.advisor().i-=k; //Updateallchangeinformation a_ch.lshift(k); } } audit(); //Compressstates if(!a_ch.empty()){ intf=a_ch.fst(); intl=a_ch.lst(); assert((f>=0)&&(l<=n)); Regionr(home); //Statemapforin-states StateIdx*i_map=r.alloc<StateIdx>(max_states); //Statemapforout-states StateIdx*o_map=r.alloc<StateIdx>(max_states); //Numberofin-states StateIdxi_n=0; n_states-=layers[l].n_states; //Initializemapforin-statesandcompress for(StateIdxj=0;j<layers[l].n_states;j++) if((layers[l].states[j].i_deg!=0)|| (layers[l].states[j].o_deg!=0)){ layers[l].states[i_n]=layers[l].states[j]; i_map[j]=i_n++; } layers[l].n_states=i_n; n_states+=layers[l].n_states; assert(i_n>0); //Updatein-statesinedgesforlastlayer,ifany if(l<n) for(ValSizej=layers[l].size;j--;){ Support&s=layers[l].support[j]; for(Degreed=s.n_edges;d--;) s.edges[d].i_state=i_map[s.edges[d].i_state]; } //Updateallchangedlayers for(inti=l-1;i>=f;i--){ //In-statesbecomeout-states std::swap(o_map,i_map);i_n=0; //Initializemapforin-statesandcompress n_states-=layers[i].n_states; for(StateIdxj=0;j<layers[i].n_states;j++) if((layers[i].states[j].o_deg!=0)|| (layers[i].states[j].i_deg!=0)){ layers[i].states[i_n]=layers[i].states[j]; i_map[j]=i_n++; } layers[i].n_states=i_n; n_states+=layers[i].n_states; assert(i_n>0); //Updatestatesinedges for(ValSizej=layers[i].size;j--;){ Support&s=layers[i].support[j]; for(Degreed=s.n_edges;d--;){ s.edges[d].i_state=i_map[s.edges[d].i_state]; s.edges[d].o_state=o_map[s.edges[d].o_state]; } } } //Updateout-statesinedgesforpreviouslayer,ifany if(f>0) for(ValSizej=layers[f-1].size;j--;){ Support&s=layers[f-1].support[j]; for(Degreed=s.n_edges;d--;) s.edges[d].o_state=i_map[s.edges[d].o_state]; } a_ch.reset(); } audit(); returnnew(home)LayeredGraph<View,Val,Degree,StateIdx>(home,share,*this); } template<classVar> forceinlineExecStatus post_lgp(Homehome,constVarArgArray<Var>&x,constDFA&dfa){ Gecode::Support::IntTypet_state_idx= Gecode::Support::u_type(static_cast<unsignedint>(dfa.n_states())); Gecode::Support::IntTypet_degree= Gecode::Support::u_type(dfa.max_degree()); Gecode::Support::IntTypet_val= std::max(Support::s_type(dfa.symbol_min()), Support::s_type(dfa.symbol_max())); switch(t_val){ caseGecode::Support::IT_CHAR: caseGecode::Support::IT_SHRT: switch(t_state_idx){ caseGecode::Support::IT_CHAR: switch(t_degree){ caseGecode::Support::IT_CHAR: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedchar,unsignedchar> ::post(home,x,dfa); caseGecode::Support::IT_SHRT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedshortint,unsignedchar> ::post(home,x,dfa); caseGecode::Support::IT_INT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedint,unsignedchar> ::post(home,x,dfa); default:GECODE_NEVER; } break; caseGecode::Support::IT_SHRT: switch(t_degree){ caseGecode::Support::IT_CHAR: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedchar,unsignedshortint> ::post(home,x,dfa); caseGecode::Support::IT_SHRT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedshortint,unsignedshortint> ::post(home,x,dfa); caseGecode::Support::IT_INT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedint,unsignedshortint> ::post(home,x,dfa); default:GECODE_NEVER; } break; caseGecode::Support::IT_INT: switch(t_degree){ caseGecode::Support::IT_CHAR: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedchar,unsignedint> ::post(home,x,dfa); caseGecode::Support::IT_SHRT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedshortint,unsignedint> ::post(home,x,dfa); caseGecode::Support::IT_INT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,shortint,unsignedint,unsignedint> ::post(home,x,dfa); default:GECODE_NEVER; } break; default:GECODE_NEVER; } caseGecode::Support::IT_INT: switch(t_state_idx){ caseGecode::Support::IT_CHAR: switch(t_degree){ caseGecode::Support::IT_CHAR: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedchar,unsignedchar> ::post(home,x,dfa); caseGecode::Support::IT_SHRT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedshortint,unsignedchar> ::post(home,x,dfa); caseGecode::Support::IT_INT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedint,unsignedchar> ::post(home,x,dfa); default:GECODE_NEVER; } break; caseGecode::Support::IT_SHRT: switch(t_degree){ caseGecode::Support::IT_CHAR: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedchar,unsignedshortint> ::post(home,x,dfa); caseGecode::Support::IT_SHRT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedshortint,unsignedshortint> ::post(home,x,dfa); caseGecode::Support::IT_INT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedint,unsignedshortint> ::post(home,x,dfa); default:GECODE_NEVER; } break; caseGecode::Support::IT_INT: switch(t_degree){ caseGecode::Support::IT_CHAR: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedchar,unsignedint> ::post(home,x,dfa); caseGecode::Support::IT_SHRT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedshortint,unsignedint> ::post(home,x,dfa); caseGecode::Support::IT_INT: returnExtensional::LayeredGraph <typenameVarTraits<Var>::View,int,unsignedint,unsignedint> ::post(home,x,dfa); default:GECODE_NEVER; } break; default:GECODE_NEVER; } default:GECODE_NEVER; } returnES_OK; } }}} //STATISTICS:int-prop