libFAUDES
Sections
Index
|
mtc_supcon.cppGo to the documentation of this file.00001 /** @file mtc_supcon.cpp 00002 00003 Supremal controllable sublanguage and controllablity 00004 00005 */ 00006 00007 /* FAU Discrete Event Systems Library (libfaudes) 00008 00009 Copyright (C) 2008 Matthias Singer 00010 Copyright (C) 2006 Bernd Opitz 00011 Exclusive copyright is granted to Klaus Schmidt 00012 00013 This library is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU Lesser General Public 00015 License as published by the Free Software Foundation; either 00016 version 2.1 of the License, or (at your option) any later version. 00017 00018 This library is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 Lesser General Public License for more details. 00022 00023 You should have received a copy of the GNU Lesser General Public 00024 License along with this library; if not, write to the Free Software 00025 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00026 00027 00028 #include "mtc_supcon.h" 00029 #include "syn_include.h" 00030 00031 namespace faudes { 00032 00033 /* 00034 ****************************** 00035 * SUPCON: USER FUNCTIONS * 00036 ****************************** 00037 */ 00038 00039 00040 // mtcSupConNB(rPlantGen, rSpecGen, rResGen) 00041 void mtcSupConNB(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, MtcSystem& rResGen) { 00042 // HELPERS: 00043 std::map< std::pair<Idx,Idx>, Idx> rcmap; 00044 // ALGORITHM: 00045 mtcSupConNB(rPlantGen, rSpecGen, rcmap, rResGen); 00046 } 00047 00048 00049 // mtcSupConNB(rPlantGen, rSpecGen, rReverseCompositionMap, rResGen) 00050 void mtcSupConNB(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, 00051 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, MtcSystem& rResGen) { 00052 FD_DF("mtcSupConNB(" << &rPlantGen << "," << &rSpecGen << ")"); 00053 00054 // PREPARE RESULT: 00055 00056 rResGen.Clear(); 00057 rResGen.Name("mtcSupConNB(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"); 00058 rResGen.InjectAlphabet(rPlantGen.Alphabet()); 00059 00060 rResGen.SetControllable(rPlantGen.ControllableEvents()); 00061 rResGen.SetForcible(rPlantGen.ForcibleEvents()); 00062 rResGen.ClrObservable(rPlantGen.UnobservableEvents()); 00063 00064 // HELPERS: 00065 00066 // controllable events 00067 const EventSet ualph = rPlantGen.UncontrollableEvents(); 00068 FD_DF("mtcSupConNB: controllable events: " << rPlantGen.ControllableEvents().ToString()); 00069 FD_DF("mtcSupConNB: uncontrollable events: " << ualph.ToString()); 00070 00071 // CONSISTENCY CHECK: 00072 00073 // alphabets must match 00074 if (rPlantGen.Alphabet() != rSpecGen.Alphabet()) { 00075 EventSet only_in_plant = rPlantGen.Alphabet() - rSpecGen.Alphabet(); 00076 EventSet only_in_spec = rSpecGen.Alphabet() - rPlantGen.Alphabet(); 00077 std::stringstream errstr; 00078 errstr << "Alphabets of generators do not match. Only in plant: " << only_in_plant.ToString() 00079 << ". Only in spec: " << only_in_spec.ToString() << "."; 00080 throw Exception("mtcSupConNB", errstr.str(), 500); 00081 } 00082 00083 // plant and spec must be deterministic 00084 bool plant_det = rPlantGen.IsDeterministic(); 00085 bool spec_det = rSpecGen.IsDeterministic(); 00086 00087 if ((plant_det == false) && (spec_det == true)) { 00088 std::stringstream errstr; 00089 errstr << "Plant generator must be deterministic, " 00090 << "but is nondeterministic"; 00091 throw Exception("mtcSupConNB", errstr.str(), 501); 00092 } 00093 else if ((plant_det == true) && (spec_det == false)) { 00094 std::stringstream errstr; 00095 errstr << "Spec generator must be deterministic, " 00096 << "but is nondeterministic"; 00097 throw Exception("mtcSupConNB", errstr.str(), 503); 00098 } 00099 else if ((plant_det == false) && (spec_det == false)) { 00100 std::stringstream errstr; 00101 errstr << "Plant and spec generator must be deterministic, " 00102 << "but both are nondeterministic"; 00103 throw Exception("mtcSupConNB", errstr.str(), 504); 00104 } 00105 00106 // ALGORITHM: 00107 00108 mtcSupConParallel(rPlantGen, rSpecGen, ualph, rReverseCompositionMap, rResGen); 00109 FD_DF("mtcSupConNB: mtcSupConParallel passed..."); 00110 00111 // make resulting generator trim until it's fully controllable 00112 while (1) { 00113 if(rResGen.Empty()) break; 00114 Idx state_num = rResGen.Size(); 00115 mtcSupConUnchecked(rPlantGen, rPlantGen.ControllableEvents(), rResGen); 00116 rResGen.StronglyTrim(); 00117 if(rResGen.Size() == state_num) break; 00118 FD_DF("mtcSupConNB: rResGen.Size() = " << ToStringInteger(rResGen.Size()) << ", state_num = " << ToStringInteger(state_num)); 00119 } 00120 } 00121 00122 // mtcSupCon(rPlantGen, rSpecGen, rResGen) 00123 void mtcSupCon(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, MtcSystem& rResGen) { 00124 // HELPERS: 00125 std::map< std::pair<Idx,Idx>, Idx> rcmap; 00126 00127 // ALGORITHM: 00128 mtcSupCon(rPlantGen, rSpecGen, rcmap, rResGen); 00129 } 00130 00131 00132 // mtcSupCon(rPlantGen, rSpecGen, rReverseCompositionMap, rResGen) 00133 void mtcSupCon(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, 00134 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, MtcSystem& rResGen) { 00135 FD_DF("mtcSupCon(" << &rPlantGen << "," << &rSpecGen << ")"); 00136 00137 // PREPARE RESULT: 00138 rResGen.Clear(); 00139 rResGen.Name("mtcSupCon(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"); 00140 00141 rResGen.InjectAlphabet(rPlantGen.Alphabet()); 00142 00143 rResGen.SetControllable(rPlantGen.ControllableEvents()); 00144 rResGen.SetForcible(rPlantGen.ForcibleEvents()); 00145 rResGen.ClrObservable(rPlantGen.UnobservableEvents()); 00146 00147 // HELPERS: 00148 00149 // controllable events 00150 const EventSet ualph = rPlantGen.UncontrollableEvents(); 00151 FD_DF("mtcSupCon: controllable events: " << rPlantGen.ControllableEvents().ToString()); 00152 FD_DF("mtcSupCon: uncontrollable events: " << ualph.ToString()); 00153 00154 // CONSISTENCY CHECK: 00155 00156 // alphabets must match 00157 if (rPlantGen.Alphabet() != rSpecGen.Alphabet()) { 00158 EventSet only_in_plant = rPlantGen.Alphabet() - rSpecGen.Alphabet(); 00159 EventSet only_in_spec = rSpecGen.Alphabet() - rPlantGen.Alphabet(); 00160 std::stringstream errstr; 00161 errstr << "Alphabets of generators do not match. Only in plant: " 00162 << only_in_plant.ToString() << ". Only in spec: " 00163 << only_in_spec.ToString() << "."; 00164 throw Exception("mtcSupCon", errstr.str(), 500); 00165 } 00166 00167 // plant and spec must be deterministic 00168 bool plant_det = rPlantGen.IsDeterministic(); 00169 bool spec_det = rSpecGen.IsDeterministic(); 00170 00171 if ((plant_det == false) && (spec_det == true)) { 00172 std::stringstream errstr; 00173 errstr << "Plant generator must be deterministic, " << "but is nondeterministic"; 00174 throw Exception("mtcSupCon", errstr.str(), 501); 00175 } 00176 else if ((plant_det == true) && (spec_det == false)) { 00177 std::stringstream errstr; 00178 errstr << "Spec generator must be deterministic, " << "but is nondeterministic"; 00179 throw Exception("mtcSupCon", errstr.str(), 503); 00180 } 00181 else if ((plant_det == false) && (spec_det == false)) { 00182 std::stringstream errstr; 00183 errstr << "Plant and spec generator must be deterministic, " 00184 << "but both are nondeterministic"; 00185 throw Exception("mtcSupConNB", errstr.str(), 504); 00186 } 00187 00188 // ALGORITHM: 00189 00190 // parallel composition 00191 mtcSupConParallel(rPlantGen, rSpecGen, ualph, rReverseCompositionMap, rResGen); 00192 // make resulting generator controllable 00193 mtcSupConUnchecked(rPlantGen, rPlantGen.ControllableEvents(), rResGen); 00194 } 00195 00196 00197 00198 /* 00199 ******************************************** 00200 * Fast parallel composition for mtcSupCon * 00201 ******************************************** 00202 */ 00203 00204 00205 // mtcSupConParallel(rPlantGen, rSpecGen, rUAlph, rReverseCompositionMap, rResGen) 00206 void mtcSupConParallel(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, const EventSet& rUAlph, 00207 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, MtcSystem& rResGen) { 00208 FD_DF("mtcSupConParallel(" << &rPlantGen << "," << &rSpecGen << ")"); 00209 00210 // HELPERS: 00211 00212 // todo stack 00213 std::stack< std::pair<Idx,Idx> > todo; 00214 // set of forbidden states 00215 StateSet forbidden; 00216 // actual pair, new pair 00217 std::pair<Idx,Idx> currentstates, newstates; 00218 // other stuff 00219 Idx tmpstate; 00220 std::map< std::pair<Idx,Idx>, Idx>::iterator rcmapit; 00221 StateSet::Iterator lit1, lit2; 00222 TransSet::Iterator titg, titg_end, tith, tith_end; 00223 00224 // Prepare 00225 rResGen.ClearStates(); 00226 00227 // ALGORITHM: 00228 if (rPlantGen.InitStatesEmpty()) { 00229 FD_DF("SupconParallel: plant got no initial states. " 00230 << "parallel composition contains empty language."); 00231 return; 00232 } 00233 00234 if (rSpecGen.InitStatesEmpty()) { 00235 FD_DF("mtcSupConParallel: spec got no initial states. " 00236 << "parallel composition contains empty language."); 00237 return; 00238 } 00239 ColorSet plantColors = rPlantGen.Colors(); 00240 ColorSet specColors = rSpecGen.Colors(); 00241 // create initial state 00242 currentstates = std::make_pair(*rPlantGen.InitStatesBegin(), *rSpecGen.InitStatesBegin()); 00243 todo.push(currentstates); 00244 ColorSet ComposedSet; 00245 ComposedColorSet(rPlantGen, currentstates.first, plantColors, rSpecGen, currentstates.second, 00246 specColors, ComposedSet); 00247 if (! ComposedSet.Empty() ) { 00248 Idx StateIndex = rResGen.InsInitState(); 00249 rReverseCompositionMap[currentstates] = StateIndex; 00250 rResGen.InsColors(StateIndex, ComposedSet); 00251 FD_DF("mtcSupConParallel: NEW IMSTATE: (" << rPlantGen.SStr(currentstates.first) 00252 << "|" << rSpecGen.SStr(currentstates.second) << ") -> " << rReverseCompositionMap[currentstates]); 00253 } 00254 else { 00255 rReverseCompositionMap[currentstates] = rResGen.InsInitState(); 00256 FD_DF("mtcSupConParallel: NEW ISTATE: (" << rPlantGen.SStr(currentstates.first) 00257 << "|" << rSpecGen.SStr(currentstates.second) << ") -> " << rReverseCompositionMap[currentstates]); 00258 } 00259 00260 // first do parallel composition of allowed states 00261 // by deleting forbidden states on the fly. 00262 // this creates an accessible new generator 00263 FD_DF("mtcSupConParallel: *** processing reachable states ***"); 00264 while (! todo.empty()) { 00265 // get next reachable pair of states from todo stack 00266 currentstates = todo.top(); 00267 todo.pop(); 00268 FD_DF("mtcSupConParallel: todo pop: (" << rPlantGen.SStr(currentstates.first) 00269 << "|" << rSpecGen.SStr(currentstates.second) << ") -> " << rReverseCompositionMap[currentstates]); 00270 00271 titg = rPlantGen.TransRelBegin(currentstates.first); 00272 titg_end = rPlantGen.TransRelEnd(currentstates.first); 00273 tith = rSpecGen.TransRelBegin(currentstates.second); 00274 tith_end = rSpecGen.TransRelEnd(currentstates.second); 00275 00276 #ifdef FAUDES_DEBUG_FUNCTION 00277 // print all transitions of current states 00278 FD_DF("mtcSupConParallel: transitions from current states:"); 00279 for (;titg != titg_end; ++titg) { 00280 FD_DF("mtcSupConParallel: g: " << rPlantGen.SStr(titg->X1) << "-" << rPlantGen.EStr(titg->Ev) 00281 << "-" << rPlantGen.SStr(titg->X2)); 00282 } 00283 for (;tith != tith_end; ++tith) { 00284 FD_DF("mtcSupConParallel: h: " << rSpecGen.SStr(tith->X1) << "-" << rSpecGen.EStr(tith->Ev) 00285 << "-" << rSpecGen.SStr(tith->X2)); 00286 } 00287 titg = rPlantGen.TransRelBegin(currentstates.first); 00288 tith = rSpecGen.TransRelBegin(currentstates.second); 00289 #endif 00290 // process all h transitions while there could be matching g transitions 00291 while ((tith != tith_end) && (titg != titg_end)) { 00292 FD_DF("mtcSupConParallel: actual g-transition: " << rPlantGen.SStr(titg->X1) 00293 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00294 FD_DF("mtcSupConParallel: actual h-transition: " << rSpecGen.SStr(tith->X1) 00295 << "-" << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2)); 00296 // execute common events 00297 if (titg->Ev == tith->Ev) { 00298 FD_DF("mtcSupConParallel: executing common event " 00299 << rPlantGen.EStr(titg->Ev)); 00300 newstates = std::make_pair(titg->X2, tith->X2); 00301 rcmapit = rReverseCompositionMap.find(newstates); 00302 // add to todo list if state is new 00303 if (rcmapit == rReverseCompositionMap.end()) { 00304 todo.push(newstates); 00305 // if colored state 00306 ComposedColorSet(rPlantGen, newstates.first, plantColors, rSpecGen, newstates.second, 00307 specColors, ComposedSet); 00308 if (not ComposedSet.Empty() ) { 00309 tmpstate = rResGen.InsState(); 00310 rResGen.InsColors(tmpstate, ComposedSet); 00311 FD_DF("mtcSupConParallel: NEW MSTATE: (" 00312 << rPlantGen.SStr(newstates.first) << "|" 00313 << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate); 00314 } 00315 // if "normal" state 00316 else { 00317 tmpstate = rResGen.InsState(); 00318 FD_DF("mtcSupConParallel: NEW STATE: (" 00319 << rPlantGen.SStr(newstates.first) << "|" 00320 << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate); 00321 } 00322 rReverseCompositionMap[newstates] = tmpstate; 00323 FD_DF("mtcSupConParallel: todo push: (" << rPlantGen.SStr(newstates.first) 00324 << "|" << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate); 00325 } 00326 // if state already exists 00327 else { 00328 tmpstate = rcmapit->second; 00329 } 00330 // if successor state not in forbidden set add transition 00331 if (! forbidden.Exists(tmpstate)) { 00332 FD_DF("mtcSupConParallel: ADDING TRANSITION " 00333 << rPlantGen.SStr(rReverseCompositionMap[currentstates]) << "-" << rPlantGen.EStr(titg->Ev) 00334 << "-" << rPlantGen.SStr(tmpstate)); 00335 rResGen.SetTransition(rReverseCompositionMap[currentstates], titg->Ev, tmpstate); 00336 FD_DF("mtcSupConParallel: incrementing g transrel"); 00337 ++titg; 00338 FD_DF("mtcSupConParallel: incrementing h transrel"); 00339 ++tith; 00340 } 00341 // if successor state in forbidden and event uncontrollable 00342 // delete state 00343 else if (rUAlph.Exists(titg->Ev)) { 00344 FD_DF("mtcSupConParallel: successor " << rSpecGen.SStr(tmpstate) 00345 << "in forbidden and common event " << rSpecGen.EStr(titg->Ev) 00346 << " uncontrollable:"); 00347 FD_DF("mtcSupConParallel: forbidden insert" << rPlantGen.SStr(tmpstate)); 00348 forbidden.Insert(tmpstate); 00349 #ifdef FAUDES_CHECKED 00350 // do not end while loops here for detecting all h transitions 00351 // not in g 00352 FD_DF("mtcSupConParallel: incrementing g transrel (FAUDES_CHECKED)"); 00353 ++titg; 00354 FD_DF("mtcSupConParallel: incrementing h transrel (FAUDES_CHECKED)"); 00355 ++tith; 00356 #else 00357 // exit all loops 00358 titg = titg_end; 00359 tith = tith_end; 00360 #endif 00361 } 00362 // else if successor state in forbidden and event controllable 00363 else { 00364 FD_DF("mtcSupConParallel: incrementing g transrel"); 00365 ++titg; 00366 FD_DF("mtcSupConParallel: incrementing h transrel"); 00367 ++tith; 00368 } 00369 } 00370 // if g got some more transitions try to resync events 00371 else if (titg->Ev < tith->Ev) { 00372 FD_DF("mtcSupConParallel: asynchronous execution of event " 00373 << rPlantGen.EStr(titg->Ev) << " in g while " << rSpecGen.EStr(tith->Ev) 00374 << " in h"); 00375 // if uncontrollable transition leaves specification 00376 // delete state from res and put into forbiddenset 00377 if (rUAlph.Exists(titg->Ev)) { 00378 FD_DF("mtcSupConParallel: asynchronous event " << rPlantGen.EStr(titg->Ev) 00379 << " in g is uncontrollable"); 00380 tmpstate = rReverseCompositionMap[currentstates]; 00381 FD_DF("mtcSupConParallel: forbidden insert" << rPlantGen.SStr(tmpstate)); 00382 forbidden.Insert(tmpstate); 00383 // exit all loops 00384 titg = titg_end; 00385 tith = tith_end; 00386 break; 00387 } 00388 FD_DF("mtcSupConParallel: incrementing g transrel"); 00389 ++titg; 00390 } // if specification leaves plant model emit warning 00391 else { 00392 #ifdef FAUDES_CHECKED 00393 // FD_WARN("mtcSupConParallel: transition " << rSpecGen.SStr(tith->X1) 00394 // << "-" << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00395 // << " in specification h not found in g"); 00396 #endif 00397 FD_DF("mtcSupConParallel: incrementing h transrel"); 00398 ++tith; 00399 } 00400 } 00401 if (rResGen.InitStates().Empty()) FD_DF("mtcSupConParallel: rResGen has no initial states... (2)"); 00402 00403 // if g got some more transitions not in h 00404 while (titg != titg_end) { 00405 FD_DF("mtcSupConParallel: asynchronous execution of event " 00406 << rPlantGen.EStr(titg->Ev) << " in g at end of h"); 00407 FD_DF("mtcSupConParallel: actual g-transition: " << rPlantGen.SStr(titg->X1) 00408 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00409 FD_DF("mtcSupConParallel: actual h-transition: end"); 00410 // if uncontrollable transition leaves specification 00411 if (rUAlph.Exists(titg->Ev)) { 00412 tmpstate = rReverseCompositionMap[currentstates]; 00413 FD_DF("mtcSupConParallel: asynchron executed uncontrollable end " 00414 << "event " << rPlantGen.EStr(titg->Ev) << " leaves specification:"); 00415 FD_DF("mtcSupConParallel: forbidden insert" << rPlantGen.SStr(tmpstate)); 00416 forbidden.Insert(tmpstate); 00417 // exit this loop 00418 // if FAUDES_CHECKED not defined this means exiting all loops 00419 break; 00420 } 00421 FD_DF("mtcSupConParallel: incrementing g transrel"); 00422 ++titg; 00423 } 00424 #ifdef FAUDES_CHECKED 00425 // if h got some more transitions not in g 00426 // while (tith != tith_end) { 00427 // FD_WARN("mtcSupConParallel: transition " << rSpecGen.SStr(tith->X1) << "-" 00428 // << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00429 // << "in specification h not found in g"); 00430 // FD_DF("mtcSupConParallel: incrementing h transrel"); 00431 // ++tith; 00432 // } 00433 #endif 00434 } 00435 FD_DF("mtcSupConParallel: deleting forbidden states..."); 00436 // remove forbidden states from stateset 00437 rResGen.DelStates(forbidden); 00438 } 00439 00440 /* 00441 ***************************************** 00442 * mtcSupConUnchecked: REAL SUPCON FUNCTION * 00443 ***************************************** 00444 */ 00445 00446 00447 // mtcSupConUnchecked(rPlantGen, rSpecGen, rCAlph) 00448 void mtcSupConUnchecked(const MtcSystem& rPlantGen, const EventSet& rCAlph, MtcSystem& rSpecGen) { 00449 00450 FD_DF("mtcSupConUnchecked(" << &rSpecGen << "," << &rPlantGen << ")"); 00451 00452 // HELPERS: 00453 00454 // forbiden states 00455 StateSet forbidden; 00456 // todo stack 00457 std::stack<Idx> todog, todoh; 00458 // set of already discovered states 00459 StateSet discovered; 00460 // reverse sorted transition relation build on the fly 00461 TransSetX2EvX1 rtransrel; 00462 00463 00464 // ALGORITHM: 00465 00466 // bail out if there is no initial state 00467 if (rPlantGen.InitStatesEmpty() || rSpecGen.InitStatesEmpty()); 00468 00469 // push combined initial state on todo stack 00470 todog.push(*rPlantGen.InitStatesBegin()); 00471 todoh.push(*rSpecGen.InitStatesBegin()); 00472 FD_DF("mtcSupCon: todo push: (" << rPlantGen.SStr(*rPlantGen.InitStatesBegin()) << "|" 00473 << rSpecGen.SStr(*rSpecGen.InitStatesBegin()) << ")"); 00474 00475 // process todo stack 00476 while (! todog.empty()) { 00477 // get top elements from todo stack 00478 Idx currentg = todog.top(); 00479 Idx currenth = todoh.top(); 00480 todog.pop(); 00481 todoh.pop(); 00482 FD_DF("mtcSupCon: todo pop: (" << rPlantGen.SStr(currentg) << "|" 00483 << rSpecGen.SStr(currenth) << ")"); 00484 00485 #ifdef FAUDES_DEBUG_FUNCTION 00486 TransSet::Iterator _titg, _tith; 00487 // print all transitions of current states 00488 FD_DF("mtcSupCon: transitions from current states:"); 00489 for (_titg = rPlantGen.TransRelBegin(currentg); _titg != rPlantGen.TransRelEnd(currentg); ++_titg) 00490 FD_DF("mtcSupCon: g: " << rPlantGen.SStr(_titg->X1) << "-" 00491 << rPlantGen.EStr(_titg->Ev) << "-" << rPlantGen.SStr(_titg->X2)); 00492 for (_tith = rSpecGen.TransRelBegin(currenth); _tith != rSpecGen.TransRelEnd(currenth); ++_tith) 00493 FD_DF("mtcSupCon: h: " << rSpecGen.SStr(_tith->X1) << "-" 00494 << rSpecGen.EStr(_tith->Ev) << "-" << rSpecGen.SStr(_tith->X2)); 00495 #endif 00496 00497 // process all h transitions while there could be matching g transitions 00498 TransSet::Iterator titg = rPlantGen.TransRelBegin(currentg); 00499 TransSet::Iterator titg_end = rPlantGen.TransRelEnd(currentg); 00500 TransSet::Iterator tith = rSpecGen.TransRelBegin(currenth); 00501 TransSet::Iterator tith_end = rSpecGen.TransRelEnd(currenth); 00502 while ((tith != tith_end) && (titg != titg_end)) { 00503 FD_DF("mtcSupCon: actual g-transition: " << rPlantGen.SStr(titg->X1) 00504 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00505 FD_DF("mtcSupCon: actual h-transition: " << rSpecGen.SStr(tith->X1) 00506 << "-" << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2)); 00507 // execute common events 00508 if (titg->Ev == tith->Ev) { 00509 FD_DF("mtcSupCon: executing common event " << rPlantGen.EStr(titg->Ev)); 00510 // add to todo list if state is undiscovered 00511 if (! discovered.Exists(currenth)) { 00512 todog.push(titg->X2); 00513 todoh.push(tith->X2); 00514 FD_DF("mtcSupCon: todo push: (" << rPlantGen.SStr(titg->X2) << "|" 00515 << rSpecGen.SStr(tith->X2) << ")"); 00516 } 00517 // if h successor state not in forbidden set add transition to rtransrel 00518 if (! forbidden.Exists(tith->X2)) { 00519 rtransrel.Insert(*tith); 00520 FD_DF("mtcSupCon: incrementing g transrel"); 00521 ++titg; 00522 FD_DF("mtcSupCon: incrementing h transrel"); 00523 ++tith; 00524 } 00525 // if successor state is forbidden and event uncontrollable 00526 else if (!rCAlph.Exists(titg->Ev)) { 00527 FD_DF("mtcSupCon: successor state " << rSpecGen.SStr(tith->X2) << 00528 " forbidden and event " << rPlantGen.EStr(titg->Ev) << " uncontrollable:"); 00529 FD_DF("mtcSupCon: TraverseUncontrollableBackwards(" << rSpecGen.SStr(currenth) << ")"); 00530 TraverseUncontrollableBackwards(rCAlph, rtransrel, forbidden, currenth); 00531 #ifdef FAUDES_CHECKED 00532 // just increment transrel iterators to find all h transitions not in g 00533 FD_DF("mtcSupCon: incrementing g transrel (FAUDES_CHECKED)"); 00534 ++titg; 00535 FD_DF("mtcSupCon: incrementing h transrel (FAUDES_CHECKED)"); 00536 ++tith; 00537 #else 00538 // exit all loops 00539 titg = titg_end; 00540 tith = tith_end; 00541 #endif 00542 break; 00543 } 00544 // else if successor state in forbidden and event controllable 00545 else { 00546 FD_DF("mtcSupCon: incrementing g transrel"); 00547 ++titg; 00548 FD_DF("mtcSupCon: incrementing h transrel"); 00549 ++tith; 00550 } 00551 } 00552 // if g got some more transitions try to resync events 00553 else if (titg->Ev < tith->Ev) { 00554 FD_DF("mtcSupCon: asynchronous execution of event " 00555 << rPlantGen.EStr(titg->Ev) << " in g while " << rSpecGen.EStr(tith->Ev) 00556 << " in h"); 00557 // if uncontrollable transition leaves specification 00558 // delete state from rResGen and put into forbiddenset 00559 if (!rCAlph.Exists(titg->Ev)) { 00560 FD_DF("mtcSupCon: asynchronous event " << rPlantGen.EStr(titg->Ev) 00561 << " in g is uncontrollable"); 00562 FD_DF("mtcSupCon: TraverseUncontrollableBackwards(" << rSpecGen.SStr(currenth) << ")"); 00563 TraverseUncontrollableBackwards(rCAlph, rtransrel, forbidden, currenth); 00564 // exit all loops over g transrel 00565 titg = titg_end; 00566 break; 00567 } 00568 FD_DF("mtcSupCon: incrementing g transrel"); 00569 ++titg; 00570 } 00571 // if specification leaves plant model emit warning 00572 else { 00573 #ifdef FAUDES_CHECKED 00574 FD_WARN("mtcSupCon: transition " << rSpecGen.SStr(tith->X1) << "-" 00575 << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00576 << "in specification h not found in g"); 00577 #endif 00578 FD_DF("mtcSupCon: incrementing h transrel"); 00579 ++tith; 00580 } 00581 } 00582 // process other transitions not in h 00583 while (titg != titg_end) { 00584 FD_DF("mtcSupCon: asynchronous execution of event " 00585 << rPlantGen.EStr(titg->Ev) << " in g at end of h"); 00586 FD_DF("mtcSupCon: actual g-transition: " << rPlantGen.SStr(titg->X1) 00587 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00588 FD_DF("mtcSupCon: actual h-transition: end"); 00589 // if uncontrollable transition leaves specification 00590 if (!rCAlph.Exists(titg->Ev)) { 00591 FD_DF("mtcSupCon: asynchronous execution of uncontrollable event " 00592 << rPlantGen.EStr(titg->Ev) << " in g"); 00593 FD_DF("mtcSupCon: TraverseUncontrollableBackwards(" << rPlantGen.SStr(currenth) << ")"); 00594 TraverseUncontrollableBackwards(rCAlph, rtransrel, forbidden, currenth); 00595 // exit this loop 00596 break; 00597 } 00598 FD_DF("mtcSupCon: incrementing g transrel"); 00599 ++titg; 00600 } 00601 #ifdef FAUDES_CHECKED 00602 // process other transitions not in g 00603 while (tith != tith_end) { 00604 FD_WARN("mtcSupCon: transition " << rSpecGen.SStr(tith->X1) << "-" 00605 << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00606 << "in specification h not found in g"); 00607 FD_DF("mtcSupCon: incrementing h transrel"); 00608 ++tith; 00609 } 00610 #endif 00611 discovered.Insert(currenth); 00612 } 00613 00614 // compute complete set of forbidden states 00615 forbidden = rSpecGen.States() - ( discovered - forbidden ); 00616 00617 // remove forbidden states from stateset 00618 rSpecGen.DelStates(forbidden); 00619 } 00620 00621 00622 00623 00624 } // namespace faudes |
libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen