pd_lang_k.cppGo to the documentation of this file.00001 /** @file pd_lang_k.cpp Test class to derive strings from pushdown automata */ 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_lang_k.h" 00011 00012 namespace faudes { 00013 00014 std::set<std::string> LangK::FindLangK(uint k, bool showStack){ 00015 00016 Idx i = pd.InitState(); 00017 std::string word = ""; 00018 std::vector<Idx> stack; 00019 stack.push_back(pd.StackBottom()); 00020 this->k = k; 00021 words.clear(); 00022 //search for words 00023 Traverse(i,word,stack,0,showStack); 00024 return words; 00025 } 00026 00027 void LangK::PrintWords(){ 00028 std::cout << "found the following words while traversing at most " << k << " transitions:" << std::endl; 00029 std::set<std::string>::iterator it; 00030 for(it = words.begin(); it != words.end(); it++){ 00031 std::cout << *it << std::endl; 00032 } 00033 } 00034 00035 void LangK::Traverse(Idx i, std::string word, std::vector<Idx> stack, uint depth, bool showStack){ 00036 00037 00038 //print current state for better debugging visualization 00039 if(showStack){ 00040 std::cout<< "Traverse("<<i<<","<< word <<","; 00041 std::vector<Idx>::reverse_iterator stackit; 00042 for(stackit = stack.rbegin(); stackit != stack.rend(); stackit++){ 00043 std::cout << " " << pd.StackSymbolName(*stackit); 00044 } 00045 std::cout<<"), depth " << depth <<std::endl; 00046 } 00047 00048 00049 //add word if current state is final state 00050 if(pd.ExistsMarkedState(i)){ 00051 if(word.compare("") == 0){ 00052 words.insert(FAUDES_PD_LAMBDA); 00053 } 00054 else{ 00055 words.insert(word); 00056 } 00057 } 00058 00059 //test if final word length is reached 00060 if(depth == k){ 00061 //add current word with indication that it is not finished and only if its not already been inserted 00062 if(!pd.ExistsMarkedState(i)){ 00063 words.insert(word + " ...?"); 00064 } 00065 //stop recursion 00066 return; 00067 } 00068 00069 00070 TransSet::Iterator it; 00071 std::vector<Idx> pop, currentStack; 00072 std::vector<Idx>::const_iterator itpush, itpop; 00073 PopPushSet popPush; 00074 PopPushSet::const_iterator ppit; 00075 std::vector<Idx>::const_reverse_iterator itstack; 00076 uint j; 00077 //examine all transitions with i as start state 00078 for(it = pd.TransRelBegin(i); it != pd.TransRelEnd(i); it++){ 00079 00080 //examine all pop/push pairs of the current transition 00081 popPush = pd.PopPush(*it); 00082 for(ppit = popPush.begin(); ppit != popPush.end(); ppit++){ 00083 00084 //take copy of current stack to work on 00085 currentStack = stack; 00086 00087 //test if pop is lambda pop 00088 if(pd.IsStackSymbolLambda(ppit->first.front())){ 00089 //pop is not necessary since it's a lambda pop 00090 //push onto stack, but don't push lambda! 00091 if(pd.IsStackSymbolLambda(!ppit->second.front())){ 00092 currentStack.insert(currentStack.end(), ppit->second.rbegin(), ppit->second.rend()); 00093 } 00094 //traverse next state 00095 std::string newWord = word; 00096 if(!pd.IsEventLambda(it->Ev)){ 00097 newWord = word + pd.EventName(it->Ev) + " "; 00098 } 00099 Traverse(it->X2,newWord,currentStack, depth+1,showStack); 00100 continue; 00101 } 00102 00103 //pop is no lambda pop 00104 //test if pop matches stack top 00105 itpop = ppit->first.begin(); 00106 for(itstack = currentStack.rbegin(); itstack != currentStack.rend(); itstack++){ 00107 00108 //stack top and pop are not equal, stop comparison 00109 if(*itstack != *itpop){ 00110 break; 00111 } 00112 00113 //If all pop elements were equal and the end of pop is reached, then pop has been fully compared and is therefore equal to the stack top 00114 itpop++; 00115 if(itpop == ppit->first.end()){ 00116 00117 //pop from stack 00118 for(j = 0; j < ppit->first.size(); j++){ 00119 currentStack.pop_back(); 00120 } 00121 //push onto stack, but don't push lambda! 00122 if(!pd.IsStackSymbolLambda(ppit->second.front())){ 00123 currentStack.insert(currentStack.end(), ppit->second.rbegin(), ppit->second.rend()); 00124 } 00125 //traverse next state 00126 std::string newWord = word; 00127 if(!pd.IsEventLambda(it->Ev)){ 00128 newWord = word + pd.EventName(it->Ev) + " "; 00129 } 00130 Traverse(it->X2,newWord,currentStack, depth+1,showStack); 00131 break; 00132 }; 00133 00134 } 00135 } 00136 00137 } 00138 } 00139 00140 00141 } // namespace faudes 00142 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |