pd_lang_k.cpp

Go 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