parallel.cpp

Go to the documentation of this file.
00001 
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.NewP();
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(rGen1, rGen2, rReverseCompositionMap, res)
00051 void Parallel(
00052   const vGenerator& rGen1, const vGenerator& rGen2, 
00053   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00054   vGenerator& rResGen)
00055 {
00056   FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
00057   // prepare result
00058   vGenerator* pResGen = &rResGen;
00059   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00060     pResGen= rResGen.NewP();
00061   }
00062   pResGen->Clear();
00063   pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
00064   // rGen1.events() \ rGen2.events()
00065   EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00066   FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
00067 
00068   // create res alphabet
00069   EventSet::Iterator eit;
00070   for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00071     pResGen->InsEvent(*eit);
00072   }
00073   for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00074     pResGen->InsEvent(*eit);
00075   }
00076   FD_DF("Parallel: inserted indices in rResGen.alphabet( "
00077       << pResGen->AlphabetToString() << ")");
00078 
00079   // todo stack
00080   std::stack< std::pair<Idx,Idx> > todo;
00081   // actual pair, new pair
00082   std::pair<Idx,Idx> currentstates, newstates;
00083   // state
00084   Idx tmpstate;  
00085   StateSet::Iterator lit1, lit2;
00086   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00087   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00088 
00089   // push all combinations of initial states on todo stack
00090   FD_DF("Parallel: adding all combinations of initial states to todo:");
00091   for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00092     for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00093       currentstates = std::make_pair(*lit1, *lit2);
00094       todo.push(currentstates);
00095       rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00096       FD_DF("Parallel:   (" << *lit1 << "|" << *lit2 << ") -> " 
00097           << rReverseCompositionMap[currentstates]);
00098     }
00099   }
00100 
00101   // start algorithm
00102   FD_DF("Parallel: processing reachable states:");
00103   while (! todo.empty()) {
00104     // get next reachable state from todo stack
00105     currentstates = todo.top();
00106     todo.pop();
00107     FD_DF("Parallel: processing (" << currentstates.first << "|" 
00108         << currentstates.second << ") -> " 
00109         << rReverseCompositionMap[currentstates]);
00110     // iterate over all rGen1 transitions 
00111     // (includes execution of shared events)
00112     tit1 = rGen1.TransRelBegin(currentstates.first);
00113     tit1_end = rGen1.TransRelEnd(currentstates.first);
00114     for (; tit1 != tit1_end; ++tit1) {
00115       // if event not shared
00116       if (! sharedalphabet.Exists(tit1->Ev)) {
00117         FD_DF("Parallel:   exists only in rGen1");
00118         newstates = std::make_pair(tit1->X2, currentstates.second);
00119         // add to todo list if composition state is new
00120         rcit = rReverseCompositionMap.find(newstates);
00121         if (rcit == rReverseCompositionMap.end()) {
00122           todo.push(newstates);
00123           tmpstate = pResGen->InsState();
00124           rReverseCompositionMap[newstates] = tmpstate;
00125           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00126               << newstates.second << ") -> " 
00127               << rReverseCompositionMap[newstates]);
00128         }
00129         else {
00130           tmpstate = rcit->second;
00131         }
00132         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, 
00133             tmpstate);
00134         FD_DF("Parallel:   add transition to new generator: " 
00135             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" 
00136             << tmpstate);
00137       }
00138       // if shared event
00139       else {
00140         FD_DF("Parallel:   common event");
00141         // find shared transitions
00142         tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00143         tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00144         for (; tit2 != tit2_end; ++tit2) {
00145           newstates = std::make_pair(tit1->X2, tit2->X2);
00146           // add to todo list if composition state is new
00147           rcit = rReverseCompositionMap.find(newstates);
00148           if (rcit == rReverseCompositionMap.end()) {
00149             todo.push(newstates);
00150             tmpstate = pResGen->InsState();
00151             rReverseCompositionMap[newstates] = tmpstate;
00152             FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00153                 << newstates.second << ") -> " 
00154                 << rReverseCompositionMap[newstates]);
00155           }
00156           else {
00157             tmpstate = rcit->second;
00158           }
00159           pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00160               tit1->Ev, tmpstate);
00161           FD_DF("Parallel:   add transition to new generator: " 
00162               << rReverseCompositionMap[currentstates] << "-" 
00163               << tit1->Ev << "-" << tmpstate);
00164         }
00165       }
00166     }
00167     // iterate over all rGen2 transitions 
00168     // (without execution of shared events)
00169     tit2 = rGen2.TransRelBegin(currentstates.second);
00170     tit2_end = rGen2.TransRelEnd(currentstates.second);
00171     for (; tit2 != tit2_end; ++tit2) {
00172       if (! sharedalphabet.Exists(tit2->Ev)) {
00173         FD_DF("Parallel:   exists only in rGen2");
00174         newstates = std::make_pair(currentstates.first, tit2->X2);
00175         // add to todo list if composition state is new
00176         rcit = rReverseCompositionMap.find(newstates);
00177         if (rcit == rReverseCompositionMap.end()) {
00178           todo.push(newstates);
00179           tmpstate = pResGen->InsState();
00180           rReverseCompositionMap[newstates] = tmpstate;
00181           FD_DF("Parallel:   todo push: (" << newstates.first << "|" 
00182               << newstates.second << ") -> " 
00183               << rReverseCompositionMap[newstates]);
00184         }
00185         else {
00186           tmpstate = rcit->second;
00187         }
00188         pResGen->SetTransition(rReverseCompositionMap[currentstates], 
00189             tit2->Ev, tmpstate);
00190         FD_DF("Parallel:   add transition to new generator: " 
00191             << rReverseCompositionMap[currentstates] << "-" 
00192             << tit2->Ev << "-" << tmpstate);
00193       }
00194     }
00195   }
00196 
00197   // set marked states
00198   for (lit1 = rGen1.MarkedStatesBegin(); 
00199       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00200     for (lit2 = rGen2.MarkedStatesBegin(); 
00201         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00202       currentstates = std::make_pair(*lit1, *lit2);
00203       rcit = rReverseCompositionMap.find(currentstates);
00204       if (rcit != rReverseCompositionMap.end()) {
00205         pResGen->SetMarkedState(rcit->second);
00206       }
00207     }
00208   }
00209   FD_DF("Parallel: set marked states at the end: " 
00210       << pResGen->MarkedStatesToString());
00211   // copy result
00212   if(pResGen != &rResGen) {
00213     rResGen = *pResGen;
00214     delete pResGen;
00215   }
00216 }
00217 
00218 
00219 // SParallel(rGen1, rGen2, res)
00220 void SParallel(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00221   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00222   SParallel(rGen1, rGen2, rcmap, rResGen);
00223 }
00224 
00225 
00226 // SParallel(rGen1, rGen2, rReverseCompositionMap, res)
00227 void SParallel(
00228   const vGenerator& rGen1, const vGenerator& rGen2, 
00229   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00230   vGenerator& rResGen)
00231 {
00232   FD_DF("SParallel(" << &rGen1 << "," << &rGen2 << ")");
00233   // prepare result
00234   vGenerator* pResGen = &rResGen;
00235   if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00236     pResGen= rResGen.NewP();
00237   }
00238   pResGen->Clear();
00239   // shared alphabet
00240   pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
00241   FD_DF("SParallel: shared alphabet: "
00242       << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
00243 
00244   // todo stack
00245   std::stack< std::pair<Idx,Idx> > todo;
00246   // actual pair, new pair
00247   std::pair<Idx,Idx> currentstates, newstates;
00248   // state
00249   Idx tmpstate;
00250   
00251   StateSet::Iterator lit1, lit2;
00252   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00253   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00254 
00255   // push all combinations of initial states on todo stack
00256   FD_DF("SParallel: adding all combinations of initial states to todo:");
00257   for (lit1 = rGen1.InitStatesBegin(); 
00258       lit1 != rGen1.InitStatesEnd(); ++lit1) {
00259     for (lit2 = rGen2.InitStatesBegin(); 
00260         lit2 != rGen2.InitStatesEnd(); ++lit2) {
00261       currentstates = std::make_pair(*lit1, *lit2);
00262       todo.push(currentstates);
00263       rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00264       FD_DF("SParallel:   (" << *lit1 << "|" << *lit2 << ") -> " 
00265           << rReverseCompositionMap[currentstates]);
00266     }
00267   }
00268 
00269   // start algorithm
00270   FD_DF("SParallel: processing reachable states:");
00271   while (! todo.empty()) {
00272     // get next reachable state from todo stack
00273     currentstates = todo.top();
00274     todo.pop();
00275     FD_DF("SParallel: processing (" << currentstates.first << "|" 
00276         << currentstates.second << ") -> " << rReverseCompositionMap[currentstates]);
00277     // iterate over all rGen1 transitions
00278     tit1 = rGen1.TransRelBegin(currentstates.first);
00279     tit1_end = rGen1.TransRelEnd(currentstates.first);
00280     tit2 = rGen2.TransRelBegin(currentstates.second);
00281     tit2_end = rGen2.TransRelEnd(currentstates.second);
00282     while ((tit1 != tit1_end) && (tit2 != tit2_end)) {
00283       // shared event
00284       if (tit1->Ev == tit2->Ev) {
00285         newstates = std::make_pair(tit1->X2, tit2->X2);
00286         // add to todo list if composition state is new
00287         rcit = rReverseCompositionMap.find(newstates);
00288         if (rcit == rReverseCompositionMap.end()) {
00289           todo.push(newstates);
00290           tmpstate = pResGen->InsState();
00291           rReverseCompositionMap[newstates] = tmpstate;
00292           FD_DF("SParallel: todo push: (" << newstates.first << "|" 
00293               << newstates.second << ") -> " << rReverseCompositionMap[newstates]);
00294         }
00295         else {
00296           tmpstate = rcit->second;
00297         }
00298         pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, tmpstate);
00299         FD_DF("SParallel: add transition to new generator: " 
00300             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
00301         ++tit1;
00302         ++tit2;
00303       }
00304       // try resync tit1
00305       else if (tit1->Ev < tit2->Ev) {
00306         ++tit1;
00307       }
00308       // try resync tit2
00309       else if (tit1->Ev > tit2->Ev) {
00310         ++tit2;
00311       }
00312     }
00313   }
00314 
00315   // set marked states
00316   for (lit1 = rGen1.MarkedStatesBegin(); 
00317       lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00318     for (lit2 = rGen2.MarkedStatesBegin(); 
00319         lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00320       currentstates = std::make_pair(*lit1, *lit2);
00321       rcit = rReverseCompositionMap.find(currentstates);
00322       if (rcit != rReverseCompositionMap.end()) {
00323         pResGen->SetMarkedState(rcit->second);
00324       }
00325     }
00326   }
00327   FD_DF("SParallel: set marked states at the end: " 
00328       << pResGen->MarkedStatesToString());
00329   // copy result
00330   if(pResGen != &rResGen) {
00331     rResGen = *pResGen;
00332     delete pResGen;
00333   }
00334 }
00335 
00336 
00337 
00338 
00339 // SetParallelStateNames
00340 void SetComposedStateNames(
00341   const vGenerator& rGen1, const vGenerator& rGen2, 
00342   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00343   vGenerator& rGen12)
00344 {
00345   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00346   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00347     Idx x1=rcit->first.first;
00348     Idx x2=rcit->first.second;
00349     Idx x12=rcit->second;
00350     if(!rGen12.ExistsState(x12)) continue;
00351     std::string name1= rGen1.StateName(x1);
00352     if(name1=="") name1=ToStringInteger(x1);
00353     std::string name2= rGen2.StateName(x2);
00354     if(name2=="") name1=ToStringInteger(x2);
00355     std::string name12= name1 + "|" + name2;
00356     name12=rGen12.UniqueStateName(name12);
00357     rGen12.StateName(x12,name12);
00358   }
00359 }
00360 
00361 
00362 } // name space

Generated on Fri May 9 11:26:47 2008 for libFAUDES 2.09b by  doxygen 1.4.4