pd_alg_nb_sub_b.cpp

Go to the documentation of this file.
00001 /** @file pd_alg_nb_sub_b.cpp  Nonblock subfunctions, part B */
00002 
00003 
00004 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2013  Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess
00007 
00008 */
00009 
00010 #include "pd_alg_nb_sub_b.h"
00011 
00012 namespace faudes {
00013 
00014 /* *************************
00015  * RenQ
00016  * *************************/
00017 PushdownGenerator RenQ(const std::string word, const PushdownGenerator& pd){
00018     
00019   //take a copy of the old generator
00020   PushdownGenerator rPd = PushdownGenerator(pd);
00021   
00022   //annotate states of the new generator
00023   StateSet::Iterator its;    
00024   for(its = pd.StatesBegin(); its != pd.StatesEnd(); its++){
00025     MergeStateAnnotation msa = MergeStateAnnotation(*its,word);
00026     rPd.SetMerge(*its,msa);
00027   }
00028   return rPd;
00029 }
00030 
00031 /* *************************
00032  * RenG
00033  * *************************/
00034 PushdownGenerator RenG(const std::string word, const PushdownGenerator& pd){
00035   
00036   //the annotation string
00037   std::string annotation = word + "-";
00038   
00039   //take a copy of the old generator
00040   PushdownGenerator rPd = PushdownGenerator(pd);
00041   
00042   //rename every stack symbol and delete the old one
00043   StackSymbolSet::Iterator it;
00044   for(it = pd.StackSymbolsBegin(); it != pd.StackSymbolsEnd(); it++){
00045     //dont rename lambda
00046     if(!pd.IsStackSymbolLambda(*it)){
00047       rPd.InsStackSymbol(annotation + pd.StackSymbolName(*it));
00048       rPd.DelStackSymbol(pd.StackSymbolName(*it));
00049     }
00050   }
00051   //rename stack bottom
00052   rPd.SetStackBottom(annotation + pd.StackSymbolName(pd.StackBottom()));
00053   
00054   //iterate over transitions and replace stack symbols in push and pop with 
00055   //the renamed versions
00056   TransSet::Iterator tit;
00057   std::vector<Idx> oldPush, oldPop, push, pop;
00058   std::vector<Idx>::const_iterator pushit, popit;
00059   PopPushSet popPush;
00060   PopPushSet::const_iterator ppit;
00061   
00062   //take copy of transitions to iterate over
00063   //copying is necessary because transitions will get deleted
00064   //iterating over the original TransSet can lead to undefined behaviour
00065   TransSet transRel = rPd.TransRel();
00066   for(tit = transRel.Begin(); tit != transRel.End(); tit++){
00067     
00068     //iterate over pop/push pairs
00069     popPush = rPd.PopPush(*tit);
00070     for(ppit = popPush.begin(); ppit != popPush.end(); ppit++){
00071       
00072       //rename pop stack symbols
00073       oldPop = ppit->first;
00074       for(popit = oldPop.begin(); popit != oldPop.end(); popit++){
00075         //dont rename lambda
00076         if(pd.IsStackSymbolLambda(*popit)){
00077           pop.push_back(*popit);
00078         }
00079         else{
00080           pop.push_back(rPd.StackSymbolIndex(annotation + rPd.StackSymbolName(*popit)));
00081         }
00082       }
00083       
00084       //rename push stack symbols
00085       oldPush = ppit->second;
00086       for(pushit = oldPush.begin(); pushit != oldPush.end(); pushit++){
00087         //dont rename lambda
00088         if(pd.IsStackSymbolLambda(*pushit)){
00089           push.push_back(*pushit);
00090         }
00091         else{
00092           push.push_back(rPd.StackSymbolIndex(annotation + rPd.StackSymbolName(*pushit)));
00093         }
00094       }
00095       
00096       //create new transitions
00097       rPd.SetTransition(*tit, pop, push);
00098       pop.clear();
00099       push.clear();
00100     
00101       //and delete the old one
00102       rPd.ClrTransition(*tit, oldPop, oldPush);
00103     }
00104   }
00105   return rPd;
00106 }
00107 
00108 /* *************************
00109  * Rep0
00110  * *************************/
00111 PushdownGenerator Rep0(const PushdownGenerator& pd){
00112   
00113   //rename stack symbols and states
00114   PushdownGenerator rPd = RenG("old",RenQ("old",pd));
00115   
00116   //remember important attributes of the generator before proceeding
00117   StackSymbolSet oldStackSymbols = rPd.StackSymbols();
00118   Idx oldInitState = rPd.InitState();
00119   std::string oldStackBottom = rPd.StackSymbolName(rPd.StackBottom());
00120   
00121   //clear old init state and create new init state which will be annotated with "new"
00122   //and derived from pd.InitState() in a merge state annotation
00123   rPd.ClrInitState(rPd.InitState());
00124   Idx newInitState = rPd.InsState();
00125   rPd.SetInitState(newInitState);
00126   MergeStateAnnotation msa(pd.InitState(),"new");
00127   rPd.SetMerge(newInitState, msa);
00128   
00129   //set new stack bottom
00130   rPd.SetStackBottom("new-" + pd.StackSymbolName(pd.StackBottom()));
00131   
00132   //if the old initial state was marked, the new initial state is marked as well
00133   if(pd.ExistsMarkedState(pd.InitState())){
00134     rPd.InsMarkedState(rPd.InitState());
00135   }
00136   
00137   //add transition that adds the old stack bottom symbol to the stack
00138   //maybe lambda event needs to be inserted first
00139   Idx lambdaIdx = rPd.InsEvent(FAUDES_PD_LAMBDA);
00140   std::vector<StackSymbol> pop, push;
00141   std::string newStackBottom = rPd.StackSymbolName(rPd.StackBottom());
00142   //pop new stack bottom
00143   pop.push_back(StackSymbol(newStackBottom));
00144   //push new stack bottom and old stack bottom
00145   push.push_back(StackSymbol(oldStackBottom));
00146   push.push_back(StackSymbol(newStackBottom));
00147   //add transition
00148   rPd.SetTransition(newInitState, lambdaIdx, oldInitState, pop, push);
00149   
00150   //iterate over all transitions
00151   //take copy of transitions to iterate over
00152   //copying is necessary because transitions will get deleted
00153   //iterating over the original TransSet can lead to undefined behaviour
00154   TransSet transRel = rPd.TransRel();
00155   TransSet::Iterator tit;
00156   StackSymbolSet::Iterator ssit;
00157   std::vector<Idx> examinedPop, examinedPush, newPop, newPush;
00158   for(tit = transRel.Begin(); tit != transRel.End(); tit++){
00159     
00160     //look for lambda popping transitions (s1,ev,s2,lambda,w)
00161     //only need to look at the first pop/push pair, because only deterministic
00162     //generator are considered. the generator would be nondeterministic if there
00163     //was a transition in addition to a lambda popping one
00164     examinedPop = rPd.PopPush(*tit).begin()->first;
00165     examinedPush = rPd.PopPush(*tit).begin()->second;
00166     if(pd.IsStackSymbolLambda(examinedPop.front())){
00167       
00168       //remove the transition
00169       rPd.ClrTransition(*tit, examinedPop, examinedPush);
00170       
00171       //add new transitions for every possible stack symbol u minus the just
00172       //inserted bottom and lambda so that it looks like (s1,ev,s2,u,uw) for
00173       //for(ssit = oldStackSymbols.Begin(); ssit != oldStackSymbols.End(); ssit++){
00174       for(ssit = rPd.StackSymbolsBegin(); ssit != rPd.StackSymbolsEnd(); ssit++){
00175         if(!rPd.IsStackSymbolLambda(*ssit)){
00176           //fill pop with stack symbol
00177           newPop.clear();
00178           newPop.push_back(*ssit);
00179           //fill push with examinedPush plus stack symbol
00180           newPush.clear();
00181           newPush.insert(newPush.end(), examinedPush.begin(), examinedPush.end());
00182           newPush.push_back(*ssit);
00183           //add transition
00184           rPd.SetTransition(*tit, newPop, newPush);
00185         }
00186       }
00187     }    
00188   }
00189   return rPd;  
00190 }
00191 
00192 
00193 /* *************************
00194  * Rpp
00195  * *************************/
00196 PushdownGenerator Rpp(const PushdownGenerator& pd){
00197   
00198   //take a copy of the old generator
00199   PushdownGenerator rPd = PushdownGenerator(pd);
00200   
00201   //annotate states of the new generator
00202   StateSet::Iterator stateit;    
00203   for(stateit = pd.StatesBegin(); stateit != pd.StatesEnd(); stateit++){
00204     MergeStateAnnotation msa = MergeStateAnnotation(*stateit, "old");
00205     rPd.SetMerge(*stateit,msa);
00206   }
00207   
00208   //clear transition relation
00209   rPd.ClearTransRel();
00210   
00211   std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > readSet, multiPushSet, popPushSet, unchangedSet;
00212   std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > >::iterator multimapit;
00213   std::pair<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > transition;
00214   std::pair<std::vector<Idx>, std::vector<Idx> > popPushPair;
00215   std::vector<Idx> pop, push, pushEnd;
00216   TransSet::Iterator transit;
00217   PopPushSet::const_iterator ppit;
00218   //partition transitions of old generator into four sets
00219   //because states have only been copied (and annotated), the state indices remain
00220   //the same for both generators
00221   for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
00222     for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
00223       
00224       //get pop and push pair
00225       pop = ppit->first;
00226       push = ppit->second;
00227       
00228       //create transition and decide further down into which set it will be put
00229       transition = std::make_pair(*transit, *ppit);
00230       
00231       
00232       //first set contains all transitions whose event is not lambda and pop does not
00233       //equal push
00234       //(i. e., are of the form (p,a,x,y,q) with x != y)
00235       if(!pd.IsEventLambda(transit->Ev) && pop != push){
00236         readSet.insert(transition);
00237       }
00238       
00239       //second and third set do not read anything (they have lambda events)
00240       else if(pd.IsEventLambda(transit->Ev)){
00241         
00242         //filter out all push transitions (p,lambda,x,yx,q), they will not need to be changed
00243         if(push.size() == 2 && push.back() == pop.front()){
00244           unchangedSet.insert(transition);
00245           continue;
00246         }
00247         //second set contains all transitions that push, but don't read lambda and
00248         //don't effectively pop
00249         //(i. e., are of the form (p,lambda,x,yax,q) with a not empty)
00250         else if(push.size() > 1){
00251           if(push.back() == pop.front()){
00252             multiPushSet.insert(transition);
00253           }
00254           
00255           //third set contains all transitions that pop and push
00256           //(i. e., are of the form (p,lambda,x,ya,q) with a not empty, x != a)
00257           else{
00258             popPushSet.insert(transition);
00259           }
00260         }
00261         //also put transitions without lambda push into third set
00262         else if (!pd.IsStackSymbolLambda(push.front())) {
00263           popPushSet.insert(transition);
00264         }
00265         
00266         //put transitions with lambda push into fourth set
00267         else{
00268           unchangedSet.insert(transition);
00269         }
00270       }
00271       //put all remaining transitions into fourth set as well
00272       else{
00273         unchangedSet.insert(transition);
00274       }
00275     }
00276   }
00277   
00278   
00279   //add lambda to events in case it has not already been added
00280   Idx lambdaIdx = rPd.InsEvent(FAUDES_PD_LAMBDA);
00281   
00282   Idx newState;
00283   //for every transition (p,a,x,y,q) in the first set
00284   for(multimapit = readSet.begin(); multimapit != readSet.end(); multimapit++){
00285     
00286     //add new intermediate state and annotate it with (p,a,x,x,p)
00287     newState = rPd.InsState();
00288     pop = multimapit->second.first;
00289     push = multimapit->second.first;
00290     MergeTransition mt(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X1, pop,push);
00291     rPd.SetMerge(newState, mt);
00292     
00293     //add transition to and from intermediate state
00294     //(p,a,x,x,newstate)
00295     rPd.SetTransition(multimapit->first.X1, multimapit->first.Ev, newState, pop, push);
00296     //(newstate,lambda,x,y,q)
00297     rPd.SetTransition(newState, lambdaIdx, multimapit->first.X2, pop, multimapit->second.second);
00298   }
00299   
00300   //for every transition (p,lambda,x,yax,q) with a not empty in the second set
00301   for(multimapit = multiPushSet.begin(); multimapit != multiPushSet.end(); multimapit++){
00302     
00303     //add new intermediate state and annotate it with (p,lambda,x,ax,p)
00304     newState = rPd.InsState();
00305     pop = multimapit->second.first;
00306     push = std::vector<Idx>(multimapit->second.second.end() - multimapit->second.first.size() - 1, multimapit->second.second.end());
00307     MergeTransition mt(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X1, pop,push);
00308     rPd.SetMerge(newState, mt);
00309     
00310     //add transition to and from intermediate state
00311     //(p,lambda,x,ax,newstate)
00312     rPd.SetTransition(multimapit->first.X1, multimapit->first.Ev, newState, pop, push);
00313     //(newstate,lambda,a,ya,q)
00314     pop.clear();
00315     pop.push_back(multimapit->second.second.at(multimapit->second.second.size() - multimapit->second.first.size() - 1));
00316     push = std::vector<Idx>(multimapit->second.second.begin(), multimapit->second.second.end() - multimapit->second.first.size());
00317     rPd.SetTransition(newState, lambdaIdx, multimapit->first.X2, pop, push);
00318   }
00319   
00320   //for every transition (p,lambda,x,ya,q) with a not empty and x != a in the third set
00321   for(multimapit = popPushSet.begin(); multimapit != popPushSet.end(); multimapit++){
00322     
00323     //add new intermediate state and annotate it with (p,lambda,x,lambda,p)
00324     newState = rPd.InsState();
00325     pop = multimapit->second.first;
00326     push.clear();
00327     push.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
00328     MergeTransition mt(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X1, pop,push);
00329     rPd.SetMerge(newState, mt);
00330     
00331     //add transition to and from intermediate state
00332     //(p,lambda,x,lambda,newstate)
00333     rPd.SetTransition(multimapit->first.X1, lambdaIdx, newState, pop, push);
00334     //(newstate,lambda,lambda,ya,q)
00335     pop.clear();
00336     pop.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
00337     push = multimapit->second.second;
00338     rPd.SetTransition(newState, lambdaIdx, multimapit->first.X2, pop, push);
00339   }
00340   
00341   //for every transitions in the fourth set
00342   for(multimapit = unchangedSet.begin(); multimapit != unchangedSet.end(); multimapit++){
00343     
00344     //read pop and push for convenience
00345     pop = multimapit->second.first;
00346     push= multimapit->second.second;
00347     
00348     //if it is a read only transition in the form of (p,a,x,x,q), changed
00349     //it to (p,a,lambda,lambda,q)
00350 //     if(!rPd.IsEventLambda(multimapit->first.Ev) && !pop.front().IsLambda() && pop == push ){
00351 //       pop.clear();
00352 //       pop.push_back(StackSymbol(FAUDES_PD_LAMBDA));
00353 //       push.clear();
00354 //       push.push_back(StackSymbol(FAUDES_PD_LAMBDA));
00355 //     }
00356 //     
00357     //insert the transition again
00358     rPd.SetTransition(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X2, pop, push);
00359   }
00360   
00361   //if changes were made, repeat recursively
00362   //if lambda popping edges were added, they need to be removed first
00363   if(popPushSet.size() != 0){
00364     rPd = Rpp(Rep0(rPd));
00365   }
00366   else if(readSet.size() + multiPushSet.size() != 0){
00367     rPd = Rpp(rPd);
00368   }
00369   
00370   return rPd;
00371 }
00372 
00373 /* *************************
00374  * PrintTransitions
00375  * *************************/
00376 void PrintTransitions(const std::multimap<Transition, std::pair<std::vector<StackSymbol>, std::vector<StackSymbol> > >& transitions){
00377   std::cout << "\nPrint Transitions:\n" << std::endl;
00378   std::multimap<Transition, std::pair<std::vector<StackSymbol>, std::vector<StackSymbol> > >::const_iterator transit;
00379   std::vector<StackSymbol>::const_iterator ssit;
00380   std::stringstream s;
00381   
00382   for(transit = transitions.begin(); transit != transitions.end(); transit++){
00383      s << transit->first.X1 << " " << PushdownGenerator::GlobalEventSymbolTablep()->Symbol(transit->first.Ev) << " " << transit->first.X2 << " [";
00384     for(ssit = transit->second.first.begin(); ssit != transit->second.first.end(); ssit++){
00385       s << ssit->Symbol() << " ";
00386     }
00387     s << "] [";
00388     for(ssit = transit->second.second.begin(); ssit != transit->second.second.end(); ssit++){
00389       s << ssit->Symbol() << " ";
00390     }
00391     s << "]" << std::endl;
00392     
00393    
00394   }
00395   std::cout << s.str() << std::endl;
00396 }
00397 
00398 /* *************************
00399  * Rep2
00400  * *************************/
00401 PushdownGenerator Rep2(const PushdownGenerator& pd){
00402  
00403   //take a copy of the old generator
00404   PushdownGenerator rPd = PushdownGenerator(pd);
00405   
00406   //add lambda to events in case it has not already been added
00407   Idx lambdaIdx = rPd.InsEvent(FAUDES_PD_LAMBDA);
00408   
00409   //annotate states of the new generator. the state indices are the same for both 
00410   //generators, only the annotations will be different
00411   StateSet::Iterator stateit;    
00412   for(stateit = pd.StatesBegin(); stateit != pd.StatesEnd(); stateit++){
00413     MergeStateAnnotation msa = MergeStateAnnotation(*stateit,"old");
00414     rPd.SetMerge(*stateit,msa);
00415   }
00416   
00417   std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > offendingTransSet;
00418   std::pair<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > transition;
00419   std::vector<Idx> pop, push;
00420   std::set< std::pair<Idx, Idx> > intermediateStates;
00421   std::pair<Idx, Idx> intermediateStatePair;
00422   std::map<std::pair<Idx, Idx>, Idx> mapIntermediateStates;
00423   TransSet::Iterator transit;
00424   PopPushSet::const_iterator ppit;
00425   Idx newState;
00426   //prepare an empty push vector
00427   push.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
00428   
00429   //look for transitions that pop more than one stack symbol,
00430   //(i. e. (q,w,av,v',q') with |a| = 1, |v| > 0)), save the transitions
00431   //in offendingTransSet, and add intermediate states that will be connected later
00432   for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
00433     for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
00434       if(ppit->first.size() > 1){
00435         
00436         //save transition
00437         transition = std::make_pair(*transit, *ppit);
00438         offendingTransSet.insert(transition);
00439         
00440         //add intermediate state annotated with ((old,q),lambda,a,lambda,(old,q)), but
00441         //only if it has not already been added for this particular pair of (q,a)
00442         intermediateStatePair = std::make_pair(transit->X1,ppit->first.front());
00443         if(intermediateStates.insert(intermediateStatePair).second){
00444           
00445           //add intermediate state
00446           newState = rPd.InsState();
00447           //and save it for connecting with transitions later on
00448           mapIntermediateStates.insert(std::make_pair(intermediateStatePair,newState));
00449           
00450           //create annotation
00451           pop.clear();
00452           pop.push_back(ppit->first.front());
00453           MergeTransition mt(transit->X1, lambdaIdx, transit->X1, pop, push);//note: transit->X1 from pd refers to (old,transit->X1) in the context of
00454           //rPd, because state indices in pd and rPd are the same (they are copies) with
00455           //only the annotations being different
00456           rPd.SetMerge(newState, mt);
00457         }
00458       }
00459     }
00460   }
00461   
00462   std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > >::iterator offendingit;
00463   Idx startState, intermediateState;
00464   Idx popSymbol;
00465   TransSet transCopy;
00466   PopPushSet ppCopy;
00467   //iterate over all offending transitions (q,w,av,v',q') to fix them
00468   for(offendingit = offendingTransSet.begin(); offendingit != offendingTransSet.end(); offendingit++){
00469     
00470     //take a copy of the generator's transitions for iterating, because transitions will
00471     //be deleted and this would mess with the iterator
00472     transCopy = rPd.TransRel();
00473     
00474     //iterate over all transitions (q,x,ay,y',q'') starting at the same state q
00475     //and popping the same stack symbol a
00476     startState = offendingit->first.X1;
00477     popSymbol = offendingit->second.first.front();
00478     //ensure q
00479     for(transit = transCopy.Begin(startState); transit != transCopy.End(startState); transit++){
00480       
00481       //take a copy of the transitions's pop/push pairs for iterating, because pairs
00482       //will be deleted and this would mess with the iterator
00483       ppCopy = rPd.PopPush(*transit);
00484       
00485       for(ppit = ppCopy.begin(); ppit != ppCopy.end(); ppit++){
00486         //ensure a and |ay| > 1 (i. e. |y| != 0)
00487         if(ppit->first.front() == popSymbol && ppit->first.size() > 1){
00488           
00489           //delete the transition
00490           rPd.ClrTransition(*transit, ppit->first, ppit->second);
00491           
00492           //and insert transition to and from corresponding intermediate state
00493           //get intermediate state index
00494           intermediateState = mapIntermediateStates.find(std::make_pair(startState,popSymbol))->second;
00495           
00496           //set transition to intermediate state
00497           pop.clear();
00498           pop.push_back(popSymbol);
00499           push.clear();
00500           push.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
00501           rPd.SetTransition(startState, lambdaIdx, intermediateState, pop, push);
00502           
00503           //set transition from intermediate state
00504           pop = ppit->first;
00505           pop.erase(pop.begin());
00506           push  = ppit->second;
00507           rPd.SetTransition(intermediateState, transit->Ev, transit->X2, pop, push);
00508           
00509         }
00510       }
00511     }
00512   }
00513   
00514   //if offending transitions were found, check again if there are offending
00515   //transitions left
00516   if(offendingTransSet.size() != 0){
00517     rPd = Rep2(rPd);
00518   }
00519   return rPd;
00520 }
00521 
00522 
00523 /* *************************
00524  * Nda
00525  * *************************/
00526 PushdownGenerator Nda(const PushdownGenerator& pd){
00527  
00528   PushdownGenerator rPd = pd;
00529   
00530   //states and transition relation will be rebuilt, so delete the existing ones
00531   rPd.ClearTransRel();
00532   rPd.ClearStates();
00533   
00534   StateSet::Iterator stateit;
00535   Idx newStateAct, newStatePas;
00536   std::string active = "active";
00537   std::string passive = "passive";
00538   std::map<Idx,std::pair<Idx,Idx> > stateMap;
00539   //for insert an active and a passive state for each state of the old generator
00540   for(stateit = pd.StatesBegin(); stateit != pd.StatesEnd(); stateit++){
00541     
00542     //active state
00543     newStateAct = rPd.InsState();
00544     MergeStateAnnotation mssAct(*stateit,active);
00545     rPd.SetMerge(newStateAct,mssAct);
00546     
00547     //if the old state was a final state, the active state is final as well
00548     if(pd.ExistsMarkedState(*stateit)){
00549       rPd.SetMarkedState(newStateAct);
00550     }
00551     
00552     //if the old state was the starting state, the active state is a starting state
00553     //as well
00554     if(pd.ExistsInitState(*stateit)){
00555       rPd.SetInitState(newStateAct);
00556     }
00557     
00558     //passive state
00559     newStatePas = rPd.InsState();
00560     MergeStateAnnotation mssPas(*stateit,passive);
00561     rPd.SetMerge(newStatePas,mssPas);
00562     
00563     //save relation between old state and new states for later reference
00564     stateMap.insert(std::make_pair(*stateit,std::make_pair(newStateAct,newStatePas)));
00565   }
00566   
00567   TransSet::Iterator transit;
00568   PopPushSet::const_iterator ppit;
00569   std::vector<Idx> pop, push;
00570   Idx startState, endState, oldStartState, oldEndState, oldEvent;
00571   //insert transitions
00572   for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
00573     for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
00574       
00575       //for convenience
00576       pop = ppit->first;
00577       push = ppit->second;
00578       oldStartState = transit->X1;
00579       oldEndState = transit->X2;
00580       oldEvent = transit->Ev;
00581       
00582       //for any reading transition
00583       if(!pd.IsEventLambda(oldEvent)){
00584         
00585         //connect active state to active state
00586         startState = stateMap.find(oldStartState)->second.first;
00587         endState = stateMap.find(oldEndState)->second.first;
00588         rPd.SetTransition(startState,oldEvent,endState,pop,push);
00589         
00590         //connect passive state to active state
00591         startState = stateMap.find(oldStartState)->second.second;
00592         rPd.SetTransition(startState,oldEvent,endState,pop,push);
00593       }
00594       
00595       
00596       else{
00597         
00598         //for any pushing and popping transition
00599         if(push.size() == 2 || pd.IsStackSymbolLambda(push.front())){
00600           
00601           //connect passive state to passive state
00602           startState = stateMap.find(oldStartState)->second.second;
00603           endState = stateMap.find(oldEndState)->second.second;
00604           rPd.SetTransition(startState,oldEvent,endState,pop,push);
00605           
00606           //if the old start state was marked, connect active state to passive state
00607           if(pd.ExistsMarkedState(oldStartState)){
00608             startState = stateMap.find(oldStartState)->second.first;
00609             rPd.SetTransition(startState,oldEvent,endState,pop,push);
00610           }
00611           
00612           //else connect active state to active state
00613           else{
00614             startState = stateMap.find(oldStartState)->second.first;
00615             endState = stateMap.find(oldEndState)->second.first;
00616             rPd.SetTransition(startState,oldEvent,endState,pop,push);
00617           }
00618         }
00619       
00620         //should never get here
00621         else{
00622           std::stringstream errstr;
00623           errstr << "While executing Nda(): Found transition which is neither read nor pop nor push, which is not allowed" << std::endl;
00624           throw Exception("Nda", errstr.str(), 1001);
00625         }
00626       }
00627     }
00628   }
00629   
00630   return rPd;  
00631 }
00632 
00633 
00634 } // namespace faudes
00635 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen