pd_alg_opt.cppGo to the documentation of this file.00001 /** @file pd_alg_opt.cpp functions for optimizations*/ 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_opt.h" 00011 00012 namespace faudes { 00013 00014 /* ************************* 00015 * TrimStackSymbols 00016 * *************************/ 00017 PushdownGenerator TrimStackSymbols(const PushdownGenerator& pd){ 00018 00019 //copy the generator 00020 PushdownGenerator rPd = pd; 00021 00022 StackSymbolSet usedSymbols; 00023 TransSet::Iterator transit; 00024 PopPushSet::const_iterator ppit; 00025 std::vector<Idx>::const_iterator ssit; 00026 std::vector<Idx> pop, push; 00027 //iterate over all transitions to get all used stack symbols 00028 for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){ 00029 for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){ 00030 00031 //extract pop and push 00032 pop = ppit->first; 00033 push = ppit->second; 00034 00035 //extract stack symbols 00036 for(ssit = pop.begin(); ssit != pop.end(); ssit++){ 00037 usedSymbols.Insert(*ssit); 00038 } 00039 //extract stack symbols 00040 for(ssit = push.begin(); ssit != push.end(); ssit++){ 00041 usedSymbols.Insert(*ssit); 00042 } 00043 } 00044 } 00045 00046 //delete all stack symbols except for the used ones 00047 StackSymbolSet::Iterator currentssit; 00048 for(currentssit = pd.StackSymbolsBegin(); currentssit != pd.StackSymbolsEnd(); currentssit++){ 00049 00050 //stack symbol is not used and is not lambda 00051 if(!usedSymbols.Exists(*currentssit) && !pd.IsStackSymbolLambda(*currentssit)){ 00052 rPd.DelStackSymbol(*currentssit); 00053 } 00054 } 00055 00056 return rPd; 00057 } 00058 00059 /* ************************* 00060 * RemoveUselessTransitions 00061 * *************************/ 00062 PushdownGenerator RemoveUselessTransitions(const PushdownGenerator& pd){ 00063 00064 //generator to return 00065 PushdownGenerator rPd = pd; 00066 00067 TransSet::Iterator transOutit, transInit; 00068 PopPushSet::const_iterator ppOutit, ppInit; 00069 //iterate over all transitions (q, a, uv, w, q') 00070 for(transOutit = pd.TransRelBegin(); transOutit != pd.TransRelEnd(); transOutit++){ 00071 00072 //get all possible stack tops for state q 00073 Idx q = transOutit->X1; 00074 StackSymbolSet possibleStackTops = GetPossibleStackTops(pd, StateSet(), q); 00075 00076 //iterate over pop-push-sets 00077 for(ppOutit = pd.PopPushBegin(*transOutit); ppOutit != pd.PopPushEnd(*transOutit); ppOutit++){ 00078 00079 //get the symbol v that gets popped from the stack first 00080 Idx popSymbol = ppOutit->first.back(); 00081 00082 //if the current pop symbol is not a possible stack top, delete the current 00083 //transition 00084 if(!possibleStackTops.Exists(popSymbol) && !pd.IsStackSymbolLambda(popSymbol)){ 00085 rPd.ClrTransition(*transOutit, ppOutit->first, ppOutit->second); 00086 } 00087 } 00088 } 00089 00090 //remove transition (p, lambda, u, u, q) that contribute nothing ("lambda read"); 00091 00092 //save generator for iterating 00093 PushdownGenerator tempPd = rPd; 00094 //save X2-sorted transition set for iterating 00095 TTransSet<TransSort::X2EvX1> transitionsByX2; 00096 rPd.TransRel().ReSort(transitionsByX2); 00097 //iterate over all transitions (p, lambda, u, u, q) 00098 for(transInit = tempPd.TransRelBegin(); transInit != tempPd.TransRelEnd(); transInit++){ 00099 00100 //the event must be lambda 00101 if(!rPd.IsEventLambda(transInit->Ev)){ 00102 continue; 00103 } 00104 00105 00106 //iterate over pop push pairs 00107 for(ppInit = tempPd.PopPushBegin(*transInit); ppInit != tempPd.PopPushEnd(*transInit); ppInit++){ 00108 00109 //pop must equal push 00110 if(ppInit->first.size() != 1 || ppInit->first != ppInit->second){ 00111 continue; 00112 } 00113 00114 //get the target state q and stack symbol u 00115 Idx q = transInit->X2; 00116 Idx u = ppInit->first.front(); 00117 00118 //find all transitions (q, a, u, v, r) originating at q with pop u 00119 for(transOutit = tempPd.TransRelBegin(q); transOutit != tempPd.TransRelEnd(q); transOutit++){ 00120 00121 //the event must be lambda 00122 // if(!rPd.IsEventLambda(transOutit->Ev)){ 00123 // continue; 00124 // } 00125 00126 //iterate over pop push pairs 00127 for(ppOutit = tempPd.PopPushBegin(*transOutit); ppOutit != tempPd.PopPushEnd(*transOutit); ppOutit++){ 00128 00129 //test for u pop 00130 if(ppOutit->first.size() == 1 && ppOutit->first.front() == u){ 00131 00132 //delete transition (p, lambda, u, u, q) 00133 rPd.ClrTransition(*transInit, ppInit->first, ppInit->second); 00134 00135 //insert transition (p, a, u, v, r) 00136 rPd.SetTransition(transInit->X1, transOutit->Ev, transOutit->X2, ppOutit->first, ppOutit->second); 00137 } 00138 } 00139 } 00140 } 00141 } 00142 00143 //there might be unreachable states and transitions left, so make the generator //accessible 00144 rPd.Accessible(); 00145 00146 return rPd; 00147 } 00148 00149 /* ************************* 00150 * GetPossibleStackTops 00151 * *************************/ 00152 StackSymbolSet GetPossibleStackTops(const PushdownGenerator& pd, const StateSet& examinedStates, Idx q){ 00153 00154 StackSymbolSet possibleStackTops; 00155 00156 //if the current state has already been examined, it will contribute nothing new 00157 if(examinedStates.Exists(q)){ 00158 return possibleStackTops; 00159 } 00160 00161 //mark the current state as examined 00162 StateSet currentExaminedStates = examinedStates; 00163 currentExaminedStates.Insert(q); 00164 00165 //if the current state is an init state, it will contribute at least the stack bottom 00166 if(pd.ExistsInitState(q)){ 00167 possibleStackTops.Insert(pd.StackBottom()); 00168 } 00169 00170 //sort transitions by end state 00171 TTransSet<TransSort::X2EvX1> transByX2; 00172 pd.TransRel().ReSort(transByX2); 00173 00174 TTransSet<TransSort::X2EvX1>::Iterator transit; 00175 PopPushSet::const_iterator ppit; 00176 //iterate over all transitions (p, b, u, w'v', q) going into q and collect all 00177 //stack symbols w' 00178 for(transit = transByX2.BeginByX2(q); transit != transByX2.EndByX2(q); transit++){ 00179 for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){ 00180 00181 //get the symbol w' that gets pushed onto the stack last 00182 Idx pushSymbol = ppit->second.front(); 00183 00184 //if w' and u are lambda, get the transition's predecessor state stack tops 00185 if(pd.IsStackSymbolLambda(pushSymbol) && pd.IsStackSymbolLambda(ppit->first.front())){ 00186 StackSymbolSet predStackTops = GetPossibleStackTops(pd, currentExaminedStates, transit->X1); 00187 possibleStackTops.SetUnion(predStackTops); 00188 } 00189 //if only w' is lambda, every stack symbol can be a predecessor, because it might 00190 //be under the stack top, about which nothing is known 00191 else if(pd.IsStackSymbolLambda(pushSymbol)){ 00192 possibleStackTops.SetUnion(pd.StackSymbols()); 00193 possibleStackTops.Erase(pd.StackSymbolIndex(FAUDES_PD_LAMBDA)); 00194 break; 00195 } 00196 //if w' is not lambda, add w' to the possible stack tops 00197 else{ 00198 possibleStackTops.Insert(pushSymbol); 00199 } 00200 } 00201 } 00202 00203 return possibleStackTops; 00204 } 00205 00206 } // namespace faudes 00207 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |