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     // allow for user interrupt, incl progress report
00230     FD_WPC(rReverseCompositionMap.size(),rReverseCompositionMap.size()+todo.size(),"Parallel(): processing"); 
00231     // get next reachable state from todo stack
00232     currentstates = todo.top();
00233     todo.pop();
00234     FD_DF("Parallel: processing (" << currentstates.first << "|" 
00235         << currentstates.second << ") -> " 
00236         << rReverseCompositionMap[currentstates]);
00237     // iterate over all rGen1 transitions 
00238     // (includes execution of shared events)
00239     tit1 = rGen1.TransRelBegin(currentstates.first);
00240     tit1_end = rGen1.TransRelEnd(currentstates.first);
00241     for (; tit1 != tit1_end; ++tit1) {
00242       // if event not shared
00243       if (! sharedalphabet.Exists(tit1->Ev)) {
00244         FD_DF("Parallel:   exists only in rGen1");
00245         newstates = std::make_pair(tit1->X2, currentstates.second);
00246         // add to todo list if composition state is new
00247         rcit = rReverseCompositionMap.find(newstates);
00248         if (rcit == rReverseCompositionMap.end()) {
00249           todo.push(newstates);
00250           tmpstate = pResGen->InsState();
00251           rReverseCompositionMap[newstates] = tmpstate;
00252           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00253               << newstates.second << ") -> " 
00254               << rReverseCompositionMap[newstates]);
00255         }
00256         else {
00257           tmpstate = rcit->second;
00258         }
00259         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, 
00260             tmpstate);
00261         FD_DF("Parallel:   add transition to new generator: " 
00262             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" 
00263             << tmpstate);
00264       }
00265       // if shared event
00266       else {
00267         FD_DF("Parallel:   common event");
00268         // find shared transitions
00269         tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00270         tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00271         for (; tit2 != tit2_end; ++tit2) {
00272           newstates = std::make_pair(tit1->X2, tit2->X2);
00273           // add to todo list if composition state is new
00274           rcit = rReverseCompositionMap.find(newstates);
00275           if (rcit == rReverseCompositionMap.end()) {
00276             todo.push(newstates);
00277             tmpstate = pResGen->InsState();
00278             rReverseCompositionMap[newstates] = tmpstate;
00279             FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00280                 << newstates.second << ") -> " 
00281                 << rReverseCompositionMap[newstates]);
00282           }
00283           else {
00284             tmpstate = rcit->second;
00285           }
00286           pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00287               tit1->Ev, tmpstate);
00288           FD_DF("Parallel:   add transition to new generator: " 
00289               << rReverseCompositionMap[currentstates] << "-" 
00290               << tit1->Ev << "-" << tmpstate);
00291         }
00292       }
00293     }
00294     // iterate over all rGen2 transitions 
00295     // (without execution of shared events)
00296     tit2 = rGen2.TransRelBegin(currentstates.second);
00297     tit2_end = rGen2.TransRelEnd(currentstates.second);
00298     for (; tit2 != tit2_end; ++tit2) {
00299       if (! sharedalphabet.Exists(tit2->Ev)) {
00300         FD_DF("Parallel:   exists only in rGen2");
00301         newstates = std::make_pair(currentstates.first, tit2->X2);
00302         // add to todo list if composition state is new
00303         rcit = rReverseCompositionMap.find(newstates);
00304         if (rcit == rReverseCompositionMap.end()) {
00305           todo.push(newstates);
00306           tmpstate = pResGen->InsState();
00307           rReverseCompositionMap[newstates] = tmpstate;
00308           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00309               << newstates.second << ") -> " 
00310               << rReverseCompositionMap[newstates]);
00311         }
00312         else {
00313           tmpstate = rcit->second;
00314         }
00315         pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00316             tit2->Ev, tmpstate);
00317         FD_DF("Parallel:   add transition to new generator: " 
00318             << rReverseCompositionMap[currentstates] << "-" 
00319             << tit2->Ev << "-" << tmpstate);
00320       }
00321     }
00322   }
00323 
00324   // set marked states
00325   for (lit1 = rGen1.MarkedStatesBegin(); 
00326       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00327     for (lit2 = rGen2.MarkedStatesBegin(); 
00328         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00329       currentstates = std::make_pair(*lit1, *lit2);
00330       rcit = rReverseCompositionMap.find(currentstates);
00331       if (rcit != rReverseCompositionMap.end()) {
00332         pResGen->SetMarkedState(rcit->second);
00333       }
00334     }
00335   }
00336   FD_DF("Parallel: set marked states at the end: " 
00337       << pResGen->MarkedStatesToString());
00338   // copy result
00339   if(pResGen != &rResGen) {
00340     rResGen = *pResGen;
00341     delete pResGen;
00342   }
00343 }
00344 
00345 
00346 // Product(rGen1, rGen2, res)
00347 void Product(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00348   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00349   // doit
00350   Product(rGen1, rGen2, rcmap, rResGen);
00351   // set statenames
00352   if (rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00353     SetComposedStateNames(rGen1, rGen2, rcmap, rResGen); 
00354   else
00355     rResGen.ClearStateNames();
00356 }
00357 
00358 
00359 // Product for vGenerators, transparent for event attributes.
00360 void aProduct(
00361   const vGenerator& rGen1,
00362   const vGenerator& rGen2,
00363   vGenerator& rResGen) 
00364 {
00365 
00366   // inputs have to agree on attributes of shared events:
00367   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00368 
00369   // prepare result
00370   vGenerator* pResGen = &rResGen;
00371   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00372     pResGen= rResGen.New();
00373   }
00374 
00375   // make product composition of inputs
00376   Product(rGen1,rGen2,*pResGen);
00377 
00378   // copy all attributes of input alphabets
00379   if(careattr) {
00380     pResGen->EventAttributes(rGen1.Alphabet());
00381     pResGen->EventAttributes(rGen2.Alphabet());
00382   }
00383 
00384   // copy result
00385   if(pResGen != &rResGen) {
00386     pResGen->Move(rResGen);
00387     delete pResGen;
00388   }
00389 
00390 }
00391 
00392 
00393 // Product(rGen1, rGen2, rReverseCompositionMap, mark1, mark2, res)
00394 void Product(
00395   const vGenerator& rGen1, const vGenerator& rGen2, 
00396   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00397   StateSet& rMark1,
00398   StateSet& rMark2,
00399   vGenerator& rResGen)
00400 {
00401 
00402   // do the composition
00403   Product(rGen1,rGen2,rReverseCompositionMap,rResGen);
00404 
00405   // clear marking
00406   rMark1.Clear();
00407   rMark2.Clear();
00408 
00409   // retrieve marking from reverse composition map
00410   std::map< std::pair<Idx,Idx>, Idx>::iterator rit;
00411   for(rit=rReverseCompositionMap.begin(); rit!=rReverseCompositionMap.end(); ++rit){
00412     if(rGen1.ExistsMarkedState(rit->first.first)) rMark1.Insert(rit->second);
00413     if(rGen2.ExistsMarkedState(rit->first.second)) rMark2.Insert(rit->second);
00414   }
00415 }
00416 
00417 
00418 // Product(rGen1, rGen2, rReverseCompositionMap, res)
00419 void Product(
00420   const vGenerator& rGen1, const vGenerator& rGen2, 
00421   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00422   vGenerator& rResGen)
00423 {
00424   FD_DF("Product(" << &rGen1 << "," << &rGen2 << ")");
00425 
00426   // prepare result
00427   vGenerator* pResGen = &rResGen;
00428   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00429     pResGen= rResGen.New();
00430   }
00431   pResGen->Clear();
00432 
00433   // shared alphabet
00434   pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
00435   FD_DF("Product: shared alphabet: "
00436       << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
00437 
00438   // todo stack
00439   std::stack< std::pair<Idx,Idx> > todo;
00440   // current pair, new pair
00441   std::pair<Idx,Idx> currentstates, newstates;
00442   // state
00443   Idx tmpstate;
00444   
00445   StateSet::Iterator lit1, lit2;
00446   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00447   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00448 
00449   // push all combinations of initial states on todo stack
00450   FD_DF("Product: adding all combinations of initial states to todo:");
00451   for (lit1 = rGen1.InitStatesBegin(); 
00452       lit1 != rGen1.InitStatesEnd(); ++lit1) {
00453     for (lit2 = rGen2.InitStatesBegin(); 
00454         lit2 != rGen2.InitStatesEnd(); ++lit2) {
00455       currentstates = std::make_pair(*lit1, *lit2);
00456       todo.push(currentstates);
00457       rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00458       FD_DF("Product:   (" << *lit1 << "|" << *lit2 << ") -> " 
00459           << rReverseCompositionMap[currentstates]);
00460     }
00461   }
00462 
00463   // start algorithm
00464   FD_DF("Product: processing reachable states:");
00465   while (! todo.empty()) {
00466     // allow for user interrupt
00467     // LoopCallback();
00468     // allow for user interrupt, incl progress report
00469     FD_WPC(rReverseCompositionMap.size(),rReverseCompositionMap.size()+todo.size(),"Product(): processing"); 
00470     // get next reachable state from todo stack
00471     currentstates = todo.top();
00472     todo.pop();
00473     FD_DF("Product: processing (" << currentstates.first << "|" 
00474         << currentstates.second << ") -> " << rReverseCompositionMap[currentstates]);
00475     // iterate over all rGen1 transitions
00476     tit1 = rGen1.TransRelBegin(currentstates.first);
00477     tit1_end = rGen1.TransRelEnd(currentstates.first);
00478     tit2 = rGen2.TransRelBegin(currentstates.second);
00479     tit2_end = rGen2.TransRelEnd(currentstates.second);
00480     while ((tit1 != tit1_end) && (tit2 != tit2_end)) {
00481       // shared event
00482       if (tit1->Ev == tit2->Ev) {
00483         newstates = std::make_pair(tit1->X2, tit2->X2);
00484         // add to todo list if composition state is new
00485         rcit = rReverseCompositionMap.find(newstates);
00486         if (rcit == rReverseCompositionMap.end()) {
00487           todo.push(newstates);
00488           tmpstate = pResGen->InsState();
00489           rReverseCompositionMap[newstates] = tmpstate;
00490           FD_DF("Product: todo push: (" << newstates.first << "|" 
00491               << newstates.second << ") -> " << rReverseCompositionMap[newstates]);
00492         }
00493         else {
00494           tmpstate = rcit->second;
00495         }
00496         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, tmpstate);
00497         FD_DF("Product: add transition to new generator: " 
00498             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
00499         ++tit1;
00500         ++tit2;
00501       }
00502       // try resync tit1
00503       else if (tit1->Ev < tit2->Ev) {
00504         ++tit1;
00505       }
00506       // try resync tit2
00507       else if (tit1->Ev > tit2->Ev) {
00508         ++tit2;
00509       }
00510     }
00511   }
00512 
00513   // set marked states
00514   for (lit1 = rGen1.MarkedStatesBegin(); 
00515       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00516     for (lit2 = rGen2.MarkedStatesBegin(); 
00517         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00518       currentstates = std::make_pair(*lit1, *lit2);
00519       rcit = rReverseCompositionMap.find(currentstates);
00520       if (rcit != rReverseCompositionMap.end()) {
00521         pResGen->SetMarkedState(rcit->second);
00522       }
00523     }
00524   }
00525   FD_DF("Product: set marked states at the end: " 
00526       << pResGen->MarkedStatesToString());
00527 
00528 
00529   // copy result (TODO: use move)
00530   if(pResGen != &rResGen) {
00531     rResGen = *pResGen;
00532     delete pResGen;
00533   }
00534 }
00535 
00536 
00537 // SetParallelStateNames
00538 void SetComposedStateNames(
00539   const vGenerator& rGen1, const vGenerator& rGen2, 
00540   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00541   vGenerator& rGen12)
00542 {
00543   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00544   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00545     Idx x1=rcit->first.first;
00546     Idx x2=rcit->first.second;
00547     Idx x12=rcit->second;
00548     if(!rGen12.ExistsState(x12)) continue;
00549     std::string name1= rGen1.StateName(x1);
00550     if(name1=="") name1=ToStringInteger(x1);
00551     std::string name2= rGen2.StateName(x2);
00552     if(name2=="") name2=ToStringInteger(x2);
00553     std::string name12= name1 + "|" + name2;
00554     name12=rGen12.UniqueStateName(name12);
00555     rGen12.StateName(x12,name12);
00556   }
00557 }
00558 
00559 
00560 // CompositionMap1
00561 void CompositionMap1(
00562   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00563   std::map<Idx,Idx>& rCompositionMap)
00564 {
00565   rCompositionMap.clear();
00566   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00567   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00568     rCompositionMap.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
00569 }
00570 
00571 
00572 // CompositionMap2
00573 void CompositionMap2(
00574   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00575   std::map<Idx,Idx>& rCompositionMap)
00576 {
00577   rCompositionMap.clear();
00578   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00579   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00580     rCompositionMap.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
00581 }
00582 
00583 
00584 } // name space

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3