| |
libFAUDES
Sections
Index
|
parallel.cppGo 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