pd_alg_nb_sub_b.cppGo 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 |