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 Generator& rGen1, const Generator& rGen2, Generator& rResGen) {
00029   // helpers:
00030   std::map< std::pair<Idx,Idx>, Idx> cmap;
00031   // prepare result
00032   Generator* pResGen = &rResGen;
00033   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00034     pResGen= rResGen.New();
00035   }
00036   // doit
00037   Parallel(rGen1, rGen2, cmap, *pResGen);
00038   // copy result
00039   if(pResGen != &rResGen) {
00040     pResGen->Move(rResGen);
00041     delete pResGen;
00042   }
00043 }
00044  
00045 
00046 // Parallel for Generators, transparent for event attributes.
00047 void aParallel(
00048   const Generator& rGen1,
00049   const Generator& rGen2,
00050   Generator& rResGen) 
00051 {
00052 
00053   // inputs have to agree on attributes of shared events:
00054   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00055 
00056   // prepare result
00057   Generator* pResGen = &rResGen;
00058   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00059     pResGen= rResGen.New();
00060   }
00061 
00062   // make product composition of inputs
00063   Parallel(rGen1,rGen2,*pResGen);
00064 
00065   // copy all attributes of input alphabets
00066   if(careattr) {
00067     pResGen->EventAttributes(rGen1.Alphabet());
00068     pResGen->EventAttributes(rGen2.Alphabet());
00069   }
00070 
00071   // copy result
00072   if(pResGen != &rResGen) {
00073     pResGen->Move(rResGen);
00074     delete pResGen;
00075   }
00076 
00077 }
00078 
00079 
00080 // Parallel for multiple Generators, transparent for event attributes.
00081 void aParallel(
00082   const GeneratorVector& rGenVec,
00083   Generator& rResGen) 
00084 {
00085 
00086   // inputs have to agree on attributes of pairwise shared events:
00087   bool careattr=true;
00088   for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++)
00089     for(GeneratorVector::Position j=0; j<i; j++) 
00090       if(!rGenVec.At(i).Alphabet().EqualAttributes(rGenVec.At(j).Alphabet()))
00091         careattr=false;
00092 
00093   // ignore empty
00094   if(rGenVec.Size()==0) {
00095     return;
00096   }
00097 
00098   // copy one 
00099   if(rGenVec.Size()==1) {
00100     rResGen=rGenVec.At(0);
00101     return;
00102   }
00103 
00104   // run parallel 
00105   Parallel(rGenVec.At(0),rGenVec.At(1),rResGen);
00106   for(GeneratorVector::Position i=2; i<rGenVec.Size(); i++) 
00107     Parallel(rGenVec.At(i),rResGen,rResGen);
00108 
00109   // fix alphabet
00110   if(careattr) {
00111     for(GeneratorVector::Position i=0; i<rGenVec.Size(); i++) 
00112       rResGen.EventAttributes(rGenVec.At(i).Alphabet());
00113   }
00114 
00115 }
00116 
00117 
00118 // aParallel(rGen1, rGen2, rCompositionMap, res)
00119 void aParallel(
00120   const Generator& rGen1, 
00121   const Generator& rGen2, 
00122   ProductCompositionMap& rCompositionMap, 
00123   Generator& rResGen) 
00124 {
00125   // inputs have to agree on attributes of shared events:
00126   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00127 
00128   // prepare result
00129   Generator* pResGen = &rResGen;
00130   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00131     pResGen= rResGen.New();
00132   }
00133 
00134   // make product composition of inputs
00135   Parallel(rGen1,rGen2,rCompositionMap.StlMap(),*pResGen);
00136 
00137   // copy all attributes of input alphabets
00138   if(careattr) {
00139     pResGen->EventAttributes(rGen1.Alphabet());
00140     pResGen->EventAttributes(rGen2.Alphabet());
00141   }
00142 
00143   // copy result
00144   if(pResGen != &rResGen) {
00145     pResGen->Move(rResGen);
00146     delete pResGen;
00147   }
00148 
00149 }
00150 
00151 // Parallel(rGen1, rGen2, rCompositionMap, res)
00152 void Parallel(
00153   const Generator& rGen1, 
00154   const Generator& rGen2, 
00155   ProductCompositionMap& rCompositionMap, 
00156   Generator& rResGen) 
00157 {
00158   // make product composition of inputs
00159   Parallel(rGen1,rGen2,rCompositionMap.StlMap(),rResGen);
00160 }
00161 
00162 // Parallel(rGen1, rGen2, rCompositionMap, mark1, mark2, res)
00163 void Parallel(
00164   const Generator& rGen1, const Generator& rGen2, 
00165   ProductCompositionMap& rCompositionMap, 
00166   StateSet& rMark1,
00167   StateSet& rMark2,
00168   Generator& rResGen)
00169 {
00170 
00171   // do the composition
00172   Parallel(rGen1,rGen2,rCompositionMap,rResGen);
00173 
00174   // clear marking
00175   rMark1.Clear();
00176   rMark2.Clear();
00177 
00178   /*
00179   see tmoor 20110208
00180 
00181   // catch special cases: a
00182   if(rGen1.AlphabetSize()==0) {
00183     rMark2=rGen2.MarkedStates();
00184     return;
00185   }
00186 
00187   // catch special cases: b
00188   if(rGen2.AlphabetSize()==0) {
00189     rMark1=rGen1.MarkedStates();
00190     return;
00191   }
00192   */
00193 
00194   // retrieve marking from reverse composition map
00195   StateSet::Iterator sit;
00196   for(sit=rResGen.StatesBegin(); sit!=rResGen.StatesEnd(); ++sit) {
00197     Idx s1=rCompositionMap.Arg1State(*sit);
00198     Idx s2=rCompositionMap.Arg2State(*sit);
00199     if(rGen1.ExistsMarkedState(s1)) rMark1.Insert(*sit);
00200     if(rGen2.ExistsMarkedState(s2)) rMark1.Insert(*sit);
00201   }
00202 }
00203 
00204 
00205 // Parallel(rGen1, rGen2, rCompositionMap, res)
00206 void Parallel(
00207   const Generator& rGen1, const Generator& rGen2, 
00208   std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 
00209   Generator& rResGen)
00210 {
00211   FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
00212 
00213   /*
00214   re-consider the special cases:
00215 
00216   if Sigma_1=0, we have either 
00217     -- L_res=L_2  (if L_1!=0) 
00218     -- L_res=0    (if L_1==0)
00219  
00220   the below special cases do not handle this correct,
00221   nor do they setup the composition map; thus, we drop
00222   the special cases;   tmoor 20110208
00223   */
00224 
00225   /*
00226   // special case: empty alphabet
00227   if(rGen1.AlphabetSize()==0) {
00228     rResGen=rGen2;
00229     rResGen.Name(rGen2.Name());
00230     return;
00231   }
00232 
00233   // special case: empty alphabet
00234   if(rGen2.AlphabetSize()==0) {
00235     rResGen=rGen1;
00236     rResGen.Name(rGen1.Name());
00237     return;
00238   }
00239   */
00240 
00241   // prepare result
00242   Generator* pResGen = &rResGen;
00243   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00244     pResGen= rResGen.New();
00245   }
00246   pResGen->Clear();
00247   pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
00248   rCompositionMap.clear();
00249 
00250   // create res alphabet
00251   EventSet::Iterator eit;
00252   for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00253     pResGen->InsEvent(*eit);
00254   }
00255   for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00256     pResGen->InsEvent(*eit);
00257   }
00258   FD_DF("Parallel: inserted indices in rResGen.alphabet( "
00259       << pResGen->AlphabetToString() << ")");
00260 
00261   // shared events
00262   EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00263   FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
00264 
00265   // todo stack
00266   std::stack< std::pair<Idx,Idx> > todo;
00267   // current pair, new pair
00268   std::pair<Idx,Idx> currentstates, newstates;
00269   // state
00270   Idx tmpstate;  
00271   StateSet::Iterator lit1, lit2;
00272   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00273   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00274 
00275   // push all combinations of initial states on todo stack
00276   FD_DF("Parallel: adding all combinations of initial states to todo:");
00277   for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00278     for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00279       currentstates = std::make_pair(*lit1, *lit2);
00280       todo.push(currentstates);
00281       tmpstate = pResGen->InsInitState();
00282       rCompositionMap[currentstates] = tmpstate;
00283       FD_DF("Parallel:   (" << *lit1 << "|" << *lit2 << ") -> " 
00284           << rCompositionMap[currentstates]);
00285     }
00286   }
00287 
00288   // start algorithm
00289   FD_DF("Parallel: processing reachable states:");
00290   while (! todo.empty()) {
00291     // allow for user interrupt
00292     // LoopCallback();
00293     // allow for user interrupt, incl progress report
00294     FD_WPC(rCompositionMap.size(),rCompositionMap.size()+todo.size(),"Parallel(): processing"); 
00295     // get next reachable state from todo stack
00296     currentstates = todo.top();
00297     todo.pop();
00298     FD_DF("Parallel: processing (" << currentstates.first << "|" 
00299         << currentstates.second << ") -> " 
00300         << rCompositionMap[currentstates]);
00301     // iterate over all rGen1 transitions 
00302     // (includes execution of shared events)
00303     tit1 = rGen1.TransRelBegin(currentstates.first);
00304     tit1_end = rGen1.TransRelEnd(currentstates.first);
00305     for (; tit1 != tit1_end; ++tit1) {
00306       // if event not shared
00307       if (! sharedalphabet.Exists(tit1->Ev)) {
00308         FD_DF("Parallel:   exists only in rGen1");
00309         newstates = std::make_pair(tit1->X2, currentstates.second);
00310         // add to todo list if composition state is new
00311         rcit = rCompositionMap.find(newstates);
00312         if (rcit == rCompositionMap.end()) {
00313           todo.push(newstates);
00314           tmpstate = pResGen->InsState();
00315           rCompositionMap[newstates] = tmpstate;
00316           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00317               << newstates.second << ") -> " 
00318               << rCompositionMap[newstates]);
00319         }
00320         else {
00321           tmpstate = rcit->second;
00322         }
00323         pResGen->SetTransition(rCompositionMap[currentstates], tit1->Ev, tmpstate);
00324         FD_DF("Parallel:   add transition to new generator: " 
00325             << rCompositionMap[currentstates] << "-" << tit1->Ev << "-" 
00326             << tmpstate);
00327       }
00328       // if shared event
00329       else {
00330         FD_DF("Parallel:   common event");
00331         // find shared transitions
00332         tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00333         tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00334         for (; tit2 != tit2_end; ++tit2) {
00335           newstates = std::make_pair(tit1->X2, tit2->X2);
00336           // add to todo list if composition state is new
00337           rcit = rCompositionMap.find(newstates);
00338           if (rcit == rCompositionMap.end()) {
00339             todo.push(newstates);
00340             tmpstate = pResGen->InsState();
00341             rCompositionMap[newstates] = tmpstate;
00342             FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00343                 << newstates.second << ") -> " 
00344                 << rCompositionMap[newstates]);
00345           }
00346           else {
00347             tmpstate = rcit->second;
00348           }
00349           pResGen->SetTransition(rCompositionMap[currentstates], 
00350               tit1->Ev, tmpstate);
00351           FD_DF("Parallel:   add transition to new generator: " 
00352               << rCompositionMap[currentstates] << "-" 
00353               << tit1->Ev << "-" << tmpstate);
00354         }
00355       }
00356     }
00357     // iterate over all rGen2 transitions 
00358     // (without execution of shared events)
00359     tit2 = rGen2.TransRelBegin(currentstates.second);
00360     tit2_end = rGen2.TransRelEnd(currentstates.second);
00361     for (; tit2 != tit2_end; ++tit2) {
00362       if (! sharedalphabet.Exists(tit2->Ev)) {
00363         FD_DF("Parallel:   exists only in rGen2");
00364         newstates = std::make_pair(currentstates.first, tit2->X2);
00365         // add to todo list if composition state is new
00366         rcit = rCompositionMap.find(newstates);
00367         if (rcit == rCompositionMap.end()) {
00368           todo.push(newstates);
00369           tmpstate = pResGen->InsState();
00370           rCompositionMap[newstates] = tmpstate;
00371           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00372               << newstates.second << ") -> " 
00373               << rCompositionMap[newstates]);
00374         }
00375         else {
00376           tmpstate = rcit->second;
00377         }
00378         pResGen->SetTransition(rCompositionMap[currentstates], 
00379             tit2->Ev, tmpstate);
00380         FD_DF("Parallel:   add transition to new generator: " 
00381             << rCompositionMap[currentstates] << "-" 
00382             << tit2->Ev << "-" << tmpstate);
00383       }
00384     }
00385   }
00386 
00387   // set marked states
00388   for (lit1 = rGen1.MarkedStatesBegin(); 
00389       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00390     for (lit2 = rGen2.MarkedStatesBegin(); 
00391         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00392       currentstates = std::make_pair(*lit1, *lit2);
00393       rcit = rCompositionMap.find(currentstates);
00394       if (rcit != rCompositionMap.end()) {
00395         pResGen->SetMarkedState(rcit->second);
00396       }
00397     }
00398   }
00399   FD_DF("Parallel: marked states: " 
00400       << pResGen->MarkedStatesToString());
00401   // copy result
00402   if(pResGen != &rResGen) {
00403     rResGen = *pResGen;
00404     delete pResGen;
00405   }
00406   // set statenames
00407   if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00408     SetComposedStateNames(rGen1, rGen2, rCompositionMap, rResGen); 
00409   else
00410     rResGen.StateNamesEnabled(false);
00411 }
00412 
00413 
00414 // Product(rGen1, rGen2, res)
00415 void Product(const Generator& rGen1, const Generator& rGen2, Generator& rResGen) {
00416   std::map< std::pair<Idx,Idx>, Idx> cmap;
00417   // doit
00418   Product(rGen1, rGen2, cmap, rResGen);
00419 }
00420 
00421 
00422 // Product for Generators, transparent for event attributes.
00423 void aProduct(
00424   const Generator& rGen1,
00425   const Generator& rGen2,
00426   Generator& rResGen) 
00427 {
00428 
00429   // inputs have to agree on attributes of shared events:
00430   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00431 
00432   // prepare result
00433   Generator* pResGen = &rResGen;
00434   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00435     pResGen= rResGen.New();
00436   }
00437 
00438   // make product composition of inputs
00439   Product(rGen1,rGen2,*pResGen);
00440 
00441   // copy all attributes of input alphabets
00442   if(careattr) {
00443     pResGen->EventAttributes(rGen1.Alphabet());
00444     pResGen->EventAttributes(rGen2.Alphabet());
00445   }
00446 
00447   // copy result
00448   if(pResGen != &rResGen) {
00449     pResGen->Move(rResGen);
00450     delete pResGen;
00451   }
00452 
00453 }
00454 
00455 
00456 // aProduct(rGen1, rGen2, rCompositionMap, res)
00457 void aProduct(
00458   const Generator& rGen1, 
00459   const Generator& rGen2, 
00460   ProductCompositionMap& rCompositionMap, 
00461   Generator& rResGen) 
00462 {
00463   // inputs have to agree on attributes of shared events:
00464   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00465 
00466   // prepare result
00467   Generator* pResGen = &rResGen;
00468   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00469     pResGen= rResGen.New();
00470   }
00471 
00472   // make product composition of inputs
00473   Product(rGen1,rGen2,rCompositionMap.StlMap(),*pResGen);
00474 
00475   // copy all attributes of input alphabets
00476   if(careattr) {
00477     pResGen->EventAttributes(rGen1.Alphabet());
00478     pResGen->EventAttributes(rGen2.Alphabet());
00479   }
00480 
00481   // copy result
00482   if(pResGen != &rResGen) {
00483     pResGen->Move(rResGen);
00484     delete pResGen;
00485   }
00486 
00487 }
00488 
00489 // Product(rGen1, rGen2, rCompositionMap, mark1, mark2, res)
00490 void Product(
00491   const Generator& rGen1, const Generator& rGen2, 
00492   std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 
00493   StateSet& rMark1,
00494   StateSet& rMark2,
00495   Generator& rResGen)
00496 {
00497 
00498   // do the composition
00499   Product(rGen1,rGen2,rCompositionMap,rResGen);
00500 
00501   // clear marking
00502   rMark1.Clear();
00503   rMark2.Clear();
00504 
00505   // retrieve marking from reverse composition map
00506   std::map< std::pair<Idx,Idx>, Idx>::iterator rit;
00507   for(rit=rCompositionMap.begin(); rit!=rCompositionMap.end(); ++rit){
00508     if(rGen1.ExistsMarkedState(rit->first.first)) rMark1.Insert(rit->second);
00509     if(rGen2.ExistsMarkedState(rit->first.second)) rMark2.Insert(rit->second);
00510   }
00511 }
00512 
00513 
00514 // Product(rGen1, rGen2, rCompositionMap, res)
00515 void Product(
00516   const Generator& rGen1, const Generator& rGen2, 
00517   std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 
00518   Generator& rResGen)
00519 {
00520   FD_DF("Product(" << &rGen1 << "," << &rGen2 << ")");
00521 
00522   // plant and spec must be deterministic
00523   bool g1_det = rGen1.IsDeterministic();
00524   bool g2_det = rGen2.IsDeterministic();
00525   if( (!g1_det) || (!g2_det)) {
00526     std::stringstream errstr;
00527     errstr << "Use Parallel instead of Product for nondeterministic generators";
00528     throw Exception("Product", errstr.str(), 201);
00529   }
00530 
00531   // prepare result
00532   Generator* pResGen = &rResGen;
00533   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00534     pResGen= rResGen.New();
00535   }
00536   pResGen->Clear();
00537   rCompositionMap.clear();
00538 
00539   // shared alphabet
00540   pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
00541   FD_DF("Product: shared alphabet: "
00542       << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
00543 
00544   // todo stack
00545   std::stack< std::pair<Idx,Idx> > todo;
00546   // current pair, new pair
00547   std::pair<Idx,Idx> currentstates, newstates;
00548   // state
00549   Idx tmpstate;
00550   
00551   StateSet::Iterator lit1, lit2;
00552   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00553   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00554 
00555   // push all combinations of initial states on todo stack
00556   FD_DF("Product: adding all combinations of initial states to todo:");
00557   for (lit1 = rGen1.InitStatesBegin(); 
00558       lit1 != rGen1.InitStatesEnd(); ++lit1) {
00559     for (lit2 = rGen2.InitStatesBegin(); 
00560         lit2 != rGen2.InitStatesEnd(); ++lit2) {
00561       currentstates = std::make_pair(*lit1, *lit2);
00562       todo.push(currentstates);
00563       rCompositionMap[currentstates] = pResGen->InsInitState();
00564       FD_DF("Product:   (" << *lit1 << "|" << *lit2 << ") -> " 
00565           << rCompositionMap[currentstates]);
00566     }
00567   }
00568 
00569   // start algorithm
00570   FD_DF("Product: processing reachable states:");
00571   while (! todo.empty()) {
00572     // allow for user interrupt
00573     // LoopCallback();
00574     // allow for user interrupt, incl progress report
00575     FD_WPC(rCompositionMap.size(),rCompositionMap.size()+todo.size(),"Product(): processing"); 
00576     // get next reachable state from todo stack
00577     currentstates = todo.top();
00578     todo.pop();
00579     FD_DF("Product: processing (" << currentstates.first << "|" 
00580         << currentstates.second << ") -> " << rCompositionMap[currentstates]);
00581     // iterate over all rGen1 transitions
00582     tit1 = rGen1.TransRelBegin(currentstates.first);
00583     tit1_end = rGen1.TransRelEnd(currentstates.first);
00584     tit2 = rGen2.TransRelBegin(currentstates.second);
00585     tit2_end = rGen2.TransRelEnd(currentstates.second);
00586     while ((tit1 != tit1_end) && (tit2 != tit2_end)) {
00587       // shared event
00588       if (tit1->Ev == tit2->Ev) {
00589         newstates = std::make_pair(tit1->X2, tit2->X2);
00590         // add to todo list if composition state is new
00591         rcit = rCompositionMap.find(newstates);
00592         if (rcit == rCompositionMap.end()) {
00593           todo.push(newstates);
00594           tmpstate = pResGen->InsState();
00595           rCompositionMap[newstates] = tmpstate;
00596           FD_DF("Product: todo push: (" << newstates.first << "|" 
00597               << newstates.second << ") -> " << rCompositionMap[newstates]);
00598         }
00599         else {
00600           tmpstate = rcit->second;
00601         }
00602         pResGen->SetTransition(rCompositionMap[currentstates], tit1->Ev, tmpstate);
00603         FD_DF("Product: add transition to new generator: " 
00604             << rCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
00605         ++tit1;
00606         ++tit2;
00607       }
00608       // try resync tit1
00609       else if (tit1->Ev < tit2->Ev) {
00610         ++tit1;
00611       }
00612       // try resync tit2
00613       else if (tit1->Ev > tit2->Ev) {
00614         ++tit2;
00615       }
00616     }
00617   }
00618 
00619   // set marked states
00620   for (lit1 = rGen1.MarkedStatesBegin(); 
00621       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00622     for (lit2 = rGen2.MarkedStatesBegin(); 
00623         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00624       currentstates = std::make_pair(*lit1, *lit2);
00625       rcit = rCompositionMap.find(currentstates);
00626       if (rcit != rCompositionMap.end()) {
00627         pResGen->SetMarkedState(rcit->second);
00628       }
00629     }
00630   }
00631   FD_DF("Product: set marked states at the end: " 
00632       << pResGen->MarkedStatesToString());
00633   // copy result (TODO: use move)
00634   if(pResGen != &rResGen) {
00635     rResGen = *pResGen;
00636     delete pResGen;
00637   }
00638   // set statenames
00639   if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00640     SetComposedStateNames(rGen1, rGen2, rCompositionMap, rResGen); 
00641   else
00642     rResGen.ClearStateNames();
00643 
00644 }
00645 
00646 
00647 // SetParallelStateNames
00648 void SetComposedStateNames(
00649   const Generator& rGen1, const Generator& rGen2, 
00650   const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 
00651   Generator& rGen12)
00652 {
00653   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00654   for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++) {
00655     Idx x1=rcit->first.first;
00656     Idx x2=rcit->first.second;
00657     Idx x12=rcit->second;
00658     if(!rGen12.ExistsState(x12)) continue;
00659     std::string name1= rGen1.StateName(x1);
00660     if(name1=="") name1=ToStringInteger(x1);
00661     std::string name2= rGen2.StateName(x2);
00662     if(name2=="") name2=ToStringInteger(x2);
00663     std::string name12= name1 + "|" + name2;
00664     name12=rGen12.UniqueStateName(name12);
00665     rGen12.StateName(x12,name12);
00666   }
00667 }
00668 
00669 
00670 // CompositionMap1
00671 void CompositionMap1(
00672   const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 
00673   std::map<Idx,Idx>& rCompositionMap1)
00674 {
00675   rCompositionMap1.clear();
00676   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00677   for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++) 
00678     rCompositionMap1.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
00679 }
00680 
00681 
00682 // CompositionMap2
00683 void CompositionMap2(
00684   const std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 
00685   std::map<Idx,Idx>& rCompositionMap2)
00686 {
00687   rCompositionMap2.clear();
00688   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00689   for(rcit=rCompositionMap.begin(); rcit!=rCompositionMap.end(); rcit++) 
00690     rCompositionMap2.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
00691 }
00692 
00693 
00694 /**
00695  * Rti wrapper class implementation
00696  */
00697 
00698 // std faudes type
00699 FAUDES_TYPE_IMPLEMENTATION(ProductCompositionMap,ProductCompositionMap,Type)
00700 
00701 // construct
00702 ProductCompositionMap::ProductCompositionMap(void) : Type() { 
00703   mCompiled=true;
00704 }
00705 
00706 // construct
00707 ProductCompositionMap::ProductCompositionMap(const ProductCompositionMap& rOther) : Type() {
00708   DoAssign(rOther);
00709 }
00710 
00711 // destruct
00712 ProductCompositionMap::~ProductCompositionMap(void) {
00713 }
00714 
00715 // clear
00716 void ProductCompositionMap::Clear(void) { 
00717   mCompositionMap.clear(); 
00718   mCompiled=true;
00719   mArg1Map.clear(); 
00720   mArg2Map.clear(); 
00721 }
00722 
00723 // assignment
00724 void ProductCompositionMap::DoAssign(const ProductCompositionMap& rSrc) {
00725   mCompositionMap=rSrc.mCompositionMap;
00726   mCompiled=rSrc.mCompiled;
00727   mArg1Map=rSrc.mArg1Map; 
00728   mArg2Map=rSrc.mArg2Map;  
00729 }
00730 
00731 // equality
00732 bool ProductCompositionMap::DoEqual(const ProductCompositionMap& rOther) const { 
00733   return mCompositionMap==rOther.mCompositionMap;
00734 }
00735 
00736 // C++/STL access
00737 const std::map< std::pair<Idx,Idx> , Idx >& ProductCompositionMap::StlMap(void) const { 
00738   return mCompositionMap;
00739 }
00740 
00741 // C++/STL access
00742 std::map< std::pair<Idx,Idx> , Idx >& ProductCompositionMap::StlMap(void) { 
00743   mCompiled=false;
00744   return mCompositionMap;
00745 }
00746 
00747 // C++/STL access
00748 void ProductCompositionMap::StlMap(const std::map< std::pair<Idx,Idx> , Idx >& rMap) { 
00749   mCompositionMap=rMap;
00750   mCompiled=false;
00751 }
00752 
00753 // access
00754 Idx ProductCompositionMap::CompState(Idx x1, Idx x2) const {
00755   std::pair<Idx,Idx> x12(x1,x2);
00756   std::map< std::pair<Idx,Idx> , Idx >::const_iterator x12it=mCompositionMap.find(x12);
00757   if(x12it==mCompositionMap.end()) return 0;
00758   return x12it->second;
00759 }
00760 
00761 // access
00762 Idx ProductCompositionMap::Arg1State(Idx x1) const {
00763   if(!mCompiled) {
00764     mArg1Map.clear();
00765     mArg2Map.clear();
00766     std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00767     for(rcit=mCompositionMap.begin(); rcit!=mCompositionMap.end(); rcit++) {
00768       mArg1Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
00769       mArg2Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
00770     }
00771     mCompiled=true;
00772   }
00773   std::map< Idx , Idx >::const_iterator x1it=mArg1Map.find(x1);
00774   if(x1it==mArg1Map.end()) return 0;
00775   return x1it->second;
00776 }
00777 
00778 // access
00779 Idx ProductCompositionMap::Arg2State(Idx x2) const {
00780   if(!mCompiled) {
00781     mArg1Map.clear();
00782     mArg2Map.clear();
00783     std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00784     for(rcit=mCompositionMap.begin(); rcit!=mCompositionMap.end(); rcit++) {
00785       mArg1Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
00786       mArg2Map.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
00787     }
00788     mCompiled=true;
00789   }
00790   std::map< Idx , Idx >::const_iterator x2it=mArg2Map.find(x2);
00791   if(x2it==mArg2Map.end()) return 0;
00792   return x2it->second;
00793 }
00794 
00795 
00796 
00797 } // name space

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