pd_alg_nb_sub_b_test.cppGo 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 |