pd_alg_opt.cpp
Go to the documentation of this file.
1 /** @file pd_alg_opt.cpp functions for optimizations*/
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_opt.h"
11 
12 namespace faudes {
13 
14 /* *************************
15  * TrimStackSymbols
16  * *************************/
18 
19  //copy the generator
20  PushdownGenerator rPd = pd;
21 
22  StackSymbolSet usedSymbols;
23  TransSet::Iterator transit;
24  PopPushSet::const_iterator ppit;
25  std::vector<Idx>::const_iterator ssit;
26  std::vector<Idx> pop, push;
27  //iterate over all transitions to get all used stack symbols
28  for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){
29  for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
30 
31  //extract pop and push
32  pop = ppit->first;
33  push = ppit->second;
34 
35  //extract stack symbols
36  for(ssit = pop.begin(); ssit != pop.end(); ssit++){
37  usedSymbols.Insert(*ssit);
38  }
39  //extract stack symbols
40  for(ssit = push.begin(); ssit != push.end(); ssit++){
41  usedSymbols.Insert(*ssit);
42  }
43  }
44  }
45 
46  //delete all stack symbols except for the used ones
47  StackSymbolSet::Iterator currentssit;
48  for(currentssit = pd.StackSymbolsBegin(); currentssit != pd.StackSymbolsEnd(); currentssit++){
49 
50  //stack symbol is not used and is not lambda
51  if(!usedSymbols.Exists(*currentssit) && !pd.IsStackSymbolLambda(*currentssit)){
52  rPd.DelStackSymbol(*currentssit);
53  }
54  }
55 
56  return rPd;
57 }
58 
59 /* *************************
60  * RemoveUselessTransitions
61  * *************************/
63 
64  //generator to return
65  PushdownGenerator rPd = pd;
66 
67  TransSet::Iterator transOutit, transInit;
68  PopPushSet::const_iterator ppOutit, ppInit;
69  //iterate over all transitions (q, a, uv, w, q')
70  for(transOutit = pd.TransRelBegin(); transOutit != pd.TransRelEnd(); transOutit++){
71 
72  //get all possible stack tops for state q
73  Idx q = transOutit->X1;
74  StackSymbolSet possibleStackTops = GetPossibleStackTops(pd, StateSet(), q);
75 
76  //iterate over pop-push-sets
77  for(ppOutit = pd.PopPushBegin(*transOutit); ppOutit != pd.PopPushEnd(*transOutit); ppOutit++){
78 
79  //get the symbol v that gets popped from the stack first
80  Idx popSymbol = ppOutit->first.back();
81 
82  //if the current pop symbol is not a possible stack top, delete the current
83  //transition
84  if(!possibleStackTops.Exists(popSymbol) && !pd.IsStackSymbolLambda(popSymbol)){
85  rPd.ClrTransition(*transOutit, ppOutit->first, ppOutit->second);
86  }
87  }
88  }
89 
90  //remove transition (p, lambda, u, u, q) that contribute nothing ("lambda read");
91 
92  //save generator for iterating
93  PushdownGenerator tempPd = rPd;
94  //save X2-sorted transition set for iterating
95  TTransSet<TransSort::X2EvX1> transitionsByX2;
96  rPd.TransRel().ReSort(transitionsByX2);
97  //iterate over all transitions (p, lambda, u, u, q)
98  for(transInit = tempPd.TransRelBegin(); transInit != tempPd.TransRelEnd(); transInit++){
99 
100  //the event must be lambda
101  if(!rPd.IsEventLambda(transInit->Ev)){
102  continue;
103  }
104 
105 
106  //iterate over pop push pairs
107  for(ppInit = tempPd.PopPushBegin(*transInit); ppInit != tempPd.PopPushEnd(*transInit); ppInit++){
108 
109  //pop must equal push
110  if(ppInit->first.size() != 1 || ppInit->first != ppInit->second){
111  continue;
112  }
113 
114  //get the target state q and stack symbol u
115  Idx q = transInit->X2;
116  Idx u = ppInit->first.front();
117 
118  //find all transitions (q, a, u, v, r) originating at q with pop u
119  for(transOutit = tempPd.TransRelBegin(q); transOutit != tempPd.TransRelEnd(q); transOutit++){
120 
121  //the event must be lambda
122 // if(!rPd.IsEventLambda(transOutit->Ev)){
123 // continue;
124 // }
125 
126  //iterate over pop push pairs
127  for(ppOutit = tempPd.PopPushBegin(*transOutit); ppOutit != tempPd.PopPushEnd(*transOutit); ppOutit++){
128 
129  //test for u pop
130  if(ppOutit->first.size() == 1 && ppOutit->first.front() == u){
131 
132  //delete transition (p, lambda, u, u, q)
133  rPd.ClrTransition(*transInit, ppInit->first, ppInit->second);
134 
135  //insert transition (p, a, u, v, r)
136  rPd.SetTransition(transInit->X1, transOutit->Ev, transOutit->X2, ppOutit->first, ppOutit->second);
137  }
138  }
139  }
140  }
141  }
142 
143  //there might be unreachable states and transitions left, so make the generator //accessible
144  rPd.Accessible();
145 
146  return rPd;
147 }
148 
149 /* *************************
150  * GetPossibleStackTops
151  * *************************/
152 StackSymbolSet GetPossibleStackTops(const PushdownGenerator& pd, const StateSet& examinedStates, Idx q){
153 
154  StackSymbolSet possibleStackTops;
155 
156  //if the current state has already been examined, it will contribute nothing new
157  if(examinedStates.Exists(q)){
158  return possibleStackTops;
159  }
160 
161  //mark the current state as examined
162  StateSet currentExaminedStates = examinedStates;
163  currentExaminedStates.Insert(q);
164 
165  //if the current state is an init state, it will contribute at least the stack bottom
166  if(pd.ExistsInitState(q)){
167  possibleStackTops.Insert(pd.StackBottom());
168  }
169 
170  //sort transitions by end state
172  pd.TransRel().ReSort(transByX2);
173 
175  PopPushSet::const_iterator ppit;
176  //iterate over all transitions (p, b, u, w'v', q) going into q and collect all
177  //stack symbols w'
178  for(transit = transByX2.BeginByX2(q); transit != transByX2.EndByX2(q); transit++){
179  for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){
180 
181  //get the symbol w' that gets pushed onto the stack last
182  Idx pushSymbol = ppit->second.front();
183 
184  //if w' and u are lambda, get the transition's predecessor state stack tops
185  if(pd.IsStackSymbolLambda(pushSymbol) && pd.IsStackSymbolLambda(ppit->first.front())){
186  StackSymbolSet predStackTops = GetPossibleStackTops(pd, currentExaminedStates, transit->X1);
187  possibleStackTops.SetUnion(predStackTops);
188  }
189  //if only w' is lambda, every stack symbol can be a predecessor, because it might
190  //be under the stack top, about which nothing is known
191  else if(pd.IsStackSymbolLambda(pushSymbol)){
192  possibleStackTops.SetUnion(pd.StackSymbols());
193  possibleStackTops.Erase(pd.StackSymbolIndex(FAUDES_PD_LAMBDA));
194  break;
195  }
196  //if w' is not lambda, add w' to the possible stack tops
197  else{
198  possibleStackTops.Insert(pushSymbol);
199  }
200  }
201  }
202 
203  return possibleStackTops;
204 }
205 
206 } // namespace faudes
207 

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