libFAUDES

Sections

Index

parallel.cpp

Go to the documentation of this file.
00001 /** @file 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 "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   if (rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00039     SetComposedStateNames(rGen1, rGen2, rcmap, *pResGen); 
00040   else
00041     pResGen->ClearStateNames();
00042   // copy result
00043   if(pResGen != &rResGen) {
00044     rResGen = *pResGen;
00045     delete pResGen;
00046   }
00047 }
00048  
00049 
00050 // Parallel for vGenerators, transparent for event attributes.
00051 void aParallel(
00052   const vGenerator& rGen1,
00053   const vGenerator& rGen2,
00054   vGenerator& rResGen) 
00055 {
00056 
00057   // inputs have to agree on attributes of shared events:
00058   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00059 
00060   // prepare result
00061   vGenerator* pResGen = &rResGen;
00062   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00063     pResGen= rResGen.New();
00064   }
00065 
00066   // make product composition of inputs
00067   Parallel(rGen1,rGen2,*pResGen);
00068 
00069   // copy all attributes of input alphabets
00070   if(careattr) {
00071     pResGen->EventAttributes(rGen1.Alphabet());
00072     pResGen->EventAttributes(rGen2.Alphabet());
00073   }
00074 
00075   // copy result
00076   if(pResGen != &rResGen) {
00077     pResGen->Move(rResGen);
00078     delete pResGen;
00079   }
00080 
00081 }
00082 
00083 
00084 // Parallel(rGen1, rGen2, rReverseCompositionMap, res)
00085 void Parallel(
00086   const vGenerator& rGen1, const vGenerator& rGen2, 
00087   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00088   vGenerator& rResGen)
00089 {
00090   FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
00091 
00092   // special case: empty alphabet
00093   if(rGen1.AlphabetSize()==0) {
00094     rResGen=rGen2;
00095     rResGen.Name(rGen2.Name());
00096     return;
00097   }
00098 
00099   // special case: empty alphabet
00100   if(rGen2.AlphabetSize()==0) {
00101     rResGen=rGen1;
00102     rResGen.Name(rGen1.Name());
00103     return;
00104   }
00105 
00106   // prepare result
00107   vGenerator* pResGen = &rResGen;
00108   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00109     pResGen= rResGen.New();
00110   }
00111   pResGen->Clear();
00112   pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
00113 
00114   // create res alphabet
00115   EventSet::Iterator eit;
00116   for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00117     pResGen->InsEvent(*eit);
00118   }
00119   for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00120     pResGen->InsEvent(*eit);
00121   }
00122   FD_DF("Parallel: inserted indices in rResGen.alphabet( "
00123       << pResGen->AlphabetToString() << ")");
00124 
00125   // shared events
00126   EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00127   FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
00128 
00129   // todo stack
00130   std::stack< std::pair<Idx,Idx> > todo;
00131   // actual pair, new pair
00132   std::pair<Idx,Idx> currentstates, newstates;
00133   // state
00134   Idx tmpstate;  
00135   StateSet::Iterator lit1, lit2;
00136   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00137   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00138 
00139   // push all combinations of initial states on todo stack
00140   FD_DF("Parallel: adding all combinations of initial states to todo:");
00141   for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00142     for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00143       currentstates = std::make_pair(*lit1, *lit2);
00144       todo.push(currentstates);
00145       rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00146       FD_DF("Parallel:   (" << *lit1 << "|" << *lit2 << ") -> " 
00147           << rReverseCompositionMap[currentstates]);
00148     }
00149   }
00150 
00151   // start algorithm
00152   FD_DF("Parallel: processing reachable states:");
00153   while (! todo.empty()) {
00154     // get next reachable state from todo stack
00155     currentstates = todo.top();
00156     todo.pop();
00157     FD_DF("Parallel: processing (" << currentstates.first << "|" 
00158         << currentstates.second << ") -> " 
00159         << rReverseCompositionMap[currentstates]);
00160     // iterate over all rGen1 transitions 
00161     // (includes execution of shared events)
00162     tit1 = rGen1.TransRelBegin(currentstates.first);
00163     tit1_end = rGen1.TransRelEnd(currentstates.first);
00164     for (; tit1 != tit1_end; ++tit1) {
00165       // if event not shared
00166       if (! sharedalphabet.Exists(tit1->Ev)) {
00167         FD_DF("Parallel:   exists only in rGen1");
00168         newstates = std::make_pair(tit1->X2, currentstates.second);
00169         // add to todo list if composition state is new
00170         rcit = rReverseCompositionMap.find(newstates);
00171         if (rcit == rReverseCompositionMap.end()) {
00172           todo.push(newstates);
00173           tmpstate = pResGen->InsState();
00174           rReverseCompositionMap[newstates] = tmpstate;
00175           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00176               << newstates.second << ") -> " 
00177               << rReverseCompositionMap[newstates]);
00178         }
00179         else {
00180           tmpstate = rcit->second;
00181         }
00182         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, 
00183             tmpstate);
00184         FD_DF("Parallel:   add transition to new generator: " 
00185             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" 
00186             << tmpstate);
00187       }
00188       // if shared event
00189       else {
00190         FD_DF("Parallel:   common event");
00191         // find shared transitions
00192         tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00193         tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00194         for (; tit2 != tit2_end; ++tit2) {
00195           newstates = std::make_pair(tit1->X2, tit2->X2);
00196           // add to todo list if composition state is new
00197           rcit = rReverseCompositionMap.find(newstates);
00198           if (rcit == rReverseCompositionMap.end()) {
00199             todo.push(newstates);
00200             tmpstate = pResGen->InsState();
00201             rReverseCompositionMap[newstates] = tmpstate;
00202             FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00203                 << newstates.second << ") -> " 
00204                 << rReverseCompositionMap[newstates]);
00205           }
00206           else {
00207             tmpstate = rcit->second;
00208           }
00209           pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00210               tit1->Ev, tmpstate);
00211           FD_DF("Parallel:   add transition to new generator: " 
00212               << rReverseCompositionMap[currentstates] << "-" 
00213               << tit1->Ev << "-" << tmpstate);
00214         }
00215       }
00216     }
00217     // iterate over all rGen2 transitions 
00218     // (without execution of shared events)
00219     tit2 = rGen2.TransRelBegin(currentstates.second);
00220     tit2_end = rGen2.TransRelEnd(currentstates.second);
00221     for (; tit2 != tit2_end; ++tit2) {
00222       if (! sharedalphabet.Exists(tit2->Ev)) {
00223         FD_DF("Parallel:   exists only in rGen2");
00224         newstates = std::make_pair(currentstates.first, tit2->X2);
00225         // add to todo list if composition state is new
00226         rcit = rReverseCompositionMap.find(newstates);
00227         if (rcit == rReverseCompositionMap.end()) {
00228           todo.push(newstates);
00229           tmpstate = pResGen->InsState();
00230           rReverseCompositionMap[newstates] = tmpstate;
00231           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00232               << newstates.second << ") -> " 
00233               << rReverseCompositionMap[newstates]);
00234         }
00235         else {
00236           tmpstate = rcit->second;
00237         }
00238         pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00239             tit2->Ev, tmpstate);
00240         FD_DF("Parallel:   add transition to new generator: " 
00241             << rReverseCompositionMap[currentstates] << "-" 
00242             << tit2->Ev << "-" << tmpstate);
00243       }
00244     }
00245   }
00246 
00247   // set marked states
00248   for (lit1 = rGen1.MarkedStatesBegin(); 
00249       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00250     for (lit2 = rGen2.MarkedStatesBegin(); 
00251         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00252       currentstates = std::make_pair(*lit1, *lit2);
00253       rcit = rReverseCompositionMap.find(currentstates);
00254       if (rcit != rReverseCompositionMap.end()) {
00255         pResGen->SetMarkedState(rcit->second);
00256       }
00257     }
00258   }
00259   FD_DF("Parallel: set marked states at the end: " 
00260       << pResGen->MarkedStatesToString());
00261   // copy result
00262   if(pResGen != &rResGen) {
00263     rResGen = *pResGen;
00264     delete pResGen;
00265   }
00266 }
00267 
00268 
00269 // Product(rGen1, rGen2, res)
00270 void Product(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00271   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00272   Product(rGen1, rGen2, rcmap, rResGen);
00273 }
00274 
00275 
00276 // Product for vGenerators, transparent for event attributes.
00277 void aProduct(
00278   const vGenerator& rGen1,
00279   const vGenerator& rGen2,
00280   vGenerator& rResGen) 
00281 {
00282 
00283   // inputs have to agree on attributes of shared events:
00284   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00285 
00286   // prepare result
00287   vGenerator* pResGen = &rResGen;
00288   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00289     pResGen= rResGen.New();
00290   }
00291 
00292   // make product composition of inputs
00293   Product(rGen1,rGen2,*pResGen);
00294 
00295   // copy all attributes of input alphabets
00296   if(careattr) {
00297     pResGen->EventAttributes(rGen1.Alphabet());
00298     pResGen->EventAttributes(rGen2.Alphabet());
00299   }
00300 
00301   // copy result
00302   if(pResGen != &rResGen) {
00303     pResGen->Move(rResGen);
00304     delete pResGen;
00305   }
00306 
00307 }
00308 
00309 
00310 // Product(rGen1, rGen2, rReverseCompositionMap, res)
00311 void Product(
00312   const vGenerator& rGen1, const vGenerator& rGen2, 
00313   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00314   vGenerator& rResGen)
00315 {
00316   FD_DF("Product(" << &rGen1 << "," << &rGen2 << ")");
00317   // prepare result
00318   vGenerator* pResGen = &rResGen;
00319   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00320     pResGen= rResGen.New();
00321   }
00322   pResGen->Clear();
00323   // shared alphabet
00324   pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
00325   FD_DF("Product: shared alphabet: "
00326       << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
00327 
00328   // todo stack
00329   std::stack< std::pair<Idx,Idx> > todo;
00330   // actual pair, new pair
00331   std::pair<Idx,Idx> currentstates, newstates;
00332   // state
00333   Idx tmpstate;
00334   
00335   StateSet::Iterator lit1, lit2;
00336   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00337   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00338 
00339   // push all combinations of initial states on todo stack
00340   FD_DF("Product: adding all combinations of initial states to todo:");
00341   for (lit1 = rGen1.InitStatesBegin(); 
00342       lit1 != rGen1.InitStatesEnd(); ++lit1) {
00343     for (lit2 = rGen2.InitStatesBegin(); 
00344         lit2 != rGen2.InitStatesEnd(); ++lit2) {
00345       currentstates = std::make_pair(*lit1, *lit2);
00346       todo.push(currentstates);
00347       rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00348       FD_DF("Product:   (" << *lit1 << "|" << *lit2 << ") -> " 
00349           << rReverseCompositionMap[currentstates]);
00350     }
00351   }
00352 
00353   // start algorithm
00354   FD_DF("Product: processing reachable states:");
00355   while (! todo.empty()) {
00356     // get next reachable state from todo stack
00357     currentstates = todo.top();
00358     todo.pop();
00359     FD_DF("Product: processing (" << currentstates.first << "|" 
00360         << currentstates.second << ") -> " << rReverseCompositionMap[currentstates]);
00361     // iterate over all rGen1 transitions
00362     tit1 = rGen1.TransRelBegin(currentstates.first);
00363     tit1_end = rGen1.TransRelEnd(currentstates.first);
00364     tit2 = rGen2.TransRelBegin(currentstates.second);
00365     tit2_end = rGen2.TransRelEnd(currentstates.second);
00366     while ((tit1 != tit1_end) && (tit2 != tit2_end)) {
00367       // shared event
00368       if (tit1->Ev == tit2->Ev) {
00369         newstates = std::make_pair(tit1->X2, tit2->X2);
00370         // add to todo list if composition state is new
00371         rcit = rReverseCompositionMap.find(newstates);
00372         if (rcit == rReverseCompositionMap.end()) {
00373           todo.push(newstates);
00374           tmpstate = pResGen->InsState();
00375           rReverseCompositionMap[newstates] = tmpstate;
00376           FD_DF("Product: todo push: (" << newstates.first << "|" 
00377               << newstates.second << ") -> " << rReverseCompositionMap[newstates]);
00378         }
00379         else {
00380           tmpstate = rcit->second;
00381         }
00382         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, tmpstate);
00383         FD_DF("Product: add transition to new generator: " 
00384             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
00385         ++tit1;
00386         ++tit2;
00387       }
00388       // try resync tit1
00389       else if (tit1->Ev < tit2->Ev) {
00390         ++tit1;
00391       }
00392       // try resync tit2
00393       else if (tit1->Ev > tit2->Ev) {
00394         ++tit2;
00395       }
00396     }
00397   }
00398 
00399   // set marked states
00400   for (lit1 = rGen1.MarkedStatesBegin(); 
00401       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00402     for (lit2 = rGen2.MarkedStatesBegin(); 
00403         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00404       currentstates = std::make_pair(*lit1, *lit2);
00405       rcit = rReverseCompositionMap.find(currentstates);
00406       if (rcit != rReverseCompositionMap.end()) {
00407         pResGen->SetMarkedState(rcit->second);
00408       }
00409     }
00410   }
00411   FD_DF("Product: set marked states at the end: " 
00412       << pResGen->MarkedStatesToString());
00413   // copy result (TODO: use move)
00414   if(pResGen != &rResGen) {
00415     rResGen = *pResGen;
00416     delete pResGen;
00417   }
00418 }
00419 
00420 // helper class
00421 class OPState {
00422 public:
00423   // minimal interface
00424   OPState() {};
00425   OPState(const Idx& rq1, const Idx& rq2, const bool& rf) :
00426     q1(rq1), q2(rq2), m1required(rf), mresolved(false) {};
00427   std::string Str(void) { return ToStringInteger(q1)+"|"+
00428       ToStringInteger(q2)+"|"+ToStringInteger(m1required); };
00429   // order
00430   bool operator < (const OPState& other) const {
00431     if (q1 < other.q1) return(true);
00432     if (q1 > other.q1) return(false);
00433     if (q2 < other.q2) return(true);
00434     if (q2 > other.q2) return(false);
00435     if (m1required && !other.m1required) return(true);
00436     return(false);
00437   }
00438   // member variables
00439   Idx q1;
00440   Idx q2;
00441   bool m1required;
00442   bool mresolved;
00443 };
00444 
00445 
00446 
00447 
00448 // OmegaParallel for vGenerators, transparent for event attributes.
00449 void aOmegaParallel(
00450   const vGenerator& rGen1,
00451   const vGenerator& rGen2,
00452   vGenerator& rResGen) 
00453 {
00454 
00455   // inputs have to agree on attributes of shared events:
00456   bool careattr=rGen1.Alphabet().EqualAttributes(rGen2.Alphabet());
00457 
00458   // prepare result
00459   vGenerator* pResGen = &rResGen;
00460   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00461     pResGen= rResGen.New();
00462   }
00463 
00464   // make product composition of inputs
00465   OmegaParallel(rGen1,rGen2,*pResGen);
00466 
00467   // copy all attributes of input alphabets
00468   if(careattr) {
00469     pResGen->EventAttributes(rGen1.Alphabet());
00470     pResGen->EventAttributes(rGen2.Alphabet());
00471   }
00472 
00473   // copy result
00474   if(pResGen != &rResGen) {
00475     pResGen->Move(rResGen);
00476     delete pResGen;
00477   }
00478 
00479 }
00480 
00481 
00482 
00483 // OmegaParallel(rGen1, rGen2, res)
00484 void OmegaParallel(
00485   const vGenerator& rGen1, const vGenerator& rGen2, 
00486   vGenerator& rResGen)
00487 {
00488   FD_DF("OmegaParallel(" << &rGen1 << "," << &rGen2 << ")");
00489   // prepare result
00490   vGenerator* pResGen = &rResGen;
00491   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00492     pResGen= rResGen.New();
00493   }
00494   pResGen->Clear();
00495   pResGen->Name(CollapsString(rGen1.Name()+"|||"+rGen2.Name()));
00496   // rGen1.events() \ rGen2.events()
00497   EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00498   FD_DF("OmegaParallel: shared events: " << sharedalphabet.ToString());
00499 
00500   // create res alphabet
00501   EventSet::Iterator eit;
00502   for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00503     pResGen->InsEvent(*eit);
00504   }
00505   for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00506     pResGen->InsEvent(*eit);
00507   }
00508   FD_DF("OmegaParallel: inserted indices in rResGen.alphabet( "
00509       << pResGen->AlphabetToString() << ")");
00510 
00511   // reverse composition map
00512   std::map< OPState, Idx> reverseCompositionMap;
00513   // todo stack
00514   std::stack< OPState > todo;
00515   // actual pair, new pair
00516   OPState currentstates, newstates;
00517   // state
00518   Idx tmpstate;  
00519   StateSet::Iterator lit1, lit2;
00520   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00521   std::map< OPState, Idx>::iterator rcit;
00522   // push all combinations of initial states on todo stack
00523   FD_DF("OmegaParallel: adding all combinations of initial states to todo:");
00524   for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00525     for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00526       currentstates = OPState(*lit1, *lit2, true);
00527       todo.push(currentstates);
00528       reverseCompositionMap[currentstates] = pResGen->InsInitState();
00529       FD_DF("OmegaParallel:   " << currentstates.Str() << " -> " 
00530           << reverseCompositionMap[currentstates]);
00531     }
00532   }
00533 
00534   // start algorithm
00535   FD_DF("OmegaParallel: processing reachable states:");
00536   while (! todo.empty()) {
00537     // get next reachable state from todo stack
00538     currentstates = todo.top();
00539     todo.pop();
00540     FD_DF("OmegaParallel: processing (" << currentstates.Str() << " -> " 
00541         << reverseCompositionMap[currentstates]);
00542     // iterate over all rGen1 transitions 
00543     // (includes execution of shared events)
00544     tit1 = rGen1.TransRelBegin(currentstates.q1);
00545     tit1_end = rGen1.TransRelEnd(currentstates.q1);
00546     for (; tit1 != tit1_end; ++tit1) {
00547       // if event not shared
00548       if (! sharedalphabet.Exists(tit1->Ev)) {
00549         FD_DF("OmegaParallel:   exists only in rGen1");
00550         newstates = OPState(tit1->X2, currentstates.q2, currentstates.m1required);
00551         // figure whether marking was resolved
00552         if(currentstates.m1required) {
00553           if(rGen1.ExistsMarkedState(currentstates.q1))
00554             newstates.m1required=false;
00555         } else {
00556           if(rGen2.ExistsMarkedState(currentstates.q2))
00557             newstates.m1required=true;
00558         }
00559         // add to todo list if composition state is new
00560         rcit = reverseCompositionMap.find(newstates);
00561         if (rcit == reverseCompositionMap.end()) {
00562           todo.push(newstates);
00563           tmpstate = pResGen->InsState();
00564           if(!newstates.m1required)
00565     if(rGen2.ExistsMarkedState(newstates.q2))
00566             pResGen->SetMarkedState(tmpstate);                   
00567           reverseCompositionMap[newstates] = tmpstate;
00568           FD_DF("OmegaParallel:   todo push: " << newstates.Str() << "|" 
00569               << reverseCompositionMap[newstates]);
00570         }
00571         else {
00572           tmpstate = rcit->second;
00573         }
00574   // insert transition to result 
00575         pResGen->SetTransition(reverseCompositionMap[currentstates], tit1->Ev, 
00576             tmpstate);
00577         FD_DF("OmegaParallel:  add transition to new generator: " << 
00578         pResGen->TStr(reverseCompositionMap[currentstates], tit1->Ev, tmpstate));
00579       }
00580       // if shared event
00581       else {
00582         FD_DF("OmegaParallel:   common event");
00583         // find shared transitions
00584         tit2 = rGen2.TransRelBegin(currentstates.q2, tit1->Ev);
00585         tit2_end = rGen2.TransRelEnd(currentstates.q2, tit1->Ev);
00586         for (; tit2 != tit2_end; ++tit2) {
00587           newstates = OPState(tit1->X2, tit2->X2,currentstates.m1required);
00588           // figure whether marking was resolved
00589           if(currentstates.m1required) {
00590         if(rGen1.ExistsMarkedState(currentstates.q1))
00591         newstates.m1required=false;
00592           } else {
00593         if(rGen2.ExistsMarkedState(currentstates.q2))
00594         newstates.m1required=true;
00595           }
00596           // add to todo list if composition state is new
00597           rcit = reverseCompositionMap.find(newstates);
00598           if (rcit == reverseCompositionMap.end()) {
00599             todo.push(newstates);
00600             tmpstate = pResGen->InsState();
00601             if(!newstates.m1required)
00602         if(rGen2.ExistsMarkedState(newstates.q2))
00603               pResGen->SetMarkedState(tmpstate);                   
00604             reverseCompositionMap[newstates] = tmpstate;
00605             FD_DF("OmegaParallel:   todo push: (" << newstates.Str() << ") -> " 
00606                 << reverseCompositionMap[newstates]);
00607           }
00608           else {
00609             tmpstate = rcit->second;
00610           }
00611           pResGen->SetTransition(reverseCompositionMap[currentstates], 
00612               tit1->Ev, tmpstate);
00613           FD_DF("OmegaParallel:  add transition to new generator: " << 
00614         pResGen->TStr(reverseCompositionMap[currentstates], tit1->Ev tmpstate));
00615         }
00616       }
00617     }
00618     // iterate over all remaining rGen2 transitions 
00619     // (without execution of shared events)
00620     tit2 = rGen2.TransRelBegin(currentstates.q2);
00621     tit2_end = rGen2.TransRelEnd(currentstates.q2);
00622     for (; tit2 != tit2_end; ++tit2) {
00623       if (! sharedalphabet.Exists(tit2->Ev)) {
00624         FD_DF("OmegaParallel:   exists only in rGen2");
00625         newstates = OPState(currentstates.q1, tit2->X2, currentstates.m1required);
00626         // figure whether marking was resolved
00627         if(currentstates.m1required) {
00628           if(rGen1.ExistsMarkedState(currentstates.q1))
00629             newstates.m1required=false;
00630         } else {
00631           if(rGen2.ExistsMarkedState(currentstates.q2))
00632             newstates.m1required=true;
00633         }
00634         // add to todo list if composition state is new
00635         rcit = reverseCompositionMap.find(newstates);
00636         if (rcit == reverseCompositionMap.end()) {
00637           todo.push(newstates);
00638           tmpstate = pResGen->InsState();
00639           if(!newstates.m1required)
00640     if(rGen2.ExistsMarkedState(newstates.q2))
00641             pResGen->SetMarkedState(tmpstate);                   
00642           reverseCompositionMap[newstates] = tmpstate;
00643           FD_DF("OmegaParallel:   todo push: " << newstates.Str() << " -> " 
00644               << reverseCompositionMap[newstates]);
00645         }
00646         else {
00647           tmpstate = rcit->second;
00648         }
00649         pResGen->SetTransition(reverseCompositionMap[currentstates], 
00650             tit2->Ev, tmpstate);
00651         FD_DF("OmegaParallel:  add transition to new generator: " << 
00652         pResGen->TStr(reverseCompositionMap[currentstates], tit2->Ev tmpstate));
00653       }
00654     }
00655   }
00656 
00657   FD_DF("OmegaParallel: marked states: " 
00658       << pResGen->MarkedStatesToString());
00659 
00660 
00661   // fix statenames ...
00662   if(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00663   for(rcit=reverseCompositionMap.begin(); rcit!=reverseCompositionMap.end(); rcit++) {
00664     Idx x1=rcit->first.q1;
00665     Idx x2=rcit->first.q2;
00666     bool m1requ=rcit->first.m1required;
00667     Idx x12=rcit->second;
00668     if(!pResGen->ExistsState(x12)) continue;
00669     std::string name1= rGen1.StateName(x1);
00670     if(name1=="") name1=ToStringInteger(x1);
00671     std::string name2= rGen2.StateName(x2);
00672     if(name2=="") name1=ToStringInteger(x2);
00673     std::string name12;
00674     if(m1requ) name12= name1 + "|" + name2 + "|r1m";
00675     else name12= name1 + "|" + name2 + "|r2m";
00676     name12=pResGen->UniqueStateName(name12);
00677     pResGen->StateName(x12,name12);
00678   }
00679 
00680   // .. or clear them (?)
00681   if(!(rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled())) 
00682     pResGen->ClearStateNames();
00683 
00684   // copy result
00685   if(pResGen != &rResGen) {
00686     pResGen->Move(rResGen);
00687     delete pResGen;
00688   }
00689 }
00690 
00691 
00692 // SetParallelStateNames
00693 void SetComposedStateNames(
00694   const vGenerator& rGen1, const vGenerator& rGen2, 
00695   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00696   vGenerator& rGen12)
00697 {
00698   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00699   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00700     Idx x1=rcit->first.first;
00701     Idx x2=rcit->first.second;
00702     Idx x12=rcit->second;
00703     if(!rGen12.ExistsState(x12)) continue;
00704     std::string name1= rGen1.StateName(x1);
00705     if(name1=="") name1=ToStringInteger(x1);
00706     std::string name2= rGen2.StateName(x2);
00707     if(name2=="") name2=ToStringInteger(x2);
00708     std::string name12= name1 + "|" + name2;
00709     name12=rGen12.UniqueStateName(name12);
00710     rGen12.StateName(x12,name12);
00711   }
00712 }
00713 
00714 
00715 // CompositionMap1
00716 void CompositionMap1(
00717   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00718   std::map<Idx,Idx>& rCompositionMap)
00719 {
00720   rCompositionMap.clear();
00721   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00722   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00723     rCompositionMap.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.first));
00724 }
00725 
00726 
00727 // CompositionMap2
00728 void CompositionMap2(
00729   const std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00730   std::map<Idx,Idx>& rCompositionMap)
00731 {
00732   rCompositionMap.clear();
00733   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00734   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00735     rCompositionMap.insert(std::pair<Idx,Idx>(rcit->second,rcit->first.second));
00736 }
00737 
00738 
00739 } // name space

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6