pd_alg_nb_sub_b.cpp
Go to the documentation of this file.
1 /** @file pd_alg_nb_sub_b.cpp Nonblock subfunctions, part B */
2 
3 
4 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2013 Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess
7 
8 */
9 
10 #include "pd_alg_nb_sub_b.h"
11 
12 namespace faudes {
13 
14 /* *************************
15  * RenQ
16  * *************************/
17 PushdownGenerator RenQ(const std::string word, const PushdownGenerator& pd){
18 
19  //take a copy of the old generator
21 
22  //annotate states of the new generator
23  StateSet::Iterator its;
24  for(its = pd.StatesBegin(); its != pd.StatesEnd(); its++){
26  rPd.SetMerge(*its,msa);
27  }
28  return rPd;
29 }
30 
31 /* *************************
32  * RenG
33  * *************************/
34 PushdownGenerator RenG(const std::string word, const PushdownGenerator& pd){
35 
36  //the annotation string
37  std::string annotation = word + "-";
38 
39  //take a copy of the old generator
41 
42  //rename every stack symbol and delete the old one
43  StackSymbolSet::Iterator it;
44  for(it = pd.StackSymbolsBegin(); it != pd.StackSymbolsEnd(); it++){
45  //dont rename lambda
46  if(!pd.IsStackSymbolLambda(*it)){
47  rPd.InsStackSymbol(annotation + pd.StackSymbolName(*it));
48  rPd.DelStackSymbol(pd.StackSymbolName(*it));
49  }
50  }
51  //rename stack bottom
52  rPd.SetStackBottom(annotation + pd.StackSymbolName(pd.StackBottom()));
53 
54  //iterate over transitions and replace stack symbols in push and pop with
55  //the renamed versions
57  std::vector<Idx> oldPush, oldPop, push, pop;
58  std::vector<Idx>::const_iterator pushit, popit;
59  PopPushSet popPush;
60  PopPushSet::const_iterator ppit;
61 
62  //take copy of transitions to iterate over
63  //copying is necessary because transitions will get deleted
64  //iterating over the original TransSet can lead to undefined behaviour
65  TransSet transRel = rPd.TransRel();
66  for(tit = transRel.Begin(); tit != transRel.End(); tit++){
67 
68  //iterate over pop/push pairs
69  popPush = rPd.PopPush(*tit);
70  for(ppit = popPush.begin(); ppit != popPush.end(); ppit++){
71 
72  //rename pop stack symbols
73  oldPop = ppit->first;
74  for(popit = oldPop.begin(); popit != oldPop.end(); popit++){
75  //dont rename lambda
76  if(pd.IsStackSymbolLambda(*popit)){
77  pop.push_back(*popit);
78  }
79  else{
80  pop.push_back(rPd.StackSymbolIndex(annotation + rPd.StackSymbolName(*popit)));
81  }
82  }
83 
84  //rename push stack symbols
85  oldPush = ppit->second;
86  for(pushit = oldPush.begin(); pushit != oldPush.end(); pushit++){
87  //dont rename lambda
88  if(pd.IsStackSymbolLambda(*pushit)){
89  push.push_back(*pushit);
90  }
91  else{
92  push.push_back(rPd.StackSymbolIndex(annotation + rPd.StackSymbolName(*pushit)));
93  }
94  }
95 
96  //create new transitions
97  rPd.SetTransition(*tit, pop, push);
98  pop.clear();
99  push.clear();
100 
101  //and delete the old one
102  rPd.ClrTransition(*tit, oldPop, oldPush);
103  }
104  }
105  return rPd;
106 }
107 
108 /* *************************
109  * Rep0
110  * *************************/
112 
113  //rename stack symbols and states
114  PushdownGenerator rPd = RenG("old",RenQ("old",pd));
115 
116  //remember important attributes of the generator before proceeding
117  StackSymbolSet oldStackSymbols = rPd.StackSymbols();
118  Idx oldInitState = rPd.InitState();
119  std::string oldStackBottom = rPd.StackSymbolName(rPd.StackBottom());
120 
121  //clear old init state and create new init state which will be annotated with "new"
122  //and derived from pd.InitState() in a merge state annotation
123  rPd.ClrInitState(rPd.InitState());
124  Idx newInitState = rPd.InsState();
125  rPd.SetInitState(newInitState);
126  MergeStateAnnotation msa(pd.InitState(),"new");
127  rPd.SetMerge(newInitState, msa);
128 
129  //set new stack bottom
130  rPd.SetStackBottom("new-" + pd.StackSymbolName(pd.StackBottom()));
131 
132  //if the old initial state was marked, the new initial state is marked as well
133  if(pd.ExistsMarkedState(pd.InitState())){
134  rPd.InsMarkedState(rPd.InitState());
135  }
136 
137  //add transition that adds the old stack bottom symbol to the stack
138  //maybe lambda event needs to be inserted first
139  Idx lambdaIdx = rPd.InsEvent(FAUDES_PD_LAMBDA);
140  std::vector<StackSymbol> pop, push;
141  std::string newStackBottom = rPd.StackSymbolName(rPd.StackBottom());
142  //pop new stack bottom
143  pop.push_back(StackSymbol(newStackBottom));
144  //push new stack bottom and old stack bottom
145  push.push_back(StackSymbol(oldStackBottom));
146  push.push_back(StackSymbol(newStackBottom));
147  //add transition
148  rPd.SetTransition(newInitState, lambdaIdx, oldInitState, pop, push);
149 
150  //iterate over all transitions
151  //take copy of transitions to iterate over
152  //copying is necessary because transitions will get deleted
153  //iterating over the original TransSet can lead to undefined behaviour
154  TransSet transRel = rPd.TransRel();
155  TransSet::Iterator tit;
156  StackSymbolSet::Iterator ssit;
157  std::vector<Idx> examinedPop, examinedPush, newPop, newPush;
158  for(tit = transRel.Begin(); tit != transRel.End(); tit++){
159 
160  //look for lambda popping transitions (s1,ev,s2,lambda,w)
161  //only need to look at the first pop/push pair, because only deterministic
162  //generator are considered. the generator would be nondeterministic if there
163  //was a transition in addition to a lambda popping one
164  examinedPop = rPd.PopPush(*tit).begin()->first;
165  examinedPush = rPd.PopPush(*tit).begin()->second;
166  if(pd.IsStackSymbolLambda(examinedPop.front())){
167 
168  //remove the transition
169  rPd.ClrTransition(*tit, examinedPop, examinedPush);
170 
171  //add new transitions for every possible stack symbol u minus the just
172  //inserted bottom and lambda so that it looks like (s1,ev,s2,u,uw) for
173  //for(ssit = oldStackSymbols.Begin(); ssit != oldStackSymbols.End(); ssit++){
174  for(ssit = rPd.StackSymbolsBegin(); ssit != rPd.StackSymbolsEnd(); ssit++){
175  if(!rPd.IsStackSymbolLambda(*ssit)){
176  //fill pop with stack symbol
177  newPop.clear();
178  newPop.push_back(*ssit);
179  //fill push with examinedPush plus stack symbol
180  newPush.clear();
181  newPush.insert(newPush.end(), examinedPush.begin(), examinedPush.end());
182  newPush.push_back(*ssit);
183  //add transition
184  rPd.SetTransition(*tit, newPop, newPush);
185  }
186  }
187  }
188  }
189  return rPd;
190 }
191 
192 
193 /* *************************
194  * Rpp
195  * *************************/
197 
198  //take a copy of the old generator
200 
201  //annotate states of the new generator
202  StateSet::Iterator stateit;
203  for(stateit = pd.StatesBegin(); stateit != pd.StatesEnd(); stateit++){
204  MergeStateAnnotation msa = MergeStateAnnotation(*stateit, "old");
205  rPd.SetMerge(*stateit,msa);
206  }
207 
208  //clear transition relation
209  rPd.ClearTransRel();
210 
211  std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > readSet, multiPushSet, popPushSet, unchangedSet;
212  std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > >::iterator multimapit;
213  std::pair<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > transition;
214  std::pair<std::vector<Idx>, std::vector<Idx> > popPushPair;
215  std::vector<Idx> pop, push, pushEnd;
216  TransSet::Iterator transit;
217  PopPushSet::const_iterator ppit;
218  //partition transitions of old generator into four sets
219  //because states have only been copied (and annotated), the state indices remain
220  //the same for both generators
221  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
222  for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
223 
224  //get pop and push pair
225  pop = ppit->first;
226  push = ppit->second;
227 
228  //create transition and decide further down into which set it will be put
229  transition = std::make_pair(*transit, *ppit);
230 
231 
232  //first set contains all transitions whose event is not lambda and pop does not
233  //equal push
234  //(i. e., are of the form (p,a,x,y,q) with x != y)
235  if(!pd.IsEventLambda(transit->Ev) && pop != push){
236  readSet.insert(transition);
237  }
238 
239  //second and third set do not read anything (they have lambda events)
240  else if(pd.IsEventLambda(transit->Ev)){
241 
242  //filter out all push transitions (p,lambda,x,yx,q), they will not need to be changed
243  if(push.size() == 2 && push.back() == pop.front()){
244  unchangedSet.insert(transition);
245  continue;
246  }
247  //second set contains all transitions that push, but don't read lambda and
248  //don't effectively pop
249  //(i. e., are of the form (p,lambda,x,yax,q) with a not empty)
250  else if(push.size() > 1){
251  if(push.back() == pop.front()){
252  multiPushSet.insert(transition);
253  }
254 
255  //third set contains all transitions that pop and push
256  //(i. e., are of the form (p,lambda,x,ya,q) with a not empty, x != a)
257  else{
258  popPushSet.insert(transition);
259  }
260  }
261  //also put transitions without lambda push into third set
262  else if (!pd.IsStackSymbolLambda(push.front())) {
263  popPushSet.insert(transition);
264  }
265 
266  //put transitions with lambda push into fourth set
267  else{
268  unchangedSet.insert(transition);
269  }
270  }
271  //put all remaining transitions into fourth set as well
272  else{
273  unchangedSet.insert(transition);
274  }
275  }
276  }
277 
278 
279  //add lambda to events in case it has not already been added
280  Idx lambdaIdx = rPd.InsEvent(FAUDES_PD_LAMBDA);
281 
282  Idx newState;
283  //for every transition (p,a,x,y,q) in the first set
284  for(multimapit = readSet.begin(); multimapit != readSet.end(); multimapit++){
285 
286  //add new intermediate state and annotate it with (p,a,x,x,p)
287  newState = rPd.InsState();
288  pop = multimapit->second.first;
289  push = multimapit->second.first;
290  MergeTransition mt(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X1, pop,push);
291  rPd.SetMerge(newState, mt);
292 
293  //add transition to and from intermediate state
294  //(p,a,x,x,newstate)
295  rPd.SetTransition(multimapit->first.X1, multimapit->first.Ev, newState, pop, push);
296  //(newstate,lambda,x,y,q)
297  rPd.SetTransition(newState, lambdaIdx, multimapit->first.X2, pop, multimapit->second.second);
298  }
299 
300  //for every transition (p,lambda,x,yax,q) with a not empty in the second set
301  for(multimapit = multiPushSet.begin(); multimapit != multiPushSet.end(); multimapit++){
302 
303  //add new intermediate state and annotate it with (p,lambda,x,ax,p)
304  newState = rPd.InsState();
305  pop = multimapit->second.first;
306  push = std::vector<Idx>(multimapit->second.second.end() - multimapit->second.first.size() - 1, multimapit->second.second.end());
307  MergeTransition mt(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X1, pop,push);
308  rPd.SetMerge(newState, mt);
309 
310  //add transition to and from intermediate state
311  //(p,lambda,x,ax,newstate)
312  rPd.SetTransition(multimapit->first.X1, multimapit->first.Ev, newState, pop, push);
313  //(newstate,lambda,a,ya,q)
314  pop.clear();
315  pop.push_back(multimapit->second.second.at(multimapit->second.second.size() - multimapit->second.first.size() - 1));
316  push = std::vector<Idx>(multimapit->second.second.begin(), multimapit->second.second.end() - multimapit->second.first.size());
317  rPd.SetTransition(newState, lambdaIdx, multimapit->first.X2, pop, push);
318  }
319 
320  //for every transition (p,lambda,x,ya,q) with a not empty and x != a in the third set
321  for(multimapit = popPushSet.begin(); multimapit != popPushSet.end(); multimapit++){
322 
323  //add new intermediate state and annotate it with (p,lambda,x,lambda,p)
324  newState = rPd.InsState();
325  pop = multimapit->second.first;
326  push.clear();
327  push.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
328  MergeTransition mt(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X1, pop,push);
329  rPd.SetMerge(newState, mt);
330 
331  //add transition to and from intermediate state
332  //(p,lambda,x,lambda,newstate)
333  rPd.SetTransition(multimapit->first.X1, lambdaIdx, newState, pop, push);
334  //(newstate,lambda,lambda,ya,q)
335  pop.clear();
336  pop.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
337  push = multimapit->second.second;
338  rPd.SetTransition(newState, lambdaIdx, multimapit->first.X2, pop, push);
339  }
340 
341  //for every transitions in the fourth set
342  for(multimapit = unchangedSet.begin(); multimapit != unchangedSet.end(); multimapit++){
343 
344  //read pop and push for convenience
345  pop = multimapit->second.first;
346  push= multimapit->second.second;
347 
348  //if it is a read only transition in the form of (p,a,x,x,q), changed
349  //it to (p,a,lambda,lambda,q)
350 // if(!rPd.IsEventLambda(multimapit->first.Ev) && !pop.front().IsLambda() && pop == push ){
351 // pop.clear();
352 // pop.push_back(StackSymbol(FAUDES_PD_LAMBDA));
353 // push.clear();
354 // push.push_back(StackSymbol(FAUDES_PD_LAMBDA));
355 // }
356 //
357  //insert the transition again
358  rPd.SetTransition(multimapit->first.X1, multimapit->first.Ev, multimapit->first.X2, pop, push);
359  }
360 
361  //if changes were made, repeat recursively
362  //if lambda popping edges were added, they need to be removed first
363  if(popPushSet.size() != 0){
364  rPd = Rpp(Rep0(rPd));
365  }
366  else if(readSet.size() + multiPushSet.size() != 0){
367  rPd = Rpp(rPd);
368  }
369 
370  return rPd;
371 }
372 
373 /* *************************
374  * PrintTransitions
375  * *************************/
376 void PrintTransitions(const std::multimap<Transition, std::pair<std::vector<StackSymbol>, std::vector<StackSymbol> > >& transitions){
377  std::cout << "\nPrint Transitions:\n" << std::endl;
378  std::multimap<Transition, std::pair<std::vector<StackSymbol>, std::vector<StackSymbol> > >::const_iterator transit;
379  std::vector<StackSymbol>::const_iterator ssit;
380  std::stringstream s;
381 
382  for(transit = transitions.begin(); transit != transitions.end(); transit++){
383  s << transit->first.X1 << " " << PushdownGenerator::GlobalEventSymbolTablep()->Symbol(transit->first.Ev) << " " << transit->first.X2 << " [";
384  for(ssit = transit->second.first.begin(); ssit != transit->second.first.end(); ssit++){
385  s << ssit->Symbol() << " ";
386  }
387  s << "] [";
388  for(ssit = transit->second.second.begin(); ssit != transit->second.second.end(); ssit++){
389  s << ssit->Symbol() << " ";
390  }
391  s << "]" << std::endl;
392 
393 
394  }
395  std::cout << s.str() << std::endl;
396 }
397 
398 /* *************************
399  * Rep2
400  * *************************/
402 
403  //take a copy of the old generator
405 
406  //add lambda to events in case it has not already been added
407  Idx lambdaIdx = rPd.InsEvent(FAUDES_PD_LAMBDA);
408 
409  //annotate states of the new generator. the state indices are the same for both
410  //generators, only the annotations will be different
411  StateSet::Iterator stateit;
412  for(stateit = pd.StatesBegin(); stateit != pd.StatesEnd(); stateit++){
413  MergeStateAnnotation msa = MergeStateAnnotation(*stateit,"old");
414  rPd.SetMerge(*stateit,msa);
415  }
416 
417  std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > offendingTransSet;
418  std::pair<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > > transition;
419  std::vector<Idx> pop, push;
420  std::set< std::pair<Idx, Idx> > intermediateStates;
421  std::pair<Idx, Idx> intermediateStatePair;
422  std::map<std::pair<Idx, Idx>, Idx> mapIntermediateStates;
423  TransSet::Iterator transit;
424  PopPushSet::const_iterator ppit;
425  Idx newState;
426  //prepare an empty push vector
427  push.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
428 
429  //look for transitions that pop more than one stack symbol,
430  //(i. e. (q,w,av,v',q') with |a| = 1, |v| > 0)), save the transitions
431  //in offendingTransSet, and add intermediate states that will be connected later
432  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
433  for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
434  if(ppit->first.size() > 1){
435 
436  //save transition
437  transition = std::make_pair(*transit, *ppit);
438  offendingTransSet.insert(transition);
439 
440  //add intermediate state annotated with ((old,q),lambda,a,lambda,(old,q)), but
441  //only if it has not already been added for this particular pair of (q,a)
442  intermediateStatePair = std::make_pair(transit->X1,ppit->first.front());
443  if(intermediateStates.insert(intermediateStatePair).second){
444 
445  //add intermediate state
446  newState = rPd.InsState();
447  //and save it for connecting with transitions later on
448  mapIntermediateStates.insert(std::make_pair(intermediateStatePair,newState));
449 
450  //create annotation
451  pop.clear();
452  pop.push_back(ppit->first.front());
453  MergeTransition mt(transit->X1, lambdaIdx, transit->X1, pop, push);//note: transit->X1 from pd refers to (old,transit->X1) in the context of
454  //rPd, because state indices in pd and rPd are the same (they are copies) with
455  //only the annotations being different
456  rPd.SetMerge(newState, mt);
457  }
458  }
459  }
460  }
461 
462  std::multimap<Transition, std::pair<std::vector<Idx>, std::vector<Idx> > >::iterator offendingit;
463  Idx startState, intermediateState;
464  Idx popSymbol;
465  TransSet transCopy;
466  PopPushSet ppCopy;
467  //iterate over all offending transitions (q,w,av,v',q') to fix them
468  for(offendingit = offendingTransSet.begin(); offendingit != offendingTransSet.end(); offendingit++){
469 
470  //take a copy of the generator's transitions for iterating, because transitions will
471  //be deleted and this would mess with the iterator
472  transCopy = rPd.TransRel();
473 
474  //iterate over all transitions (q,x,ay,y',q'') starting at the same state q
475  //and popping the same stack symbol a
476  startState = offendingit->first.X1;
477  popSymbol = offendingit->second.first.front();
478  //ensure q
479  for(transit = transCopy.Begin(startState); transit != transCopy.End(startState); transit++){
480 
481  //take a copy of the transitions's pop/push pairs for iterating, because pairs
482  //will be deleted and this would mess with the iterator
483  ppCopy = rPd.PopPush(*transit);
484 
485  for(ppit = ppCopy.begin(); ppit != ppCopy.end(); ppit++){
486  //ensure a and |ay| > 1 (i. e. |y| != 0)
487  if(ppit->first.front() == popSymbol && ppit->first.size() > 1){
488 
489  //delete the transition
490  rPd.ClrTransition(*transit, ppit->first, ppit->second);
491 
492  //and insert transition to and from corresponding intermediate state
493  //get intermediate state index
494  intermediateState = mapIntermediateStates.find(std::make_pair(startState,popSymbol))->second;
495 
496  //set transition to intermediate state
497  pop.clear();
498  pop.push_back(popSymbol);
499  push.clear();
500  push.push_back(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
501  rPd.SetTransition(startState, lambdaIdx, intermediateState, pop, push);
502 
503  //set transition from intermediate state
504  pop = ppit->first;
505  pop.erase(pop.begin());
506  push = ppit->second;
507  rPd.SetTransition(intermediateState, transit->Ev, transit->X2, pop, push);
508 
509  }
510  }
511  }
512  }
513 
514  //if offending transitions were found, check again if there are offending
515  //transitions left
516  if(offendingTransSet.size() != 0){
517  rPd = Rep2(rPd);
518  }
519  return rPd;
520 }
521 
522 
523 /* *************************
524  * Nda
525  * *************************/
527 
528  PushdownGenerator rPd = pd;
529 
530  //states and transition relation will be rebuilt, so delete the existing ones
531  rPd.ClearTransRel();
532  rPd.ClearStates();
533 
534  StateSet::Iterator stateit;
535  Idx newStateAct, newStatePas;
536  std::string active = "active";
537  std::string passive = "passive";
538  std::map<Idx,std::pair<Idx,Idx> > stateMap;
539  //for insert an active and a passive state for each state of the old generator
540  for(stateit = pd.StatesBegin(); stateit != pd.StatesEnd(); stateit++){
541 
542  //active state
543  newStateAct = rPd.InsState();
544  MergeStateAnnotation mssAct(*stateit,active);
545  rPd.SetMerge(newStateAct,mssAct);
546 
547  //if the old state was a final state, the active state is final as well
548  if(pd.ExistsMarkedState(*stateit)){
549  rPd.SetMarkedState(newStateAct);
550  }
551 
552  //if the old state was the starting state, the active state is a starting state
553  //as well
554  if(pd.ExistsInitState(*stateit)){
555  rPd.SetInitState(newStateAct);
556  }
557 
558  //passive state
559  newStatePas = rPd.InsState();
560  MergeStateAnnotation mssPas(*stateit,passive);
561  rPd.SetMerge(newStatePas,mssPas);
562 
563  //save relation between old state and new states for later reference
564  stateMap.insert(std::make_pair(*stateit,std::make_pair(newStateAct,newStatePas)));
565  }
566 
567  TransSet::Iterator transit;
568  PopPushSet::const_iterator ppit;
569  std::vector<Idx> pop, push;
570  Idx startState, endState, oldStartState, oldEndState, oldEvent;
571  //insert transitions
572  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
573  for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
574 
575  //for convenience
576  pop = ppit->first;
577  push = ppit->second;
578  oldStartState = transit->X1;
579  oldEndState = transit->X2;
580  oldEvent = transit->Ev;
581 
582  //for any reading transition
583  if(!pd.IsEventLambda(oldEvent)){
584 
585  //connect active state to active state
586  startState = stateMap.find(oldStartState)->second.first;
587  endState = stateMap.find(oldEndState)->second.first;
588  rPd.SetTransition(startState,oldEvent,endState,pop,push);
589 
590  //connect passive state to active state
591  startState = stateMap.find(oldStartState)->second.second;
592  rPd.SetTransition(startState,oldEvent,endState,pop,push);
593  }
594 
595 
596  else{
597 
598  //for any pushing and popping transition
599  if(push.size() == 2 || pd.IsStackSymbolLambda(push.front())){
600 
601  //connect passive state to passive state
602  startState = stateMap.find(oldStartState)->second.second;
603  endState = stateMap.find(oldEndState)->second.second;
604  rPd.SetTransition(startState,oldEvent,endState,pop,push);
605 
606  //if the old start state was marked, connect active state to passive state
607  if(pd.ExistsMarkedState(oldStartState)){
608  startState = stateMap.find(oldStartState)->second.first;
609  rPd.SetTransition(startState,oldEvent,endState,pop,push);
610  }
611 
612  //else connect active state to active state
613  else{
614  startState = stateMap.find(oldStartState)->second.first;
615  endState = stateMap.find(oldEndState)->second.first;
616  rPd.SetTransition(startState,oldEvent,endState,pop,push);
617  }
618  }
619 
620  //should never get here
621  else{
622  std::stringstream errstr;
623  errstr << "While executing Nda(): Found transition which is neither read nor pop nor push, which is not allowed" << std::endl;
624  throw Exception("Nda", errstr.str(), 1001);
625  }
626  }
627  }
628  }
629 
630  return rPd;
631 }
632 
633 
634 } // namespace faudes
635 

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen