00001
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "regular.h"
00034
00035
00036
00037
00038 #define Move Copy
00039
00040
00041
00042
00043 #define Product SParallel
00044
00045 namespace faudes {
00046
00047
00048 void LanguageUnionNonDet(const vGenerator& rGen1, const vGenerator& rGen2,
00049 vGenerator& rResGen) {
00050
00051 FD_DF("LanguageUnionNonDet("<< rGen1.Name()
00052 << "," << rGen2.Name() << ")");
00053
00054
00055 bool stateNamesEnabled=rResGen.StateNamesEnabled();
00056
00057
00058
00059 vGenerator* pResGen = &rResGen;
00060 if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00061 pResGen= rResGen.NewP();
00062 }
00063
00064
00065 pResGen->Clear();
00066
00067
00068 pResGen->InjectAlphabet(rGen1.Alphabet()+rGen2.Alphabet());
00069
00070
00071 std::map<Idx,Idx> Gen1StatesMap;
00072 std::map<Idx,Idx> Gen2StatesMap;
00073
00074
00075 StateSet::Iterator sit;
00076 for (sit = rGen1.StatesBegin(); sit != rGen1.StatesEnd(); ++sit) {
00077 if (stateNamesEnabled) {
00078 Gen1StatesMap[*sit] = pResGen->InsState(pResGen->UniqueStateName(rGen1.StateName(*sit)+"(1)"));
00079 }
00080 else {
00081 Gen1StatesMap[*sit] = pResGen->InsState();
00082 }
00083 }
00084 for (sit = rGen2.StatesBegin(); sit != rGen2.StatesEnd(); ++sit) {
00085 if (stateNamesEnabled) {
00086 Gen2StatesMap[*sit] = pResGen->InsState(pResGen->UniqueStateName(rGen2.StateName(*sit)+"(2)"));
00087 }
00088 else {
00089 Gen2StatesMap[*sit] = pResGen->InsState();
00090 }
00091 }
00092
00093
00094 TransSet::Iterator tit;
00095 for (tit = rGen1.TransRelBegin(); tit != rGen1.TransRelEnd(); ++tit) {
00096 pResGen->SetTransition(Gen1StatesMap[tit->X1], tit->Ev, Gen1StatesMap[tit->X2]);
00097 }
00098 for (tit = rGen2.TransRelBegin(); tit != rGen2.TransRelEnd(); ++tit) {
00099 pResGen->SetTransition(Gen2StatesMap[tit->X1], tit->Ev, Gen2StatesMap[tit->X2]);
00100 }
00101
00102
00103 for (sit = rGen1.InitStatesBegin(); sit != rGen1.InitStatesEnd(); ++sit) {
00104 pResGen->SetInitState(Gen1StatesMap[*sit]);
00105 }
00106 for (sit = rGen2.InitStatesBegin(); sit != rGen2.InitStatesEnd(); ++sit) {
00107 pResGen->SetInitState(Gen2StatesMap[*sit]);
00108 }
00109
00110
00111 for (sit = rGen1.MarkedStatesBegin(); sit != rGen1.MarkedStatesEnd(); ++sit) {
00112 pResGen->SetMarkedState(Gen1StatesMap[*sit]);
00113 }
00114 for (sit = rGen2.MarkedStatesBegin(); sit != rGen2.MarkedStatesEnd(); ++sit) {
00115 pResGen->SetMarkedState(Gen2StatesMap[*sit]);
00116 }
00117
00118
00119 pResGen->Name(CollapsString("UnionNonDet("+rGen1.Name()+","+rGen2.Name()+")"));
00120
00121
00122 if(pResGen != &rResGen) {
00123 pResGen->Move(rResGen);
00124 delete pResGen;
00125 }
00126
00127 }
00128
00129
00130 void LanguageUnion(const vGenerator& rGen1, const vGenerator& rGen2,
00131 vGenerator& rResGen) {
00132
00133 FD_DF("LanguageUnion("<< rGen1.Name()
00134 << "," << rGen2.Name() << ")");
00135
00136
00137 std::string name1 = rGen1.Name();
00138 std::string name2 = rGen2.Name();
00139
00140
00141 vGenerator* pTempGen = rResGen.NewP();
00142
00143
00144 LanguageUnionNonDet(rGen1, rGen2, *pTempGen);
00145
00146
00147 Deterministic(*pTempGen, rResGen);
00148
00149
00150 delete pTempGen;
00151
00152
00153 rResGen.Name(CollapsString("Union("+name1+","+name2+")"));
00154
00155 }
00156
00157
00158 void LanguageIntersection(const vGenerator& rGen1, const vGenerator& rGen2,
00159 vGenerator& rResGen) {
00160 FD_DF("LanguageIntersection("<< rGen1.Name()
00161 << "," << rGen2.Name() << ")");
00162
00163
00164 std::string name1 = rGen1.Name();
00165 std::string name2 = rGen2.Name();
00166
00167
00168 Product(rGen1, rGen2, rResGen);
00169 rResGen.Name(CollapsString("Intersection("+name1+","+name2+")"));
00170
00171 }
00172
00173
00174 bool EmptyLanguageIntersection(const vGenerator& rGen1, const vGenerator& rGen2) {
00175 FD_DF("EmptyLanguageIntersection("<< rGen1.Name()
00176 << "," << rGen2.Name() << ")");
00177
00178
00179
00180
00181
00182 Generator ProductGen;
00183 Product(rGen1, rGen2, ProductGen);
00184 return EmptyLanguage(ProductGen);
00185 }
00186
00187
00188 bool LanguageDisjoint(const vGenerator& rGen1, const vGenerator& rGen2) {
00189 FD_DF("LanguageDisjoint("<< rGen1.Name()
00190 << "," << rGen2.Name() << ")");
00191 return EmptyLanguageIntersection(rGen1,rGen2);
00192 }
00193
00194
00195 void Automaton(vGenerator& rGen, const EventSet& rAlphabet) {
00196 FD_DF("Automaton("<< rGen1.Name() << "," << rAlphabet.Name() << ")");
00197
00198
00199 #ifdef FAUDES_CHECKED
00200 if( !(rGen.Alphabet() <= rAlphabet) ){
00201 std::stringstream errstr;
00202 errstr << "Alphabet of generator " << rGen.Name() <<
00203 " has to be subset of alphabet "<< rAlphabet.Name() << ".";
00204 throw Exception("Automaton()", errstr.str(), 100);
00205 }
00206 #endif
00207
00208
00209 rGen.InjectAlphabet(rGen.Alphabet()+rAlphabet);
00210
00211
00212 rGen.Coaccessible();
00213
00214
00215
00216 if(EmptyLanguage(rGen)){
00217
00218
00219 std::string name;
00220 name=rGen.Name();
00221
00222 FullLanguage(rGen.Alphabet(),rGen);
00223 if (rGen.StateNamesEnabled()) {
00224 rGen.StateName(*(rGen.InitStatesBegin()),"dump");
00225 }
00226
00227 rGen.ClearMarkedStates();
00228
00229
00230 rGen.Name(CollapsString("Automaton(" + name + "," + rAlphabet.Name() + ")"));
00231 return;
00232 }
00233
00234
00235 #ifdef FAUDES_CHECKED
00236 if ( !(rGen.IsDeterministic()) ) {
00237 FD_WARN("Automaton(): nondeterministic parameter " << rGen.Name() <<".");
00238 }
00239 #endif
00240
00241
00242 rGen.Name(CollapsString("Automaton(" + rGen.Name() + "," + rAlphabet.Name() + ")"));
00243
00244
00245 Idx dump;
00246 if (rGen.StateNamesEnabled()) {
00247 std::string dumpstr=rGen.UniqueStateName("dump");
00248 dump = rGen.InsState(dumpstr);
00249 } else {
00250 dump = rGen.InsState();
00251 }
00252
00253
00254 StateSet::Iterator sit;
00255 EventSet::Iterator eit;
00256 bool dumpNotReached=true;
00257 for (sit = rGen.StatesBegin(); sit != rGen.StatesEnd(); ++sit) {
00258 for (eit = rGen.Alphabet().Begin(); eit != rGen.Alphabet().End(); ++eit) {
00259
00260
00261
00262 if (rGen.TransRelBegin(*sit, *eit) == rGen.TransRelEnd(*sit, *eit)) {
00263 rGen.SetTransition(*sit, *eit, dump);
00264
00265 if(*sit!=dump) dumpNotReached=false;
00266 }
00267 }
00268 }
00269
00270
00271 if(dumpNotReached)
00272 rGen.DelState(dump);
00273 }
00274
00275
00276 void Automaton(vGenerator& rGen) {
00277 FD_DF("Automaton("<< rGen1.Name() << ")");
00278 std::string name=rGen.Name();
00279 Automaton(rGen,rGen.Alphabet());
00280 rGen.Name(CollapsString("Automaton(" + name + ")"));
00281 }
00282
00283
00284 void LanguageComplement(vGenerator& rGen, const EventSet& rAlphabet) {
00285 FD_DF("LanguageComplement("<< rGen1.Name() << "," << rAlphabet.Name() << ")");
00286
00287
00288 #ifdef FAUDES_CHECKED
00289 if( !(rGen.Alphabet() <= rAlphabet) ){
00290 std::stringstream errstr;
00291 errstr << "Alphabet of generator " << rGen.Name() <<
00292 " has to be subset of alphabet "<< rAlphabet.Name() << ".";
00293 throw Exception("LanguageComplement()", errstr.str(), 100);
00294 }
00295 #endif
00296
00297 std::string name = rGen.Name();
00298
00299
00300 bool stateNamesEnabled=rGen.StateNamesEnabled();
00301 rGen.StateNamesEnabled(false);
00302 Automaton(rGen,rAlphabet);
00303 rGen.StateNamesEnabled(stateNamesEnabled);
00304
00305
00306 rGen.InjectMarkedStates(rGen.States() - rGen.MarkedStates());
00307
00308
00309 rGen.Name(CollapsString("Complement(" + name + "," + rAlphabet.Name() + ")"));
00310 }
00311
00312
00313 void LanguageComplement(vGenerator& rGen) {
00314 FD_DF("LanguageComplement("<< rGen1.Name() << ")");
00315 std::string name=rGen.Name();
00316 LanguageComplement(rGen,rGen.Alphabet());
00317 rGen.Name(CollapsString("Complement(" + name + ")"));
00318 return;
00319 }
00320
00321
00322 void LanguageConcatenateNonDet(const vGenerator& rGen1, const vGenerator& rGen2,
00323 vGenerator& rResGen) {
00324 FD_DF("LanguageConcatenateNonDet(" << rGen1.Name() << "," << rGen2.Name() << ")");
00325
00326
00327 bool stateNamesEnabled=rResGen.StateNamesEnabled();
00328
00329
00330
00331 vGenerator* pResGen = &rResGen;
00332 if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00333 pResGen= rResGen.NewP();
00334 }
00335
00336
00337 pResGen->Clear();
00338
00339
00340 pResGen->InjectAlphabet(rGen1.Alphabet() + rGen2.Alphabet());
00341
00342
00343 std::map<Idx,Idx> Gen1StatesMap;
00344 std::map<Idx,Idx> Gen2StatesMap;
00345
00346
00347 StateSet::Iterator sit;
00348 StateSet::Iterator sit1m, sit2i;
00349 TransSet::Iterator tit;
00350
00351
00352 for (sit = rGen1.StatesBegin(); sit != rGen1.StatesEnd(); ++sit) {
00353 if (stateNamesEnabled) {
00354 Gen1StatesMap[*sit] = pResGen->InsState(pResGen->UniqueStateName(rGen1.StateName(*sit)+"(1)"));
00355 }
00356 else {
00357 Gen1StatesMap[*sit] = pResGen->InsState();
00358 }
00359 }
00360 for (sit = rGen2.StatesBegin(); sit != rGen2.StatesEnd(); ++sit) {
00361 if (stateNamesEnabled) {
00362 Gen2StatesMap[*sit] = pResGen->InsState(pResGen->UniqueStateName(rGen2.StateName(*sit)+"(2)"));
00363 }
00364 else {
00365 Gen2StatesMap[*sit] = pResGen->InsState();
00366 }
00367 }
00368
00369
00370
00371
00372
00373 bool concatenateEpsilon=false;
00374 for (sit = rGen2.InitStatesBegin(); sit != rGen2.InitStatesEnd(); ++sit) {
00375 pResGen->DelState(Gen2StatesMap[*sit]);
00376 Gen2StatesMap.erase(*sit);
00377 if (rGen2.ExistsMarkedState(*sit)) {
00378 concatenateEpsilon=true;
00379 }
00380 }
00381
00382
00383 pResGen->InjectInitStates(rGen1.InitStates());
00384
00385
00386 for (sit = rGen1.InitStatesBegin(); sit != rGen1.InitStatesEnd(); ++sit) {
00387 pResGen->SetInitState(Gen1StatesMap[*sit]);
00388 }
00389
00390
00391 for (tit = rGen1.TransRelBegin(); tit != rGen1.TransRelEnd(); ++tit) {
00392 pResGen->SetTransition(Gen1StatesMap[tit->X1], tit->Ev, Gen1StatesMap[tit->X2]);
00393 }
00394
00395
00396
00397 for (sit2i = rGen2.InitStatesBegin(); sit2i != rGen2.InitStatesEnd(); ++sit2i) {
00398 for (tit = rGen2.TransRelBegin(*sit2i); tit != rGen2.TransRelEnd(*sit2i); ++tit) {
00399
00400 for (sit1m = rGen1.MarkedStatesBegin(); sit1m != rGen1.MarkedStatesEnd(); ++sit1m) {
00401
00402
00403 pResGen->SetTransition(Gen1StatesMap[*sit1m], tit->Ev, Gen2StatesMap[tit->X2]);
00404 }
00405 }
00406 }
00407
00408
00409 for (tit = rGen2.TransRelBegin(); tit != rGen2.TransRelEnd(); ++tit) {
00410
00411 if (rGen2.ExistsInitState(tit->X1)) {
00412 continue;
00413 }
00414 pResGen->SetTransition(Gen2StatesMap[tit->X1], tit->Ev, Gen2StatesMap[tit->X2]);
00415 }
00416
00417
00418 for (sit = rGen2.MarkedStatesBegin(); sit != rGen2.MarkedStatesEnd(); ++sit) {
00419 if(!(rGen2.ExistsInitState(*sit))) {
00420 pResGen->SetMarkedState(Gen2StatesMap[*sit]);
00421 }
00422 }
00423
00424
00425
00426 if(concatenateEpsilon){
00427 for (sit = rGen1.MarkedStatesBegin(); sit != rGen1.MarkedStatesEnd(); ++sit) {
00428 pResGen->SetMarkedState(Gen1StatesMap[*sit]);
00429 }
00430 }
00431
00432
00433 pResGen->Coaccessible();
00434 pResGen->Name("ConcatenateNonDet("+rGen1.Name()+","+rGen2.Name()+")");
00435
00436
00437 if(pResGen != &rResGen) {
00438 pResGen->Move(rResGen);
00439 delete pResGen;
00440 }
00441
00442 }
00443
00444
00445 void LanguageConcatenate(const vGenerator& rGen1, const vGenerator& rGen2,
00446 vGenerator& rResGen) {
00447
00448 FD_DF("LanguageConcatenate("<< rGen1.Name()
00449 << "," << rGen2.Name() << ")");
00450
00451
00452 LanguageConcatenateNonDet(rGen1, rGen2, rResGen);
00453
00454
00455 if(!(rResGen.IsDeterministic())){
00456 Deterministic(rResGen, rResGen);
00457 }
00458
00459
00460 rResGen.Name("Concatenate("+rGen1.Name()+","+rGen2.Name()+")");
00461
00462 return;
00463 }
00464
00465
00466 void FullLanguage(const EventSet& rAlphabet, vGenerator& rResGen) {
00467 FD_DF("FullLanguage("<< rAlphabet.Name()
00468 << "," << rResGen.Name() << ")");
00469
00470
00471 rResGen.Clear();
00472
00473
00474 Idx state;
00475 EventSet::Iterator evit;
00476
00477
00478 rResGen.InjectAlphabet(rAlphabet);
00479
00480
00481 if(rResGen.StateNamesEnabled()){
00482 state = rResGen.InsInitState("1");
00483 } else{
00484 state = rResGen.InsInitState();
00485 }
00486 rResGen.SetMarkedState(state);
00487
00488
00489 for (evit = rAlphabet.Begin(); evit != rAlphabet.End(); ++evit) {
00490 rResGen.SetTransition(state, *evit, state);
00491 }
00492
00493
00494 rResGen.Name("FullLanguage("+rAlphabet.Name()+")");
00495
00496 return;
00497 }
00498
00499
00500 void AlphabetLanguage(const EventSet& rAlphabet, vGenerator& rResGen) {
00501 FD_DF("AlphabetLanguage("<< rAlphabet.Name()
00502 << "," << rResGen.Name() << ")");
00503
00504
00505 rResGen.Clear();
00506
00507
00508 rResGen.Name("AlphabetLanguage("+rAlphabet.Name()+")");
00509
00510
00511 if(rAlphabet.Empty()){
00512 FD_WARN("AlphabetLanguage: empty alphabet.");
00513 return;
00514 }
00515
00516
00517 Idx istate, mstate;
00518 EventSet::Iterator evit;
00519
00520
00521 rResGen.InjectAlphabet(rAlphabet);
00522
00523
00524 if(rResGen.StateNamesEnabled()){
00525 istate = rResGen.InsInitState("1");
00526 mstate = rResGen.InsMarkedState("2");
00527 }
00528 else{
00529 istate = rResGen.InsInitState();
00530 mstate = rResGen.InsMarkedState();
00531 }
00532
00533
00534 for (evit = rAlphabet.Begin(); evit != rAlphabet.End(); ++evit) {
00535 rResGen.SetTransition(istate, *evit, mstate);
00536 }
00537
00538 return;
00539 }
00540
00541
00542 void EmptyStringLanguage(const EventSet& rAlphabet, vGenerator& rResGen) {
00543 FD_DF("EmptyStringLanguage("<< rAlphabet.Name()
00544 << "," << rResGen.Name() << ")");
00545
00546
00547 rResGen.Clear();
00548
00549
00550 Idx state;
00551
00552
00553 rResGen.InjectAlphabet(rAlphabet);
00554
00555
00556 if(rResGen.StateNamesEnabled()){
00557 state = rResGen.InsInitState("1");
00558 }
00559 else{
00560 state = rResGen.InsInitState();
00561 }
00562 rResGen.SetMarkedState(state);
00563
00564
00565 rResGen.Name("EmptyStringLanguage("+rAlphabet.Name()+")");
00566
00567 return;
00568 }
00569
00570
00571 void EmptyLanguage(const EventSet& rAlphabet, vGenerator& rResGen) {
00572 FD_DF("EmptyStringLanguage("<< rAlphabet.Name()
00573 << "," << rResGen.Name() << ")");
00574
00575
00576 rResGen.Clear();
00577
00578
00579 rResGen.InjectAlphabet(rAlphabet);
00580
00581
00582 rResGen.Name("EmptyLanguage("+rAlphabet.Name()+")");
00583
00584 return;
00585 }
00586
00587
00588 bool EmptyLanguage(const vGenerator& rGen) {
00589
00590 if(rGen.MarkedStatesSize()==0) return true;
00591
00592 return (rGen.AccessibleSet()*rGen.MarkedStates()).Empty();
00593 }
00594
00595
00596 bool LanguageInclusion(const vGenerator& rGen1, const vGenerator& rGen2) {
00597
00598 FD_DF("LanguageInclusion("<< rGen1.Name() << "," << rGen2.Name() << ")");
00599
00600
00601 Generator NotrGen2=rGen2;
00602
00603
00604 LanguageComplement(NotrGen2 , rGen1.Alphabet()+rGen2.Alphabet());
00605 return EmptyLanguageIntersection(rGen1,NotrGen2);
00606 }
00607
00608
00609 bool LanguageEquality(const vGenerator& rGen1, const vGenerator& rGen2) {
00610
00611 FD_DF("LanguageEquality("<< rGen1.Name() << "," << rGen2.Name() << ")");
00612
00613
00614 return LanguageInclusion(rGen1,rGen2) && LanguageInclusion(rGen2,rGen1);
00615 }
00616
00617
00618 void KleeneClosure(vGenerator& rGen) {
00619
00620 FD_DF("KleeneClosure("<< rGen.Name() << ")");
00621
00622
00623 std::string name=CollapsString("KleeneClosure(" + rGen.Name() + ")");
00624
00625
00626 if(EmptyLanguage(rGen)){
00627 rGen.Name(name);
00628 return;
00629 }
00630
00631
00632 KleeneClosureNonDet(rGen);
00633 Deterministic(rGen, rGen);
00634
00635
00636 rGen.Name(name);
00637 }
00638
00639
00640 void KleeneClosureNonDet(vGenerator& rGen) {
00641
00642 FD_DF("KleeneClosureNonDet("<< rGen.Name() << ")");
00643
00644
00645 rGen.Name(CollapsString("KleeneClosureNonDet("+ rGen.Name() + ")"));
00646
00647
00648 if(EmptyLanguage(rGen)) return;
00649
00650
00651 TransSet::Iterator tit;
00652 StateSet::Iterator init = rGen.InitStatesBegin();
00653 TransSet TransToInsert;
00654
00655
00656
00657
00658
00659
00660 for (tit = rGen.TransRelBegin(); tit != rGen.TransRelEnd(); ++tit) {
00661
00662 if(rGen.ExistsMarkedState(tit->X2)) {
00663 if( !(rGen.ExistsTransition(tit->X1, tit->Ev, *init)) ){
00664 TransToInsert.Insert(tit->X1, tit->Ev, *init);
00665 }
00666 }
00667
00668 }
00669
00670 for (tit = TransToInsert.Begin(); tit != TransToInsert.End(); ++tit) {
00671 rGen.SetTransition(*tit);
00672 }
00673
00674
00675
00676 rGen.SetMarkedState(*init);
00677 }
00678
00679
00680 void PrefixClosure(vGenerator& rGen) {
00681
00682 FD_DF("PrefixClosure("<< name << ")");
00683
00684
00685 std::string name=CollapsString("PrefixClosure("+ rGen.Name() + ")");
00686
00687
00688 rGen.Coaccessible();
00689
00690
00691 rGen.InjectMarkedStates(rGen.States());
00692
00693
00694 rGen.Name(name);
00695
00696 }
00697
00698
00699 void SelfLoop(vGenerator& rGen,const EventSet& rAlphabet) {
00700
00701 FD_DF("SelfLoop(" << rGen.Name() << "," << rAlphabet.Name() << ")");
00702
00703
00704 std::string name = CollapsString("SelfLoop(" + rGen.Name() + "," + rAlphabet.Name() + ")");
00705
00706 rGen.InjectAlphabet(rGen.Alphabet()+rAlphabet);
00707
00708
00709 EventSet::Iterator evit,evbegin,evend;
00710 evbegin = rAlphabet.Begin();
00711 evend = rAlphabet.End();
00712 StateSet::Iterator sit;
00713
00714
00715 for (sit = rGen.StatesBegin(); sit != rGen.StatesEnd(); ++sit) {
00716 for(evit = evbegin; evit != evend; ++evit){
00717 rGen.SetTransition(*sit, *evit, *sit);
00718 }
00719 }
00720
00721
00722 rGen.Name(name);
00723 }
00724
00725
00726 void SelfLoopMarkedStates(vGenerator& rGen,const EventSet& rAlphabet) {
00727
00728 FD_DF("SelfLoopMarkedStates(" << rGen.Name() << "," << rAlphabet.Name() << ")");
00729
00730
00731 std::string name = CollapsString("SelfLoopMarkedStates(" + rGen.Name()
00732 + "," + rAlphabet.Name() + ")");
00733
00734
00735 rGen.InjectAlphabet(rGen.Alphabet()+rAlphabet);
00736
00737
00738 EventSet::Iterator evit,evbegin,evend;
00739 evbegin = rAlphabet.Begin();
00740 evend = rAlphabet.End();
00741 StateSet::Iterator sit;
00742
00743
00744 for (sit = rGen.MarkedStatesBegin(); sit != rGen.MarkedStatesEnd(); ++sit) {
00745 for(evit = evbegin; evit != evend; ++evit){
00746 rGen.SetTransition(*sit, *evit, *sit);
00747 }
00748 }
00749
00750
00751 rGen.Name(name);
00752 }
00753
00754
00755 void SelfLoop(vGenerator& rGen,const EventSet& rAlphabet,const StateSet& rStates) {
00756
00757 FD_DF("SelfLoop(" << rGen.Name() << "," << rAlphabet.Name() << "," << rStates.Name() << ")");
00758
00759
00760 std::string name = CollapsString("SelfLoop(" + rGen.Name()
00761 + "," + rAlphabet.Name() + "," + rStates.Name() + ")");
00762
00763
00764 #ifdef FAUDES_CHECKED
00765 if( !(rStates <= rGen.States()) ){
00766 std::stringstream errstr;
00767 errstr << "State set " << rStates.Name() <<
00768 " has to be included in state set of "<< rGen.Name() << ".";
00769 throw Exception("SelfLoop()", errstr.str(), 100);
00770 }
00771 #endif
00772
00773
00774 rGen.InjectAlphabet(rGen.Alphabet()+rAlphabet);
00775
00776
00777 EventSet::Iterator evit,evbegin,evend;
00778 evbegin = rAlphabet.Begin();
00779 evend = rAlphabet.End();
00780 StateSet::Iterator sit;
00781
00782
00783 for (sit = rStates.Begin(); sit != rStates.End(); ++sit) {
00784 for(evit = evbegin; evit != evend; ++evit){
00785 rGen.SetTransition(*sit, *evit, *sit);
00786 }
00787 }
00788
00789
00790 rGen.Name(name);
00791 }
00792
00793 }
00794
00795 #undef Move //see define above for comment
00796 #undef Product //see define above for comment