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

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen