pd_alg_nb_sub_b_test.cpp

Go to the documentation of this file.
00001 /** @file pd_alg_nb_sub_b_test.cpp  Unit Tests */
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 #include "pd_alg_nb_sub_b_test.h"
00010 
00011 namespace faudes {
00012 
00013 /* *****************
00014  * TestRenqRenaming
00015  * *****************/
00016 void TestRenQRenaming(){
00017   std::string name = "RenQ Renaming";
00018   std::cout << "Testing " << name << " ..." <<  std::endl;
00019   
00020   std::string renameString = "old";
00021   
00022   PushdownGenerator g1 = TestGenerator1();
00023   PushdownGenerator g2 = RenQ(renameString,g1);
00024   
00025   try{
00026     StateSet::Iterator its;    
00027     for(its = g2.StatesBegin(); its != g2.StatesEnd(); its++){
00028       
00029       const MergeStateAnnotation* msa = dynamic_cast<const MergeStateAnnotation*>(g2.StateAttribute(*its).Merge());
00030       
00031       if(msa == NULL)
00032         throw Exception(name, "MergeStateAnnotation not set.", 1003);
00033       if(msa->Annotation().compare(renameString) != 0){
00034         std::stringstream errstr;
00035         errstr << "Annotation incorrect, was " << msa->Annotation() << ", but " << renameString << " was expected." << std::endl;
00036         throw Exception(name, errstr.str(), 1003);
00037       }
00038     }
00039   }
00040   catch (Exception e){ 
00041   }
00042   std::cout << "Finished " << name << std::endl;
00043 }
00044 
00045 /* *****************
00046  * TestRenQNumberOfStates
00047  * *****************/
00048 void TestRenQNumberOfStates(){
00049   std::string name = "RenQ Number of States";
00050   std::cout << "Testing " << name << " ..." <<  std::endl;
00051   
00052   std::string renameString = "old";
00053   
00054   PushdownGenerator g1 = TestGenerator1();
00055   PushdownGenerator g2 = RenQ(renameString,g1);
00056   
00057   try{
00058     if(g1.Size() != g2.Size()){
00059         std::stringstream errstr;
00060         errstr << "Incorrect, number of states, was " << g1.Size() << ", but " << g2.Size() << " was expected." << std::endl;
00061         throw Exception(name, errstr.str(), 1003);
00062     } 
00063   }
00064   catch (Exception e){ 
00065   }
00066   std::cout << "Finished " << name << std::endl;
00067 }
00068 
00069 /* *****************
00070  * TestRenGRenamingStackSymbols
00071  * *****************/
00072 void TestRenGRenamingStackSymbols(){
00073   std::string name = "RenG Renaming Stack Symbols";
00074   std::cout << "Testing " << name << " ..." <<std::endl;
00075   
00076   std::string renameString = "old";
00077   
00078   PushdownGenerator g1 = TestGenerator1();
00079   PushdownGenerator g2 = RenG(renameString,g1);
00080   
00081   try{
00082     StackSymbolSet::Iterator it;
00083     for(it = g1.StackSymbolsBegin(); it != g1.StackSymbolsEnd(); it++){
00084       //lambda does not get renamed so test for not getting renamed instead
00085       if(g2.IsStackSymbolLambda(*it)){
00086         if(!g2.StackSymbols().Exists(g2.StackSymbolName(*it))){
00087           std::stringstream errstr;
00088           errstr << "Annotation incorrect, " << g2.StackSymbolName(*it) << " was expected, but not found in the stack symbol list:\n" ;
00089           StackSymbolSet::Iterator iterr;
00090           for(iterr = g2.StackSymbolsBegin(); iterr != g2.StackSymbolsEnd(); iterr++){
00091             errstr << " " << g2.StackSymbolName(*iterr);
00092           }
00093           errstr << std::endl;
00094           throw Exception(name, errstr.str(), 1003);
00095         }
00096       }
00097       //all other symbols must get renamed
00098       else{
00099         if(!g2.StackSymbols().Exists(renameString + "-" + g2.StackSymbolName(*it))){
00100           std::stringstream errstr;
00101           errstr << "Annotation incorrect, " << renameString << "-" << g2.StackSymbolName(*it) << " was expected, but not found in the stack symbol list:\n" ;
00102           StackSymbolSet::Iterator iterr;
00103           for(iterr = g2.StackSymbolsBegin(); iterr != g2.StackSymbolsEnd(); iterr++){
00104             errstr << " " << g2.StackSymbolName(*iterr);
00105           }
00106           errstr << std::endl;
00107           throw Exception(name, errstr.str(), 1003);
00108       }
00109       }
00110   
00111     }
00112   }
00113   catch(Exception e){
00114   }
00115   std::cout << "Finished " << name << std::endl;
00116 }
00117 
00118 /* *****************
00119  * TestRenGNumberOfStackSymbols
00120  * *****************/
00121 void TestRenGNumberOfStackSymbols(){
00122   std::string name = "RenG Number of Stack Symbols";
00123   std::cout << "Testing " << name << " ..." <<  std::endl;
00124   
00125   std::string renameString = "old";
00126   
00127   PushdownGenerator g1 = TestGenerator1();
00128   PushdownGenerator g2 = RenG(renameString,g1);
00129   
00130   try{
00131      if(g1.StackSymbols().Size() != g2.StackSymbols().Size()){
00132         std::stringstream errstr;
00133         errstr << "Incorrect number of stack symbols, was " << g1.StackSymbols().Size() << ", but " << g2.StackSymbols().Size() << " was expected." << std::endl;
00134         throw Exception(name, errstr.str(), 1003);
00135     } 
00136   }
00137   catch (Exception e){ 
00138   }
00139   std::cout << "Finished " << name << std::endl;
00140 }
00141 
00142 /* *****************
00143  * TestRenGRenamingTransitions
00144  * *****************/
00145 void TestRenGRenamingTransitions(){
00146   
00147   FAUDES_TEST_DUMP("test 77",true)
00148   
00149   std::string name = "RenG Renaming Transitions";
00150   std::cout << "Testing " << name << " ..." <<  std::endl;
00151   
00152   std::string renameString = "old";
00153   
00154   PushdownGenerator g1 = TestGenerator1();
00155   PushdownGenerator g2 = RenG(renameString,g1);
00156   
00157   TransSet::Iterator tit;
00158   std::vector<Idx> oldPush, oldPop, push, pop;
00159   std::vector<Idx>::const_iterator pushit, popit;
00160   PopPushSet popPush;
00161   PopPushSet::const_iterator ppit;
00162 
00163   try{
00164     for(tit = g2.TransRelBegin(); tit != g2.TransRelEnd(); tit++){
00165       //examine all pop/push pairs
00166       popPush = g2.PopPush(*tit);
00167       for(ppit = popPush.begin(); ppit != popPush.end(); ppit++){
00168         
00169         //test pop stack symbols
00170         oldPop = ppit->first;
00171         for(popit = oldPop.begin(); popit != oldPop.end(); popit++){
00172           
00173           //everything but lambda must be renamed
00174           if(!g2.IsStackSymbolLambda(*popit)){
00175             std::string annotation = g2.StackSymbolName(*popit).substr(0, renameString.size() + 1);
00176             if(annotation.compare(renameString + "-") != 0){
00177               std::stringstream errstr;
00178               errstr << "Annotation incorrect, " << renameString << "- was expected, but symbol was " << g2.StackSymbolName(*popit) << std::endl;
00179               throw Exception(name, errstr.str(), 1003);
00180             }
00181           }
00182         }
00183         
00184         //test push stack symbols
00185         oldPush = ppit->second;
00186         for(pushit = oldPush.begin(); pushit != oldPush.end(); pushit++){
00187           
00188           //everything but lambda must be renamed
00189           if(!g2.IsStackSymbolLambda(*pushit)){
00190             std::string annotation = g2.StackSymbolName(*pushit).substr(0, renameString.size() + 1);
00191             if(annotation.compare(renameString + "-") != 0){
00192               std::stringstream errstr;
00193               errstr << "Annotation incorrect, " << renameString << "- was expected, but symbol was " << g2.StackSymbolName(*pushit) << std::endl;
00194               throw Exception(name, errstr.str(), 1003);
00195             }
00196           }
00197         }
00198       }
00199       
00200     }
00201   }
00202   catch(Exception e){
00203       FAUDES_TEST_DUMP("test 77 ERROR ",false)
00204   }
00205   std::cout << "Finished " << name << std::endl;
00206 }
00207 
00208 /* *****************
00209  * TestRep0NoLambdaPop
00210  * *****************/
00211 void TestRep0NoLambdaPop(){
00212   std::string name = "Rep0 No Lambda Pop";
00213   std::cout << "Testing " << name << " ..." <<  std::endl;
00214   
00215   PushdownGenerator g1 = TestGenerator1();
00216   PushdownGenerator g2 = Rep0(g1);
00217   
00218   try{
00219     
00220     //iterate over all transitions
00221     TransSet::Iterator tit;
00222     PopPushSet::const_iterator ppsit;
00223     for(tit = g2.TransRel().Begin(); tit != g2.TransRel().End(); tit++){
00224       
00225       //get all PopPush pairs, extract pop (first), extract foremost
00226       //stack symbol (front), and test for lambda
00227       for(ppsit = g2.PopPush(*tit).begin(); ppsit != g2.PopPush(*tit).end(); ppsit++){
00228         if(g2.IsStackSymbolLambda(ppsit->first.front())){
00229           std::stringstream errstr;
00230           errstr << "Lambda popping edges not removed, Lambda pop found in transition" << g2.TransRel().Str(*tit) << std::endl;
00231           throw Exception(name, errstr.str(), 1003);
00232         }
00233       }
00234     }
00235   }
00236    catch(Exception e){
00237   }
00238   std::cout << "Finished " << name << std::endl;
00239 }
00240 
00241 /* *****************
00242  * TestRep0AllExpectingTransition
00243  * *****************/
00244 void TestRep0AllExpectingTransition(){
00245   std::string name = "Rep0 All Expecting Transition";
00246   std::cout << "Testing " << name << " ..." <<  std::endl;
00247 
00248   PushdownGenerator g1 = TestGenerator1();
00249   PushdownGenerator g2 = Rep0(g1);
00250  
00251   //test g1 for lambda transition
00252   TransSet::Iterator tit;
00253   PopPushSet::const_iterator ppsit;
00254   bool hasLambda;
00255   for(tit = g1.TransRel().Begin(); tit != g1.TransRel().End(); tit++){
00256     
00257     //get all PopPush pairs, extract pop (first), extract foremost
00258     //stack symbol (front), and test for lambda
00259     for(ppsit = g1.PopPush(*tit).begin(); ppsit != g1.PopPush(*tit).end(); ppsit++){
00260       if(g2.IsStackSymbolLambda(ppsit->first.front())){
00261         hasLambda = true;
00262         //lambda was found, no need to search further
00263         break;
00264       }
00265     }
00266   }
00267   
00268   if(!hasLambda){
00269       std::cout << "warning: cannot perform test, because there is no lambda pop in the original generator" << std::endl;
00270       return;
00271   }
00272   
00273   //test g2 for transition (s1,ev,s2,u,uw), where u is every stack symbol
00274   //except for lambda and bottom
00275   try{
00276     
00277     //iterate over all transitions
00278     std::vector<Idx> pop, push;
00279     std::vector<Idx>::const_iterator popit, pushit;
00280     StackSymbolSet::Iterator ssit;
00281     bool transFound, symbolFound;
00282     for(tit = g2.TransRel().Begin(); tit != g2.TransRel().End(); tit++){
00283       transFound = true;
00284       
00285       //iterate over all relevant stack symbols and see if there is one PopPush
00286       //pair with pop u and push wu
00287       for(ssit = g2.StackSymbols().Begin(); ssit != g2.StackSymbols().End(); ssit++){
00288 
00289         //lambda and stack bottom are not relevant
00290         if (*ssit == g2.StackBottom() || g2.IsStackSymbolLambda(*ssit)) continue;
00291         
00292         //test PopPush pairs and find at least one (u,uw) PopPush pair per symbol
00293         symbolFound = false;
00294         for(ppsit = g2.PopPush(*tit).begin(); ppsit != g2.PopPush(*tit).end(); ppsit++){
00295 
00296           pop = ppsit->first;
00297           push = ppsit->second;
00298           //if front of pop or push are  identical, the pair is found
00299           if(pop.front() == *ssit && *push.rbegin() == *ssit){
00300             symbolFound = true;
00301             break;
00302           }
00303         }
00304         //if any one symbol has not been found, this transition is not relevant
00305         if(!symbolFound){
00306           transFound = false;
00307           break;
00308         }
00309       }
00310       //no need to look for another such transition
00311       if(transFound) break;
00312     }
00313     
00314     if(!transFound){
00315       std::stringstream errstr;
00316       errstr << "Original generator has lambda popping edge, but result generator has no edge that accepts all stack symbols" << std::endl;
00317       throw Exception(name, errstr.str(), 1003);
00318     }
00319   }
00320    catch(Exception e){
00321   }
00322   std::cout << "Finished " << name << std::endl;
00323 }
00324 
00325 /* ****************
00326  * TestRep2NumberOfTransitions
00327  * *****************/
00328 void TestRep2NumberOfStatesTransitions(){
00329   
00330   std::string name = "Rep2 Number of States and Transitions";
00331   TestStart(name);
00332   
00333   PushdownGenerator g1 = TestGenerator4();
00334   
00335   //expected resulst for this particular test generator
00336   Idx expectedNumberTransitions = 7;
00337   Idx expectedNumberStates = 6;
00338   
00339   PushdownGenerator g2 = Rep2(g1);
00340   
00341   try{
00342       
00343     //test for number of states
00344     if(g2.Size() != expectedNumberStates){
00345       std::stringstream errstr;
00346       errstr << "Number of states  was " << g2.Size() << ", but " << expectedNumberStates << " was expected." << std::endl;
00347       throw Exception(name, errstr.str(), 1003);
00348     }
00349     
00350     //test for number of transitions
00351     if(g2.TransRelSize() != expectedNumberTransitions){
00352       std::stringstream errstr;
00353       errstr << "Number of transitions incorrect" << g2.TransRelSize() << ", but " << expectedNumberTransitions << " was expected." << std::endl;
00354       throw Exception(name, errstr.str(), 1003);
00355     }
00356   }
00357   catch (Exception e){ 
00358   }
00359   
00360   TestEnd(name);
00361 }
00362 
00363 /* *****************
00364  * TestRep2Renaming
00365  * *****************/
00366 void TestRep2Renaming(){
00367   std::string name = "Rep2 Renaming";
00368   TestStart(name);
00369   
00370   std::string renameString = "old";
00371   
00372   PushdownGenerator g1 = TestGenerator4();
00373   
00374   PushdownGenerator g2 = Rep2(g1);
00375   
00376   try{
00377     StateSet::Iterator stateit;    
00378     for(stateit = g2.StatesBegin(); stateit != g2.StatesEnd(); stateit++){
00379       
00380       const MergeStateAnnotation* msa = dynamic_cast<const MergeStateAnnotation*>(g2.StateAttribute(*stateit).Merge());
00381       
00382       if(msa == NULL)
00383         throw Exception(name, "MergeStateAnnotation not set.", 1003);
00384       if(msa->Annotation().compare(renameString) != 0){
00385         std::stringstream errstr;
00386         errstr << "Annotation incorrect, was " << msa->Annotation() << ", but " << renameString << " was expected." << std::endl;
00387         throw Exception(name, errstr.str(), 1003);
00388       }
00389     }
00390   }
00391   catch (Exception e){ 
00392   }
00393   TestEnd(name);
00394 }
00395 
00396 /* ****************
00397  * TestRppReadPopPushOnly
00398  * *****************/
00399 void TestRppNumberStatesTransitions(){
00400   //TODO dont know what to expect
00401 //   std::string name = "Rpp Number States Transitions";
00402 //   TestStart(name);
00403 //   
00404 //   PushdownGenerator g1 = TestGenerator6();
00405 //   
00406 //   PushdownGenerator g2 = Rpp(g1);
00407 //   try{
00408 //     //number of states must be 7
00409 //     if(g2.Size() != 7){
00410 //       std::stringstream errstr;
00411 //       errstr << "Number of states was expected to be 7, but was " << g2.Size() << "." << std::endl;
00412 //       throw Exception(name, errstr.str(), 1003);
00413 //     }
00414 //     
00415 //     TransSet::Iterator transit;    
00416 //     PopPushSet::const_iterator ppit;
00417 //     //number of transitions must be 10
00418 //     int transCount = 0;
00419 //     for(transit = g2.TransRelBegin(); transit != g2.TransRelEnd(); transit++){
00420 //       transCount += g2.PopPush(*transit).size();
00421 //     }
00422 //     
00423 //     if(transCount != 10){
00424 //       std::stringstream errstr;
00425 //       errstr << "Number of transitions was expected to be 10, but was " << transCount << "." << std::endl;
00426 //       throw Exception(name, errstr.str(), 1003);
00427 //     }
00428 //   }
00429 //   catch (Exception e){ 
00430 //   }
00431 //   TestEnd(name);
00432 }
00433 
00434 /* ****************
00435  * TestRppReadPopPushOnly
00436  * *****************/
00437 void TestRppReadPopPushOnly(){
00438   std::string name = "Rpp Read Pop Push Only";
00439   TestStart(name);
00440   
00441   PushdownGenerator g1 = TestGenerator6();
00442   
00443   PushdownGenerator g2 = Rpp(g1);
00444   try{
00445     TransSet::Iterator transit;    
00446     PopPushSet::const_iterator ppit;
00447     std::vector<Idx> pop, push;
00448     std::vector<Idx>::const_iterator ssit;
00449     for(transit = g2.TransRelBegin(); transit != g2.TransRelEnd(); transit++){
00450       for(ppit = g2.PopPushBegin(*transit); ppit != g2.PopPushEnd(*transit); ppit++){
00451         
00452         //read pop and push for convenience
00453         pop = ppit->first;
00454         push = ppit->second;
00455         
00456         //check for read only transition
00457         if(!g2.IsEventLambda(transit->Ev) &&
00458           pop == push){
00459           continue;
00460         }
00461         //check for pop only transition
00462         else if(g2.IsEventLambda(transit->Ev) &&
00463           !g2.IsStackSymbolLambda(pop.front()) &&
00464           pop.size() == 1 &&
00465           g2.IsStackSymbolLambda(push.front())){
00466           continue;
00467         }
00468         //check for push only transition
00469         else if(g2.IsEventLambda(transit->Ev) &&
00470           push.size() == 2 &&
00471           pop.size() == 1 &&
00472           pop.front() == push.back()){
00473           continue;
00474         }
00475         //error
00476         else{
00477           std::stringstream errstr;
00478           errstr << "Transition (" << transit->X1 << ", " << g2.EventName(transit->Ev) << ", " << transit->X2 << ") with pop [";
00479           for(ssit = pop.begin(); ssit != pop.end(); ssit++){
00480             errstr << " " << g2.StackSymbolName(*ssit);
00481           }
00482           errstr << "] and push [";
00483           for(ssit = push.begin(); ssit != push.end(); ssit++){
00484             errstr << " " << g2.StackSymbolName(*ssit);
00485           }
00486           errstr << "] was neither read nor pop nor push." << std::endl;
00487           throw Exception(name, errstr.str(), 1003);
00488         }
00489       }
00490     }
00491   }
00492   catch (Exception e){ 
00493   }
00494   TestEnd(name);
00495 }
00496 
00497 /* ****************
00498  * TestNdaActivePassive
00499  * *****************/
00500 void TestNdaActivePassive(){
00501   std::string name = "Nda Active Passive";
00502   TestStart(name);
00503   
00504   PushdownGenerator g1 = TestGenerator7();
00505   PushdownGenerator g2 = Nda(g1);
00506   
00507   try{
00508     //the number of transitions must have doubled
00509     if(2*g1.States().Size() != g2.States().Size()){
00510       std::stringstream errstr;
00511       errstr << "Number of states incorrect, was" << g2.States().Size() << ", but " << 2*g1.States().Size() << " was expected." << std::endl;
00512       throw Exception(name, errstr.str(), 1003);
00513     }
00514     
00515     StateSet::Iterator stateit;
00516     int active = 0;
00517     int passive = 0;
00518     //there must be an equal amount of active and passive states
00519     for(stateit = g2.StatesBegin(); stateit != g2.StatesEnd(); stateit++){
00520       
00521       const MergeStateAnnotation* msa = dynamic_cast<const MergeStateAnnotation*>(g2.StateAttribute(*stateit).Merge());
00522       
00523       if(msa == NULL)
00524         throw Exception(name, "MergeStateAnnotation not set.", 1003);
00525       
00526       if(msa->Annotation().compare("active") == 0){
00527         active++;
00528       }
00529       else if(msa->Annotation().compare("passive") == 0){
00530         passive++;
00531       }
00532       else{
00533         std::stringstream errstr;
00534         errstr << "Annotation incorrect, was " << msa->Annotation() << ", but either active or passive was expected." << std::endl;
00535         throw Exception(name, errstr.str(), 1003);
00536       }
00537     }
00538     if(active != passive){
00539       std::stringstream errstr;
00540       errstr << "There were " <<  active << " active states and " << passive << " passive states, but equal numbers were expected." << std::endl;
00541       throw Exception(name, errstr.str(), 1003);
00542     }
00543   }
00544   catch (Exception e){ 
00545   }
00546   
00547   TestEnd(name);
00548 }
00549 
00550 /* ****************
00551  * TestNdaTransitions
00552  * *****************/
00553 void TestNdaTransitions(){
00554   std::string name = "Nda Transitions";
00555   TestStart(name);
00556   
00557   PushdownGenerator g1 = TestGenerator7();
00558   PushdownGenerator g2 = Nda(g1);
00559   
00560   //put together expected transitions for later comparison
00561   std::set<std::pair<Idx,Idx> > expectedTransitions;
00562   expectedTransitions.insert(std::make_pair(1,3));
00563   expectedTransitions.insert(std::make_pair(1,5));
00564   expectedTransitions.insert(std::make_pair(2,3));
00565   expectedTransitions.insert(std::make_pair(2,6));
00566   expectedTransitions.insert(std::make_pair(3,8));
00567   expectedTransitions.insert(std::make_pair(4,8));
00568   expectedTransitions.insert(std::make_pair(5,3));
00569   expectedTransitions.insert(std::make_pair(6,4));
00570   expectedTransitions.insert(std::make_pair(7,6));
00571   expectedTransitions.insert(std::make_pair(8,6));
00572   
00573   try{
00574     TransSet::Iterator transit;
00575     for(transit = g2.TransRelBegin(); transit != g2.TransRelEnd(); transit++){
00576 
00577       if(expectedTransitions.erase(std::make_pair(transit->X1, transit->X2)) == 0){
00578         std::stringstream errstr;
00579         errstr << "Transition from state " << transit->X1 << " to state " << transit->X2 << " found, but was not expected." << std::endl;
00580         throw Exception(name, errstr.str(), 1003);
00581       }
00582     }
00583     
00584     if(expectedTransitions.size() != 0){
00585       std::stringstream errstr;
00586       errstr << "Not all expected transitions were found." << std::endl;
00587       throw Exception(name, errstr.str(), 1003);
00588     }
00589   }
00590   catch (Exception e){ 
00591   }
00592   
00593   TestEnd(name);
00594 }
00595 
00596 /* *****************
00597  * TestRenQ
00598  * *****************/
00599 void TestRenQ(){
00600   TestRenQRenaming();
00601   //TestRenQNumberOfStates();
00602 }
00603 
00604 /* *****************
00605  * TestRenG
00606  * *****************/
00607 void TestRenG(){
00608   TestRenGRenamingStackSymbols();  
00609   TestRenGNumberOfStackSymbols();
00610   TestRenGRenamingTransitions();
00611 }
00612 
00613 /* *****************
00614  * TestRep0
00615  * *****************/
00616 void TestRep0(){
00617   TestRep0NoLambdaPop();
00618   TestRep0AllExpectingTransition();
00619 }
00620 
00621 /* ****************
00622  * TestRpp
00623  * *****************/
00624 void TestRpp(){
00625   TestRppNumberStatesTransitions();
00626   TestRppReadPopPushOnly();
00627 }
00628 
00629 /* *****************
00630  * TestRep2
00631  * *****************/
00632 void TestRep2(){
00633   
00634   TestRep2NumberOfStatesTransitions();
00635   TestRep2Renaming();
00636 }
00637 
00638 /* *****************
00639  * TestNda
00640  * *****************/
00641 void TestNda(){
00642   
00643   TestNdaActivePassive();
00644   TestNdaTransitions();
00645 }
00646 
00647 } // namespace faudes
00648 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen