00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "supcon.h"
00024
00025
00026 namespace faudes {
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 bool IsControllableUnchecked(
00043 const vGenerator& rPlantGen,
00044 const EventSet& rCAlph,
00045 const vGenerator& rSupCandGen,
00046 StateSet& rCriticalStates)
00047 {
00048 FD_DF("IsControllableUnchecked(" << &rSupCandGen << "," << &rPlantGen << ")");
00049
00050
00051
00052
00053 std::stack<Idx> todog, todoh;
00054
00055 StateSet processed;
00056
00057 TransSetX2EvX1 rtransrel;
00058
00059
00060 rCriticalStates.Clear();
00061
00062
00063
00064
00065 if (rPlantGen.InitStatesEmpty() || rSupCandGen.InitStatesEmpty()) {
00066 return false;
00067 }
00068
00069
00070 todog.push(*rPlantGen.InitStatesBegin());
00071 todoh.push(*rSupCandGen.InitStatesBegin());
00072 FD_DF("IsControllable: todo push: (" << rPlantGen.SStr(*rPlantGen.InitStatesBegin()) << "|"
00073 << rSupCandGen.SStr(*rSupCandGen.InitStatesBegin()) << ")");
00074
00075
00076 while (! todog.empty()) {
00077
00078 Idx currentg = todog.top();
00079 Idx currenth = todoh.top();
00080 todog.pop();
00081 todoh.pop();
00082 FD_DF("IsControllable: todo pop: (" << rPlantGen.SStr(currentg) << "|"
00083 << rSupCandGen.SStr(currenth) << ")");
00084
00085 #ifdef FAUDES_DEBUG_FUNCTION
00086 TransSet::Iterator _titg, _tith;
00087
00088 FD_DF("IsControllable: transitions from current states:");
00089 for (_titg = rPlantGen.TransRelBegin(currentg); _titg != rPlantGen.TransRelEnd(currentg); ++_titg)
00090 FD_DF("IsControllable: g: " << rPlantGen.SStr(_titg->X1) << "-"
00091 << rPlantGen.EStr(_titg->Ev) << "-" << rPlantGen.SStr(_titg->X2));
00092 for (_tith = rSupCandGen.TransRelBegin(currenth); _tith != rSupCandGen.TransRelEnd(currenth); ++_tith)
00093 FD_DF("IsControllable: h: " << rSupCandGen.SStr(_tith->X1) << "-"
00094 << rSupCandGen.EStr(_tith->Ev) << "-" << rSupCandGen.SStr(_tith->X2));
00095 #endif
00096
00097
00098 TransSet::Iterator titg = rPlantGen.TransRelBegin(currentg);
00099 TransSet::Iterator titg_end = rPlantGen.TransRelEnd(currentg);
00100 TransSet::Iterator tith = rSupCandGen.TransRelBegin(currenth);
00101 TransSet::Iterator tith_end = rSupCandGen.TransRelEnd(currenth);
00102 while ((tith != tith_end) && (titg != titg_end)) {
00103 FD_DF("IsControllable: processing g-transition: " << rPlantGen.SStr(titg->X1)
00104 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2));
00105 FD_DF("IsControllable: processing h-transition: " << rSupCandGen.SStr(tith->X1)
00106 << "-" << rSupCandGen.EStr(tith->Ev) << "-" << rSupCandGen.SStr(tith->X2));
00107
00108 if (titg->Ev == tith->Ev) {
00109 FD_DF("IsControllable: processing common event " << rPlantGen.EStr(titg->Ev));
00110
00111 if (! processed.Exists(currenth)) {
00112 todog.push(titg->X2);
00113 todoh.push(tith->X2);
00114 FD_DF("IsControllable: todo push: (" << rPlantGen.SStr(titg->X2) << "|"
00115 << rSupCandGen.SStr(tith->X2) << ")");
00116 }
00117
00118 if (! rCriticalStates.Exists(tith->X2)) {
00119 rtransrel.Insert(*tith);
00120 FD_DF("IsControllable: incrementing g and h transrel");
00121 ++titg;
00122 ++tith;
00123 }
00124
00125 else if (!rCAlph.Exists(titg->Ev)) {
00126 FD_DF("IsControllable: successor state " << rSupCandGen.SStr(tith->X2) <<
00127 " critical and event " << rPlantGen.EStr(titg->Ev) << " uncontrollable:");
00128 FD_DF("IsControllable: TraverseUncontrollableBackwards(" << rSupCandGen.SStr(currenth) << ")");
00129 TraverseUncontrollableBackwards(rCAlph, rtransrel, rCriticalStates, currenth);
00130 #ifdef FAUDES_CHECKED
00131
00132 FD_DF("IsControllable: incrementing g an h transrel (FAUDES_CHECKED)");
00133 ++titg;
00134 ++tith;
00135 break;
00136 #else
00137
00138 titg = titg_end;
00139 tith = tith_end;
00140 break;
00141 #endif
00142 }
00143
00144 else {
00145 FD_DF("IsControllable: incrementing g and h transrel");
00146 ++titg;
00147 ++tith;
00148 }
00149 }
00150
00151 else if (titg->Ev < tith->Ev) {
00152 FD_DF("IsControllable: asynchronous execution of event "
00153 << rPlantGen.EStr(titg->Ev) << " in g while " << rSupCandGen.EStr(tith->Ev)
00154 << " in h");
00155
00156
00157 if (!rCAlph.Exists(titg->Ev)) {
00158 FD_DF("IsControllable: asynchronous event " << rPlantGen.EStr(titg->Ev)
00159 << " in g is uncontrollable");
00160 FD_DF("IsControllable: TraverseUncontrollableBackwards(" << rSupCandGen.SStr(currenth) << ")");
00161 TraverseUncontrollableBackwards(rCAlph, rtransrel, rCriticalStates, currenth);
00162
00163 titg = titg_end;
00164 break;
00165 }
00166 FD_DF("IsControllable: incrementing g transrel");
00167 ++titg;
00168 }
00169
00170 else {
00171
00172
00173
00174
00175 FD_DF("IsControllable: incrementing h transrel");
00176 ++tith;
00177 }
00178 }
00179
00180 while (titg != titg_end) {
00181 FD_DF("IsControllable: asynchronous execution of event "
00182 << rPlantGen.EStr(titg->Ev) << " in g at end of h");
00183 FD_DF("IsControllable: actual g-transition: " << rPlantGen.SStr(titg->X1)
00184 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2));
00185 FD_DF("IsControllable: actual h-transition: end");
00186
00187 if (!rCAlph.Exists(titg->Ev)) {
00188 FD_DF("IsControllable: asynchronous execution of uncontrollable event "
00189 << rPlantGen.EStr(titg->Ev) << " in g");
00190 FD_DF("IsControllable: TraverseUncontrollableBackwards(" << rPlantGen.SStr(currenth) << ")");
00191 TraverseUncontrollableBackwards(rCAlph, rtransrel, rCriticalStates, currenth);
00192
00193 break;
00194 }
00195 FD_DF("IsControllable: incrementing g transrel");
00196 ++titg;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 processed.Insert(currenth);
00207 }
00208
00209
00210 rCriticalStates = rSupCandGen.States() - ( processed - rCriticalStates );
00211
00212 if (rCriticalStates.Empty()) {
00213 FD_DF("IsControllable: controllable");
00214 return true;
00215 }
00216 FD_DF("IsControllable: not controllable");
00217 return false;
00218 }
00219
00220
00221
00222
00223
00224 bool SupConUnchecked(
00225 const vGenerator& rPlantGen,
00226 const EventSet& rCAlph,
00227 vGenerator& rSupCandGen)
00228 {
00229 FD_DF("SupConUnchecked...");
00230
00231
00232
00233
00234 StateSet critical;
00235
00236
00237
00238
00239 if (rPlantGen.InitStatesEmpty() || rSupCandGen.InitStatesEmpty()) {
00240 return true;
00241 }
00242
00243
00244 IsControllable(rPlantGen, rCAlph, rSupCandGen, critical);
00245 FD_DF("SupCon: delete critical states: " << rSupCandGen.States().ToString());
00246 StateSet::Iterator sit;
00247 for(sit = critical.Begin(); sit != critical.End(); ++sit){
00248 rSupCandGen.DelState(*sit);
00249 }
00250
00251
00252 if (critical.Empty()) {
00253 FD_DF("SupCon: controllable");
00254 return true;
00255 }
00256
00257 FD_DF("SupCon: not controllable");
00258 return false;
00259 }
00260
00261
00262
00263 void SupconParallel(
00264 const vGenerator& rPlantGen,
00265 const EventSet& rCAlph,
00266 const vGenerator& rSpecGen,
00267 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00268 vGenerator& rResGen)
00269 {
00270 FD_DF("SupconParallel(" << &rPlantGen << "," << &rSpecGen << ")");
00271
00272
00273
00274
00275 std::stack< std::pair<Idx,Idx> > todo;
00276
00277 StateSet critical;
00278
00279 std::pair<Idx,Idx> currentstates, newstates;
00280
00281 Idx tmpstate;
00282 std::map< std::pair<Idx,Idx>, Idx>::iterator rcmapit;
00283 StateSet::Iterator lit1, lit2;
00284 TransSet::Iterator titg, titg_end, tith, tith_end;
00285
00286
00287
00288 if (rPlantGen.InitStatesEmpty()) {
00289 FD_DF("SupconParallel: plant got no initial states. "
00290 << "parallel composition contains empty language.");
00291 return;
00292 }
00293 if (rSpecGen.InitStatesEmpty()) {
00294 FD_DF("SupconParallel: spec got no initial states. "
00295 << "parallel composition contains empty language.");
00296 return;
00297 }
00298
00299
00300 currentstates = std::make_pair(*rPlantGen.InitStatesBegin(), *rSpecGen.InitStatesBegin());
00301 todo.push(currentstates);
00302 rReverseCompositionMap[currentstates] = rResGen.InsInitState();
00303 FD_DF("SupconParallel: NEW ISTATE: (" << rPlantGen.SStr(currentstates.first)
00304 << "|" << rSpecGen.SStr(currentstates.second) << ") -> "
00305 << rReverseCompositionMap[currentstates]);
00306 if (rPlantGen.ExistsMarkedState(*rPlantGen.InitStatesBegin())
00307 && rSpecGen.ExistsMarkedState(*rSpecGen.InitStatesBegin())) {
00308 rResGen.SetMarkedState(rReverseCompositionMap[currentstates]);
00309 FD_DF("SupconParallel: recent ISTATE Marked");
00310 }
00311
00312
00313
00314 FD_DF("SupconParallel: *** processing reachable states ***");
00315 while (! todo.empty()) {
00316
00317 currentstates = todo.top();
00318 todo.pop();
00319 FD_DF("SupconParallel: todo pop: (" << rPlantGen.SStr(currentstates.first)
00320 << "|" << rSpecGen.SStr(currentstates.second) << ") -> "
00321 << rReverseCompositionMap[currentstates]);
00322
00323 titg = rPlantGen.TransRelBegin(currentstates.first);
00324 titg_end = rPlantGen.TransRelEnd(currentstates.first);
00325 tith = rSpecGen.TransRelBegin(currentstates.second);
00326 tith_end = rSpecGen.TransRelEnd(currentstates.second);
00327
00328 #ifdef FAUDES_DEBUG_FUNCTION
00329
00330 FD_DF("SupConParallel: transitions from current states:");
00331 for (;titg != titg_end; ++titg) {
00332 FD_DF("SupConParallel: g: " << rPlantGen.SStr(titg->X1) << "-" << rPlantGen.EStr(titg->Ev)
00333 << "-" << rPlantGen.SStr(titg->X2));
00334 }
00335 for (;tith != tith_end; ++tith) {
00336 FD_DF("SupConParallel: h: " << rSpecGen.SStr(tith->X1) << "-" << rSpecGen.EStr(tith->Ev)
00337 << "-" << rSpecGen.SStr(tith->X2));
00338 }
00339 titg = rPlantGen.TransRelBegin(currentstates.first);
00340 tith = rSpecGen.TransRelBegin(currentstates.second);
00341 #endif
00342
00343
00344 while ((tith != tith_end) && (titg != titg_end)) {
00345 FD_DF("SupconParallel: current g-transition: " << rPlantGen.TStr(*titg) );
00346 FD_DF("SupconParallel: actual h-transition: " << rSpecGen.TStr(*tith));
00347
00348 if (titg->Ev == tith->Ev) {
00349 FD_DF("SupconParallel: executing common event " << rPlantGen.EStr(titg->Ev));
00350 newstates = std::make_pair(titg->X2, tith->X2);
00351 rcmapit = rReverseCompositionMap.find(newstates);
00352
00353 if (rcmapit == rReverseCompositionMap.end()) {
00354 todo.push(newstates);
00355
00356 if (rPlantGen.ExistsMarkedState(newstates.first) &&
00357 rSpecGen.ExistsMarkedState(newstates.second)) {
00358 tmpstate = rResGen.InsMarkedState();
00359 FD_DF("SupconParallel: NEW MSTATE: (" << rPlantGen.SStr(newstates.first) << "|"
00360 << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate);
00361 }
00362
00363 else {
00364 tmpstate = rResGen.InsState();
00365 FD_DF("SupconParallel: NEW STATE: (" << rPlantGen.SStr(newstates.first) << "|"
00366 << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate);
00367 }
00368 rReverseCompositionMap[newstates] = tmpstate;
00369 FD_DF("SupconParallel: todo push: (" << rPlantGen.SStr(newstates.first)
00370 << "|" << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate);
00371 }
00372
00373 else {
00374 tmpstate = rcmapit->second;
00375 }
00376
00377 if (! critical.Exists(tmpstate)) {
00378 FD_DF("SupconParallel: ADDING TRANSITION "
00379 << rPlantGen.SStr(rReverseCompositionMap[currentstates]) << "-" << rPlantGen.EStr(titg->Ev)
00380 << "-" << rPlantGen.SStr(tmpstate));
00381 rResGen.SetTransition(rReverseCompositionMap[currentstates], titg->Ev, tmpstate);
00382 FD_DF("SupconParallel: incrementing g and h transrel");
00383 ++titg;
00384 ++tith;
00385 }
00386
00387 else if (!rCAlph.Exists(titg->Ev)) {
00388 FD_DF("SupconParallel: successor " << rSpecGen.SStr(tmpstate)
00389 << "in critical and common event " << rSpecGen.EStr(titg->Ev)
00390 << " uncontrollable:");
00391 FD_DF("SupconParallel: critical insert" << rPlantGen.SStr(tmpstate));
00392 critical.Insert(tmpstate);
00393 #ifdef FAUDES_CHECKED
00394
00395
00396 FD_DF("SupconParallel: incrementing g and h transrel (FAUDES_CHECKED)");
00397 ++titg;
00398 ++tith;
00399 #else
00400
00401 titg = titg_end;
00402 tith = tith_end;
00403 #endif
00404 }
00405
00406 else {
00407 FD_DF("SupconParallel: incrementing g and h transrel");
00408 ++titg;
00409 ++tith;
00410 }
00411 }
00412
00413 else if (titg->Ev < tith->Ev) {
00414 FD_DF("SupconParallel: asynchronous execution of event "
00415 << rPlantGen.EStr(titg->Ev) << " in g while " << rSpecGen.EStr(tith->Ev) << " in h");
00416
00417
00418 if (!rCAlph.Exists(titg->Ev)) {
00419 FD_DF("SupconParallel: asynchronous event " << rPlantGen.EStr(titg->Ev)
00420 << " in g is uncontrollable");
00421 tmpstate = rReverseCompositionMap[currentstates];
00422 FD_DF("SupconParallel: critical insert" << rPlantGen.SStr(tmpstate));
00423 critical.Insert(tmpstate);
00424
00425 titg = titg_end;
00426 tith = tith_end;
00427 break;
00428 }
00429 FD_DF("SupconParallel: incrementing g transrel");
00430 ++titg;
00431 }
00432
00433 else {
00434
00435
00436
00437 FD_DF("SupconParallel: incrementing h transrel");
00438 ++tith;
00439 }
00440 }
00441
00442 while (titg != titg_end) {
00443 FD_DF("SupconParallel: asynchronous execution of event "
00444 << rPlantGen.EStr(titg->Ev) << " in g at end of h");
00445 FD_DF("SupconParallel: actual g-transition: " << rPlantGen.SStr(titg->X1)
00446 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2));
00447 FD_DF("SupconParallel: actual h-transition: end");
00448
00449 if (!rCAlph.Exists(titg->Ev)) {
00450 tmpstate = rReverseCompositionMap[currentstates];
00451 FD_DF("SupconParallel: asynchron executed uncontrollable end "
00452 << "event " << rPlantGen.EStr(titg->Ev) << " leaves specification:");
00453 FD_DF("SupconParallel: critical insert" << rPlantGen.SStr(tmpstate));
00454 critical.Insert(tmpstate);
00455
00456 break;
00457 }
00458 FD_DF("SupconParallel: incrementing g transrel");
00459 ++titg;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469 }
00470 FD_DF("SupconParallel: deleting critical states...");
00471 StateSet::Iterator sit;
00472 for(sit = critical.Begin(); sit!= critical.End(); ++sit)
00473 rResGen.DelState(*sit);
00474
00475 }
00476
00477
00478
00479
00480 void SupConNBUnchecked(
00481 const vGenerator& rPlantGen,
00482 const EventSet& rCAlph,
00483 const vGenerator& rSpecGen,
00484 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00485 vGenerator& rResGen)
00486 {
00487 FD_DF("SupConNB(" << &rPlantGen << "," << &rSpecGen << ")");
00488
00489
00490 vGenerator* pResGen = &rResGen;
00491 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00492 pResGen= rResGen.NewP();
00493 }
00494 pResGen->Clear();
00495 pResGen->Name(CollapsString("SupConNB(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"));
00496 pResGen->InjectAlphabet(rPlantGen.Alphabet());
00497
00498
00499 FD_DF("SupConNB: controllable events: " << rCAlph.ToString());
00500
00501
00502 SupconParallel(rPlantGen, rCAlph, rSpecGen, rReverseCompositionMap, *pResGen);
00503
00504
00505 while (1) {
00506 if (pResGen->Empty()) {
00507 break;
00508 }
00509 Idx state_num = pResGen->Size();
00510 bool supcon = SupConUnchecked(rPlantGen, rCAlph, *pResGen);
00511 bool trim = pResGen->Trim();
00512 if (supcon && trim && (pResGen->Size() == state_num)) {
00513 break;
00514 }
00515 }
00516
00517
00518 if (rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && rResGen.StateNamesEnabled())
00519 SetComposedStateNames(rPlantGen, rSpecGen, rReverseCompositionMap, *pResGen);
00520 else
00521 pResGen->ClearStateNames();
00522
00523
00524 if(pResGen != &rResGen) {
00525 rResGen = *pResGen;
00526 delete pResGen;
00527 }
00528
00529 }
00530
00531
00532 void ControlProblemConsistencyCheck(
00533 const vGenerator& rPlantGen,
00534 const EventSet& rCAlph,
00535 const vGenerator& rSpecGen)
00536 {
00537
00538
00539 if ( rPlantGen.Alphabet() != rSpecGen.Alphabet()) {
00540 EventSet only_in_plant = rPlantGen.Alphabet() - rSpecGen.Alphabet();
00541 EventSet only_in_spec = rSpecGen.Alphabet() - rPlantGen.Alphabet();
00542 std::stringstream errstr;
00543 errstr << "Alphabets of generators do not match. Only in plant: "
00544 << only_in_plant.ToString() << ". Only in spec: "
00545 << only_in_spec.ToString() << ".";
00546 throw Exception("SupConNB", errstr.str(), 100);
00547 }
00548
00549
00550
00551
00552
00553
00554 bool plant_det = rPlantGen.IsDeterministic();
00555 bool spec_det = rSpecGen.IsDeterministic();
00556
00557 if ((plant_det == false) && (spec_det == true)) {
00558 std::stringstream errstr;
00559 errstr << "Plant generator must be deterministic, "
00560 << "but is nondeterministic";
00561 throw Exception("ControllableConsistencyCheck", errstr.str(), 201);
00562 }
00563 else if ((plant_det == true) && (spec_det == false)) {
00564 std::stringstream errstr;
00565 errstr << "Spec generator must be deterministic, "
00566 << "but is nondeterministic";
00567 throw Exception("ControllableConsistencyCheck", errstr.str(), 203);
00568 }
00569 else if ((plant_det == false) && (spec_det == false)) {
00570 std::stringstream errstr;
00571 errstr << "Plant and spec generator must be deterministic, "
00572 << "but both are nondeterministic";
00573 throw Exception("ControllableConsistencyCheck", errstr.str(), 204);
00574 }
00575 }
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 bool IsControllable(
00587 const vGenerator& rPlantGen,
00588 const EventSet& rCAlph,
00589 const vGenerator& rSupCandGen)
00590 {
00591 FD_DF("IsControllable(" << &rSupCandGen << "," << &rPlantGen << ")");
00592
00593
00594 FD_DF("IsControllable: controllable events: " << rCAlph.ToString());
00595
00596 StateSet critical;
00597
00598
00599 ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSupCandGen);
00600
00601
00602 return IsControllableUnchecked(rPlantGen, rCAlph, rSupCandGen, critical);
00603 }
00604
00605
00606
00607 bool IsControllable(
00608 const vGenerator& rPlantGen,
00609 const EventSet& rCAlph,
00610 const vGenerator& rSupCandGen,
00611 StateSet& rCriticalStates)
00612 {
00613 FD_DF("IsControllable(" << &rSupCandGen << "," << &rPlantGen << ")");
00614
00615
00616 ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSupCandGen);
00617
00618
00619 return IsControllableUnchecked(rPlantGen, rCAlph, rSupCandGen, rCriticalStates);
00620 }
00621
00622
00623
00624
00625 void SupConNB(
00626 const vGenerator& rPlantGen,
00627 const EventSet& rCAlph,
00628 const vGenerator& rSpecGen,
00629 vGenerator& rResGen)
00630 {
00631
00632
00633 ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSpecGen);
00634
00635
00636 std::map< std::pair<Idx,Idx>, Idx> rcmap;
00637
00638
00639 SupConNBUnchecked(rPlantGen, rCAlph, rSpecGen, rcmap, rResGen);
00640 }
00641
00642
00643
00644
00645
00646
00647 void SupConNBNonDet(
00648 const vGenerator& rPlantGen,
00649 const EventSet& rCAlph,
00650 const vGenerator& rSpecGen,
00651 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00652 Generator rDetPlantGen,
00653 Generator rDetSpecGen,
00654 std::map<Idx,StateSet>& rPowerStatesPlant,
00655 std::map<Idx,StateSet>& rPowerStatesSpec,
00656 bool& rDetPlantBool,
00657 bool& rDetSpecBool,
00658 vGenerator& rResGen)
00659 {
00660 FD_DF("SupConNBNonDet(" << &rPlantGen << "," << &rSpecGen << ")");
00661
00662
00663 if (rPlantGen.Alphabet() != rSpecGen.Alphabet()) {
00664 throw Exception("SupConNBNonDet", "Alphabets of generators don't match", 100);
00665 }
00666
00667
00668 vGenerator* pResGen = &rResGen;
00669 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00670 pResGen= rResGen.NewP();
00671 }
00672 pResGen->Clear();
00673 pResGen->Name(CollapsString("SupConNBNonDet(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"));
00674 pResGen->InjectAlphabet(rPlantGen.Alphabet());
00675
00676
00677 rPowerStatesPlant.clear();
00678 rPowerStatesSpec.clear();
00679
00680
00681 FD_DF("SupConNB: controllable events: " << rCAlph.ToString());
00682
00683
00684 vGenerator* plantp;
00685 vGenerator* specp;
00686
00687
00688 rDetPlantBool = rPlantGen.IsDeterministic();
00689 rDetSpecBool = rSpecGen.IsDeterministic();
00690
00691
00692 plantp = const_cast<vGenerator*>(&rPlantGen);
00693 specp = const_cast<vGenerator*>(&rSpecGen);
00694 if (rDetPlantBool == false) {
00695 Deterministic(rPlantGen, rPowerStatesPlant, rDetPlantGen);
00696 plantp = &rDetPlantGen;
00697 }
00698 if (rDetSpecBool == false) {
00699 Deterministic(rSpecGen, rPowerStatesSpec, rDetSpecGen);
00700 specp = &rDetSpecGen;
00701 }
00702
00703
00704
00705
00706 SupconParallel(*plantp, rCAlph, *specp, rReverseCompositionMap, *pResGen);
00707
00708
00709 while (! (SupConUnchecked(*plantp, rCAlph, *pResGen) && pResGen->Trim()));
00710
00711
00712 if(pResGen != &rResGen) {
00713 rResGen = *pResGen;
00714 delete pResGen;
00715 }
00716 }
00717
00718
00719 void SupCon(
00720 const vGenerator& rPlantGen,
00721 const EventSet& rCAlph,
00722 const vGenerator& rSpecGen,
00723 vGenerator& rResGen)
00724 {
00725
00726 std::map< std::pair<Idx,Idx>, Idx> rcmap;
00727
00728
00729 SupCon(rPlantGen, rCAlph, rSpecGen, rcmap, rResGen);
00730 }
00731
00732
00733
00734 void SupCon(
00735 const vGenerator& rPlantGen,
00736 const EventSet& rCAlph,
00737 const vGenerator& rSpecGen,
00738 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00739 vGenerator& rResGen)
00740 {
00741 FD_DF("SupCon(" << &rPlantGen << "," << &rSpecGen << ")");
00742
00743
00744
00745
00746
00747 vGenerator* pResGen = &rResGen;
00748 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00749 pResGen= rResGen.NewP();
00750 }
00751 pResGen->Clear();
00752 pResGen->Name(CollapsString("SupCon(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"));
00753 pResGen->InjectAlphabet(rPlantGen.Alphabet());
00754
00755
00756 FD_DF("SupCon: controllable events: " << rCAlph.ToString());
00757
00758
00759 ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSpecGen);
00760
00761
00762
00763
00764 SupconParallel(rPlantGen, rCAlph, rSpecGen, rReverseCompositionMap, *pResGen);
00765
00766 SupConUnchecked(rPlantGen, rCAlph, *pResGen);
00767
00768
00769 if(pResGen != &rResGen) {
00770 rResGen = *pResGen;
00771 delete pResGen;
00772 }
00773 }
00774
00775
00776
00777 void TraverseUncontrollableBackwards(
00778 const EventSet& rCAlph,
00779 TransSetX2EvX1& rtransrel,
00780 StateSet& rCriticalStates,
00781 Idx current) {
00782 FD_DF("TraverseUncontrollableBackwards: " << rCriticalStates.Str(current));
00783
00784
00785 std::stack<Idx> todo;
00786 TransSetX2EvX1::Iterator rtit = rtransrel.BeginByX2(current);
00787 TransSetX2EvX1::Iterator rtit_end = rtransrel.EndByX2(current);
00788
00789
00790 rCriticalStates.Insert(current);
00791 todo.push(current);
00792 FD_DF("TraverseUncontrollableBackwards: current rCriticalStates set: "
00793 << rCriticalStates.ToString());
00794
00795 while (! todo.empty()) {
00796
00797 current = todo.top(); todo.pop();
00798
00799 rtit_end = rtransrel.EndByX2(current);
00800 rtit = rtransrel.BeginByX2(current);
00801 for (; rtit != rtit_end; ++rtit) {
00802
00803 if ((!rCAlph.Exists(rtit->Ev)) && (! rCriticalStates.Exists(rtit->X1))) {
00804 FD_DF("TraverseUncontrollableBackwards: todo push " << rCriticalStates.Str(rtit->X1));
00805 todo.push(rtit->X1);
00806 FD_DF("TraverseUncontrollableBackwards: critical insert: " << rCriticalStates.Str(rtit->X1));
00807 rCriticalStates.Insert(rtit->X1);
00808 }
00809 }
00810 }
00811 }
00812
00813 }