libFAUDES

Sections

Index

cfl_parallel.cpp

Go to the documentation of this file.
00001 /** @file cfl_parallel.cpp parallel composition */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2006  Bernd Opitz
00006    Exclusive copyright is granted to Klaus Schmidt
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2.1 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with this library; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00021 
00022 
00023 #include "cfl_parallel.h"
00024 
00025 namespace faudes {
00026 
00027 // Parallel(rGen1, rGen2, res)
00028 void Parallel(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00029   // helpers:
00030   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00031   // prepare result
00032   vGenerator* pResGen = &rResGen;
00033   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00034     pResGen= rResGen.New();
00035   }
00036   // doit
00037   Parallel(rGen1, rGen2, rcmap, *pResGen);
00038   // set statenames
00039   if (rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00040     SetComposedStateNames(rGen1, rGen2, rcmap, *pResGen); 
00041   else
00042     pResGen->ClearStateNames();
00043   // copy result
00044   if(pResGen != &rResGen) {
00045     rResGen = *pResGen;
00046     delete pResGen;
00047   }
00048 }
00049  
00050 
00051 // Parallel for vGenerators, transparent for event attributes.
00052 void aParallel(
00053   const vGenerator& rGen1,
00054   const vGenerator& rGen2,
00055   vGenerator& rResGen) 
00056 {
00057 
00058   // inputs have to agree on attributes of shared events:
00059   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00060 
00061   // prepare result
00062   vGenerator* pResGen = &rResGen;
00063   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00064     pResGen= rResGen.New();
00065   }
00066 
00067   // make product composition of inputs
00068   Parallel(rGen1,rGen2,*pResGen);
00069 
00070   // copy all attributes of input alphabets
00071   if(careattr) {
00072     pResGen->EventAttributes(rGen1.Alphabet());
00073     pResGen->EventAttributes(rGen2.Alphabet());
00074   }
00075 
00076   // copy result
00077   if(pResGen != &rResGen) {
00078     pResGen->Move(rResGen);
00079     delete pResGen;
00080   }
00081 
00082 }
00083 
00084 
00085 // Parallel for multiple vGenerators, transparent for event attributes.
00086 void aParallel(
00087   const GeneratorVector& rGenVec,
00088   vGenerator& rResGen) 
00089 {
00090 
00091   // inputs have to agree on attributes of pairwise shared events:
00092   bool careattr=true;
00093   for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++)
00094     for(GeneratorVector::Position j=0; j<i; j++) 
00095       if(!rGenVec.At(i).Alphabet().EqualAttributes(rGenVec.At(j).Alphabet()))
00096         careattr=false;
00097 
00098   // ignore empty
00099   if(rGenVec.Size()==0) {
00100     return;
00101   }
00102 
00103   // copy first
00104   rResGen=rGenVec.At(0);
00105 
00106   // run parallel on others
00107   for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) 
00108     Parallel(rGenVec.At(i),rResGen,rResGen);
00109 
00110   // fix alphabet
00111   if(careattr) {
00112     for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++) 
00113       rResGen.EventAttributes(rGenVec.At(i).Alphabet());
00114   }
00115 
00116 }
00117 
00118 
00119 // Parallel(rGen1, rGen2, rReverseCompositionMap, mark1, mark2, res)
00120 void Parallel(
00121   const vGenerator& rGen1, const vGenerator& rGen2, 
00122   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00123   StateSet& rMark1,
00124   StateSet& rMark2,
00125   vGenerator& rResGen)
00126 {
00127 
00128   // do the composition
00129   Parallel(rGen1,rGen2,rReverseCompositionMap,rResGen);
00130 
00131   // clear marking
00132   rMark1.Clear();
00133   rMark2.Clear();
00134 
00135   // catch special cases: a
00136   if(rGen1.AlphabetSize()==0) {
00137     rMark2=rGen2.MarkedStates();
00138     return;
00139   }
00140 
00141   // catch special cases: b
00142   if(rGen2.AlphabetSize()==0) {
00143     rMark1=rGen1.MarkedStates();
00144     return;
00145   }
00146 
00147   // retrieve marking from reverse composition map
00148   std::map< std::pair<Idx,Idx>, Idx>::iterator rit;
00149   for(rit=rReverseCompositionMap.begin(); rit!=rReverseCompositionMap.end(); ++rit){
00150     if(rGen1.ExistsMarkedState(rit->first.first)) rMark1.Insert(rit->second);
00151     if(rGen2.ExistsMarkedState(rit->first.second)) rMark2.Insert(rit->second);
00152   }
00153 }
00154 
00155 
00156 // Parallel(rGen1, rGen2, rReverseCompositionMap, mark1, mark2, res)
00157 void Parallel(
00158   const vGenerator& rGen1, const vGenerator& rGen2, 
00159   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00160   vGenerator& rResGen)
00161 {
00162   FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
00163 
00164   // special case: empty alphabet
00165   if(rGen1.AlphabetSize()==0) {
00166     rResGen=rGen2;
00167     rResGen.Name(rGen2.Name());
00168     return;
00169   }
00170 
00171   // special case: empty alphabet
00172   if(rGen2.AlphabetSize()==0) {
00173     rResGen=rGen1;
00174     rResGen.Name(rGen1.Name());
00175     return;
00176   }
00177 
00178   // prepare result
00179   vGenerator* pResGen = &rResGen;
00180   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00181     pResGen= rResGen.New();
00182   }
00183   pResGen->Clear();
00184   pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
00185 
00186   // create res alphabet
00187   EventSet::Iterator eit;
00188   for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00189     pResGen->InsEvent(*eit);
00190   }
00191   for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00192     pResGen->InsEvent(*eit);
00193   }
00194   FD_DF("Parallel: inserted indices in rResGen.alphabet( "
00195       << pResGen->AlphabetToString() << ")");
00196 
00197   // shared events
00198   EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00199   FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
00200 
00201   // todo stack
00202   std::stack< std::pair<Idx,Idx> > todo;
00203   // current pair, new pair
00204   std::pair<Idx,Idx> currentstates, newstates;
00205   // state
00206   Idx tmpstate;  
00207   StateSet::Iterator lit1, lit2;
00208   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00209   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00210 
00211   // push all combinations of initial states on todo stack
00212   FD_DF("Parallel: adding all combinations of initial states to todo:");
00213   for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00214     for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00215       currentstates = std::make_pair(*lit1, *lit2);
00216       todo.push(currentstates);
00217       tmpstate = pResGen->InsInitState();
00218       rReverseCompositionMap[currentstates] = tmpstate;
00219       FD_DF("Parallel:   (" << *lit1 << "|" << *lit2 << ") -> " 
00220           << rReverseCompositionMap[currentstates]);
00221     }
00222   }
00223 
00224   // start algorithm
00225   FD_DF("Parallel: processing reachable states:");
00226   while (! todo.empty()) {
00227     // allow for user interrupt
00228     LoopCallback();
00229     // get next reachable state from todo stack
00230     currentstates = todo.top();
00231     todo.pop();
00232     FD_DF("Parallel: processing (" << currentstates.first << "|" 
00233         << currentstates.second << ") -> " 
00234         << rReverseCompositionMap[currentstates]);
00235     // iterate over all rGen1 transitions 
00236     // (includes execution of shared events)
00237     tit1 = rGen1.TransRelBegin(currentstates.first);
00238     tit1_end = rGen1.TransRelEnd(currentstates.first);
00239     for (; tit1 != tit1_end; ++tit1) {
00240       // if event not shared
00241       if (! sharedalphabet.Exists(tit1->Ev)) {
00242         FD_DF("Parallel:   exists only in rGen1");
00243         newstates = std::make_pair(tit1->X2, currentstates.second);
00244         // add to todo list if composition state is new
00245         rcit = rReverseCompositionMap.find(newstates);
00246         if (rcit == rReverseCompositionMap.end()) {
00247           todo.push(newstates);
00248           tmpstate = pResGen->InsState();
00249           rReverseCompositionMap[newstates] = tmpstate;
00250           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00251               << newstates.second << ") -> " 
00252               << rReverseCompositionMap[newstates]);
00253         }
00254         else {
00255           tmpstate = rcit->second;
00256         }
00257         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, 
00258             tmpstate);
00259         FD_DF("Parallel:   add transition to new generator: " 
00260             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" 
00261             << tmpstate);
00262       }
00263       // if shared event
00264       else {
00265         FD_DF("Parallel:   common event");
00266         // find shared transitions
00267         tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00268         tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00269         for (; tit2 != tit2_end; ++tit2) {
00270           newstates = std::make_pair(tit1->X2, tit2->X2);
00271           // add to todo list if composition state is new
00272           rcit = rReverseCompositionMap.find(newstates);
00273           if (rcit == rReverseCompositionMap.end()) {
00274             todo.push(newstates);
00275             tmpstate = pResGen->InsState();
00276             rReverseCompositionMap[newstates] = tmpstate;
00277             FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00278                 << newstates.second << ") -> " 
00279                 << rReverseCompositionMap[newstates]);
00280           }
00281           else {
00282             tmpstate = rcit->second;
00283           }
00284           pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00285               tit1->Ev, tmpstate);
00286           FD_DF("Parallel:   add transition to new generator: " 
00287               << rReverseCompositionMap[currentstates] << "-" 
00288               << tit1->Ev << "-" << tmpstate);
00289         }
00290       }
00291     }
00292     // iterate over all rGen2 transitions 
00293     // (without execution of shared events)
00294     tit2 = rGen2.TransRelBegin(currentstates.second);
00295     tit2_end = rGen2.TransRelEnd(currentstates.second);
00296     for (; tit2 != tit2_end; ++tit2) {
00297       if (! sharedalphabet.Exists(tit2->Ev)) {
00298         FD_DF("Parallel:   exists only in rGen2");
00299         newstates = std::make_pair(currentstates.first, tit2->X2);
00300         // add to todo list if composition state is new
00301         rcit = rReverseCompositionMap.find(newstates);
00302         if (rcit == rReverseCompositionMap.end()) {
00303           todo.push(newstates);
00304           tmpstate = pResGen->InsState();
00305           rReverseCompositionMap[newstates] = tmpstate;
00306           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00307               << newstates.second << ") -> " 
00308               << rReverseCompositionMap[newstates]);
00309         }
00310         else {
00311           tmpstate = rcit->second;
00312         }
00313         pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00314             tit2->Ev, tmpstate);
00315         FD_DF("Parallel:   add transition to new generator: " 
00316             << rReverseCompositionMap[currentstates] << "-" 
00317             << tit2->Ev << "-" << tmpstate);
00318       }
00319     }
00320   }
00321 
00322   // set marked states
00323   for (lit1 = rGen1.MarkedStatesBegin(); 
00324       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00325     for (lit2 = rGen2.MarkedStatesBegin(); 
00326         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00327       currentstates = std::make_pair(*lit1, *lit2);
00328       rcit = rReverseCompositionMap.find(currentstates);
00329       if (rcit != rReverseCompositionMap.end()) {
00330         pResGen->SetMarkedState(rcit->second);
00331       }
00332     }
00333   }
00334   FD_DF("Parallel: set marked states at the end: " 
00335       << pResGen->MarkedStatesToString());
00336   // copy result
00337   if(pResGen != &rResGen) {
00338     rResGen = *pResGen;
00339     delete pResGen;
00340   }
00341 }
00342 
00343 
00344 // Product(rGen1, rGen2, res)
00345 void Product(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00346   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00347   // doit
00348   Product(rGen1, rGen2, rcmap, rResGen);
00349   // set statenames
00350   if (rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00351     SetComposedStateNames(rGen1, rGen2, rcmap, rResGen); 
00352   else
00353     rResGen.ClearStateNames();
00354 }
00355 
00356 
00357 // Product for vGenerators, transparent for event attributes.
00358 void aProduct(
00359   const vGenerator& rGen1,
00360   const vGenerator& rGen2,
00361   vGenerator& rResGen) 
00362 {
00363 
00364   // inputs have to agree on attributes of shared events:
00365   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00366 
00367   // prepare result
00368   vGenerator* pResGen = &rResGen;
00369   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00370     pResGen= rResGen.New();
00371   }
00372 
00373   // make product composition of inputs
00374   Product(rGen1,rGen2,*pResGen);
00375 
00376   // copy all attributes of input alphabets
00377   if(careattr) {
00378     pResGen->EventAttributes(rGen1.Alphabet());
00379     pResGen->EventAttributes(rGen2.Alphabet());
00380   }
00381 
00382   // copy result
00383   if(pResGen != &rResGen) {
00384     pResGen->Move(rResGen);
00385     delete pResGen;
00386   }
00387 
00388 }
00389 
00390 
00391 // Product(rGen1, rGen2, rReverseCompositionMap, mark1, mark2, res)
00392 void Product(
00393   const vGenerator& rGen1, const vGenerator& rGen2, 
00394   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00395   StateSet& rMark1,
00396   StateSet& rMark2,
00397   vGenerator& rResGen)
00398 {
00399 
00400   // do the composition
00401   Product(rGen1,rGen2,rReverseCompositionMap,rResGen);
00402 
00403   // clear marking
00404   rMark1.Clear();
00405   rMark2.Clear();
00406 
00407   // retrieve marking from reverse composition map
00408   std::map< std::pair<Idx,Idx>, Idx>::iterator rit;
00409   for(rit=rReverseCompositionMap.begin(); rit!=rReverseCompositionMap.end(); ++rit){
00410     if(rGen1.ExistsMarkedState(rit->first.first)) rMark1.Insert(rit->second);
00411     if(rGen2.ExistsMarkedState(rit->first.second)) rMark2.Insert(rit->second);
00412   }
00413 }
00414 
00415 
00416 // Product(rGen1, rGen2, rReverseCompositionMap, res)
00417 void Product(
00418   const vGenerator& rGen1, const vGenerator& rGen2, 
00419   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00420   vGenerator& rResGen)
00421 {
00422   FD_DF("Product(" << &rGen1 << "," << &rGen2 << ")");
00423 
00424   // prepare result
00425   vGenerator* pResGen = &rResGen;
00426   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00427     pResGen= rResGen.New();
00428   }
00429   pResGen->Clear();
00430 
00431   // shared alphabet
00432   pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
00433   FD_DF("Product: shared alphabet: "
00434       << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
00435 
00436   // todo stack
00437   std::stack< std::pair<Idx,Idx> > todo;
00438   // current pair, new pair
00439   std::pair<Idx,Idx> currentstates, newstates;
00440   // state
00441   Idx tmpstate;
00442   
00443   StateSet::Iterator lit1, lit2;
00444   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00445   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00446 
00447   // push all combinations of initial states on todo stack
00448   FD_DF("Product: adding all combinations of initial states to todo:");
00449   for (lit1 = rGen1.InitStatesBegin(); 
00450       lit1 != rGen1.InitStatesEnd(); ++lit1) {
00451     for (lit2 = rGen2.InitStatesBegin(); 
00452         lit2 != rGen2.InitStatesEnd(); ++lit2) {
00453       currentstates = std::make_pair(*lit1, *lit2);
00454       todo.push(currentstates);
00455       rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00456       FD_DF("Product:   (" << *lit1 << "|" << *lit2 << ") -> " 
00457           << rReverseCompositionMap[currentstates]);
00458     }
00459   }
00460 
00461   // start algorithm
00462   FD_DF("Product: processing reachable states:");
00463   while (! todo.empty()) {
00464     // allow for user interrupt
00465     LoopCallback();
00466     // get next reachable state from todo stack
00467     currentstates = todo.top();
00468     todo.pop();
00469     FD_DF("Product: processing (" << currentstates.first << "|" 
00470         << currentstates.second << ") -> " << rReverseCompositionMap[currentstates]);
00471     // iterate over all rGen1 transitions
00472     tit1 = rGen1.TransRelBegin(currentstates.first);
00473     tit1_end = rGen1.TransRelEnd(currentstates.first);
00474     tit2 = rGen2.TransRelBegin(currentstates.second);
00475     tit2_end = rGen2.TransRelEnd(currentstates.second);
00476     while ((tit1 != tit1_end) && (tit2 != tit2_end)) {
00477       // shared event
00478       if (tit1->Ev == tit2->Ev) {
00479         newstates = std::make_pair(tit1->X2, tit2->X2);
00480         // add to todo list if composition state is new
00481         rcit = rReverseCompositionMap.find(newstates);
00482         if (rcit == rReverseCompositionMap.end()) {
00483           todo.push(newstates);
00484           tmpstate = pResGen->InsState();
00485           rReverseCompositionMap[newstates] = tmpstate;
00486           FD_DF("Product: todo push: (" << newstates.first << "|" 
00487               << newstates.second << ") -> " << rReverseCompositionMap[newstates]);
00488         }
00489         else {
00490           tmpstate = rcit->second;
00491         }
00492         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, tmpstate);
00493         FD_DF("Product: add transition to new generator: " 
00494             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
00495         ++tit1;
00496         ++tit2;
00497       }
00498       // try resync tit1
00499       else if (tit1->Ev < tit2->Ev) {
00500         ++tit1;
00501       }
00502       // try resync tit2
00503       else if (tit1->Ev > tit2->Ev) {
00504         ++tit2;
00505       }
00506     }
00507   }
00508 
00509   // set marked states
00510   for (lit1 = rGen1.MarkedStatesBegin(); 
00511       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00512     for (lit2 = rGen2.MarkedStatesBegin(); 
00513         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00514       currentstates = std::make_pair(*lit1, *lit2);
00515       rcit = rReverseCompositionMap.find(currentstates);
00516       if (rcit != rReverseCompositionMap.end()) {
00517         pResGen->SetMarkedState(rcit->second);
00518       }
00519     }
00520   }
00521   FD_DF("Product: set marked states at the end: " 
00522       << pResGen->MarkedStatesToString());
00523 
00524 
00525   // copy result (TODO: use move)
00526   if(pResGen != &rResGen) {
00527     rResGen = *pResGen;
00528     delete pResGen;
00529   }
00530 }
00531 
00532 
00533 // SetParallelStateNames
00534 void SetComposedStateNames(
00535   const vGenerator& rGen1, const vGenerator& rGen2, 
00536   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00537   vGenerator& rGen12)
00538 {
00539   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00540   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00541     Idx x1=rcit->first.first;
00542     Idx x2=rcit->first.second;
00543     Idx x12=rcit->second;
00544     if(!rGen12.ExistsState(x12)) continue;
00545     std::string name1= rGen1.StateName(x1);
00546     if(name1=="") name1=ToStringInteger(x1);
00547     std::string name2= rGen2.StateName(x2);
00548     if(name2=="") name2=ToStringInteger(x2);
00549     std::string name12= name1 + "|" + name2;
00550     name12=rGen12.UniqueStateName(name12);
00551     rGen12.StateName(x12,name12);
00552   }
00553 }
00554 
00555 
00556 // CompositionMap1
00557 void CompositionMap1(
00558   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00559   std::map<Idx,Idx>& rCompositionMap)
00560 {
00561   rCompositionMap.clear();
00562   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00563   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00564     rCompositionMap.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
00565 }
00566 
00567 
00568 // CompositionMap2
00569 void CompositionMap2(
00570   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00571   std::map<Idx,Idx>& rCompositionMap)
00572 {
00573   rCompositionMap.clear();
00574   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00575   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00576     rCompositionMap.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
00577 }
00578 
00579 
00580 } // name space

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3