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>& rCompositionMap, 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, rCompositionMap, 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 // restrict composition map 00122 std::map< std::pair<Idx,Idx>, Idx>::iterator rcmapit = rCompositionMap.begin(); 00123 for(; rcmapit != rCompositionMap.end(); rcmapit++) 00124 if(!rResGen.ExistsState(rcmapit->second)) rCompositionMap.erase(rcmapit++); 00125 00126 00127 } 00128 00129 // mtcSupConClosed(rPlantGen, rSpecGen, rResGen) 00130 void mtcSupConClosed(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, MtcSystem& rResGen) { 00131 // HELPERS: 00132 std::map< std::pair<Idx,Idx>, Idx> rcmap; 00133 00134 // ALGORITHM: 00135 mtcSupConClosed(rPlantGen, rSpecGen, rcmap, rResGen); 00136 } 00137 00138 00139 // mtcSupConClosed(rPlantGen, rSpecGen, rCompositionMap, rResGen) 00140 void mtcSupConClosed(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, 00141 std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, MtcSystem& rResGen) { 00142 FD_DF("mtcSupConClosed(" << &rPlantGen << "," << &rSpecGen << ")"); 00143 00144 // PREPARE RESULT: 00145 rResGen.Clear(); 00146 rResGen.Name("mtcSupConClosed(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"); 00147 00148 rResGen.InjectAlphabet(rPlantGen.Alphabet()); 00149 00150 rResGen.SetControllable(rPlantGen.ControllableEvents()); 00151 rResGen.SetForcible(rPlantGen.ForcibleEvents()); 00152 rResGen.ClrObservable(rPlantGen.UnobservableEvents()); 00153 00154 // HELPERS: 00155 00156 // controllable events 00157 const EventSet ualph = rPlantGen.UncontrollableEvents(); 00158 FD_DF("mtcSupConClosed: controllable events: " << rPlantGen.ControllableEvents().ToString()); 00159 FD_DF("mtcSupConClosed: uncontrollable events: " << ualph.ToString()); 00160 00161 // CONSISTENCY CHECK: 00162 00163 // alphabets must match 00164 if (rPlantGen.Alphabet() != rSpecGen.Alphabet()) { 00165 EventSet only_in_plant = rPlantGen.Alphabet() - rSpecGen.Alphabet(); 00166 EventSet only_in_spec = rSpecGen.Alphabet() - rPlantGen.Alphabet(); 00167 std::stringstream errstr; 00168 errstr << "Alphabets of generators do not match. Only in plant: " 00169 << only_in_plant.ToString() << ". Only in spec: " 00170 << only_in_spec.ToString() << "."; 00171 throw Exception("mtcSupConClosed", errstr.str(), 500); 00172 } 00173 00174 // plant and spec must be deterministic 00175 bool plant_det = rPlantGen.IsDeterministic(); 00176 bool spec_det = rSpecGen.IsDeterministic(); 00177 00178 if ((plant_det == false) && (spec_det == true)) { 00179 std::stringstream errstr; 00180 errstr << "Plant generator must be deterministic, " << "but is nondeterministic"; 00181 throw Exception("mtcSupConClosed", errstr.str(), 501); 00182 } 00183 else if ((plant_det == true) && (spec_det == false)) { 00184 std::stringstream errstr; 00185 errstr << "Spec generator must be deterministic, " << "but is nondeterministic"; 00186 throw Exception("mtcSupConClosed", errstr.str(), 503); 00187 } 00188 else if ((plant_det == false) && (spec_det == false)) { 00189 std::stringstream errstr; 00190 errstr << "Plant and spec generator must be deterministic, " 00191 << "but both are nondeterministic"; 00192 throw Exception("mtcSupCon", errstr.str(), 504); 00193 } 00194 00195 // ALGORITHM: 00196 00197 // parallel composition 00198 mtcSupConParallel(rPlantGen, rSpecGen, ualph, rCompositionMap, rResGen); 00199 // make resulting generator controllable 00200 mtcSupConUnchecked(rPlantGen, rPlantGen.ControllableEvents(), rResGen); 00201 00202 // restrict composition map 00203 std::map< std::pair<Idx,Idx>, Idx>::iterator rcmapit = rCompositionMap.begin(); 00204 for(; rcmapit != rCompositionMap.end(); rcmapit++) 00205 if(!rResGen.ExistsState(rcmapit->second)) rCompositionMap.erase(rcmapit++); 00206 00207 00208 } 00209 00210 00211 00212 /* 00213 ******************************************** 00214 * Fast parallel composition for mtcSupCon * 00215 ******************************************** 00216 */ 00217 00218 00219 // mtcSupConParallel(rPlantGen, rSpecGen, rUAlph, rReverseCompositionMap, rResGen) 00220 void mtcSupConParallel(const MtcSystem& rPlantGen, const MtcSystem& rSpecGen, const EventSet& rUAlph, 00221 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, MtcSystem& rResGen) { 00222 FD_DF("mtcSupConParallel(" << &rPlantGen << "," << &rSpecGen << ")"); 00223 00224 // HELPERS: 00225 00226 // todo stack 00227 std::stack< std::pair<Idx,Idx> > todo; 00228 // set of forbidden states 00229 StateSet forbidden; 00230 // actual pair, new pair 00231 std::pair<Idx,Idx> currentstates, newstates; 00232 // other stuff 00233 Idx tmpstate; 00234 std::map< std::pair<Idx,Idx>, Idx>::iterator rcmapit; 00235 StateSet::Iterator lit1, lit2; 00236 TransSet::Iterator titg, titg_end, tith, tith_end; 00237 00238 // Prepare 00239 rResGen.ClearStates(); 00240 00241 // ALGORITHM: 00242 if (rPlantGen.InitStatesEmpty()) { 00243 FD_DF("SupconParallel: plant got no initial states. " 00244 << "parallel composition contains empty language."); 00245 return; 00246 } 00247 00248 if (rSpecGen.InitStatesEmpty()) { 00249 FD_DF("mtcSupConParallel: spec got no initial states. " 00250 << "parallel composition contains empty language."); 00251 return; 00252 } 00253 ColorSet plantColors = rPlantGen.Colors(); 00254 ColorSet specColors = rSpecGen.Colors(); 00255 // create initial state 00256 currentstates = std::make_pair(*rPlantGen.InitStatesBegin(), *rSpecGen.InitStatesBegin()); 00257 todo.push(currentstates); 00258 ColorSet ComposedSet; 00259 ComposedColorSet(rPlantGen, currentstates.first, plantColors, rSpecGen, currentstates.second, 00260 specColors, ComposedSet); 00261 if (! ComposedSet.Empty() ) { 00262 Idx StateIndex = rResGen.InsInitState(); 00263 rReverseCompositionMap[currentstates] = StateIndex; 00264 rResGen.InsColors(StateIndex, ComposedSet); 00265 FD_DF("mtcSupConParallel: NEW IMSTATE: (" << rPlantGen.SStr(currentstates.first) 00266 << "|" << rSpecGen.SStr(currentstates.second) << ") -> " << rReverseCompositionMap[currentstates]); 00267 } 00268 else { 00269 rReverseCompositionMap[currentstates] = rResGen.InsInitState(); 00270 FD_DF("mtcSupConParallel: NEW ISTATE: (" << rPlantGen.SStr(currentstates.first) 00271 << "|" << rSpecGen.SStr(currentstates.second) << ") -> " << rReverseCompositionMap[currentstates]); 00272 } 00273 00274 // first do parallel composition of allowed states 00275 // by deleting forbidden states on the fly. 00276 // this creates an accessible new generator 00277 FD_DF("mtcSupConParallel: *** processing reachable states ***"); 00278 while (! todo.empty()) { 00279 // get next reachable pair of states from todo stack 00280 currentstates = todo.top(); 00281 todo.pop(); 00282 FD_DF("mtcSupConParallel: todo pop: (" << rPlantGen.SStr(currentstates.first) 00283 << "|" << rSpecGen.SStr(currentstates.second) << ") -> " << rReverseCompositionMap[currentstates]); 00284 00285 titg = rPlantGen.TransRelBegin(currentstates.first); 00286 titg_end = rPlantGen.TransRelEnd(currentstates.first); 00287 tith = rSpecGen.TransRelBegin(currentstates.second); 00288 tith_end = rSpecGen.TransRelEnd(currentstates.second); 00289 00290 #ifdef FAUDES_DEBUG_FUNCTION 00291 // print all transitions of current states 00292 FD_DF("mtcSupConParallel: transitions from current states:"); 00293 for (;titg != titg_end; ++titg) { 00294 FD_DF("mtcSupConParallel: g: " << rPlantGen.SStr(titg->X1) << "-" << rPlantGen.EStr(titg->Ev) 00295 << "-" << rPlantGen.SStr(titg->X2)); 00296 } 00297 for (;tith != tith_end; ++tith) { 00298 FD_DF("mtcSupConParallel: h: " << rSpecGen.SStr(tith->X1) << "-" << rSpecGen.EStr(tith->Ev) 00299 << "-" << rSpecGen.SStr(tith->X2)); 00300 } 00301 titg = rPlantGen.TransRelBegin(currentstates.first); 00302 tith = rSpecGen.TransRelBegin(currentstates.second); 00303 #endif 00304 // process all h transitions while there could be matching g transitions 00305 while ((tith != tith_end) && (titg != titg_end)) { 00306 FD_DF("mtcSupConParallel: actual g-transition: " << rPlantGen.SStr(titg->X1) 00307 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00308 FD_DF("mtcSupConParallel: actual h-transition: " << rSpecGen.SStr(tith->X1) 00309 << "-" << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2)); 00310 // execute common events 00311 if (titg->Ev == tith->Ev) { 00312 FD_DF("mtcSupConParallel: executing common event " 00313 << rPlantGen.EStr(titg->Ev)); 00314 newstates = std::make_pair(titg->X2, tith->X2); 00315 rcmapit = rReverseCompositionMap.find(newstates); 00316 // add to todo list if state is new 00317 if (rcmapit == rReverseCompositionMap.end()) { 00318 todo.push(newstates); 00319 // if colored state 00320 ComposedColorSet(rPlantGen, newstates.first, plantColors, rSpecGen, newstates.second, 00321 specColors, ComposedSet); 00322 if (not ComposedSet.Empty() ) { 00323 tmpstate = rResGen.InsState(); 00324 rResGen.InsColors(tmpstate, ComposedSet); 00325 FD_DF("mtcSupConParallel: NEW MSTATE: (" 00326 << rPlantGen.SStr(newstates.first) << "|" 00327 << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate); 00328 } 00329 // if "normal" state 00330 else { 00331 tmpstate = rResGen.InsState(); 00332 FD_DF("mtcSupConParallel: NEW STATE: (" 00333 << rPlantGen.SStr(newstates.first) << "|" 00334 << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate); 00335 } 00336 rReverseCompositionMap[newstates] = tmpstate; 00337 FD_DF("mtcSupConParallel: todo push: (" << rPlantGen.SStr(newstates.first) 00338 << "|" << rSpecGen.SStr(newstates.second) << ") -> " << tmpstate); 00339 } 00340 // if state already exists 00341 else { 00342 tmpstate = rcmapit->second; 00343 } 00344 // if successor state not in forbidden set add transition 00345 if (! forbidden.Exists(tmpstate)) { 00346 FD_DF("mtcSupConParallel: ADDING TRANSITION " 00347 << rPlantGen.SStr(rReverseCompositionMap[currentstates]) << "-" << rPlantGen.EStr(titg->Ev) 00348 << "-" << rPlantGen.SStr(tmpstate)); 00349 rResGen.SetTransition(rReverseCompositionMap[currentstates], titg->Ev, tmpstate); 00350 FD_DF("mtcSupConParallel: incrementing g transrel"); 00351 ++titg; 00352 FD_DF("mtcSupConParallel: incrementing h transrel"); 00353 ++tith; 00354 } 00355 // if successor state in forbidden and event uncontrollable 00356 // delete state 00357 else if (rUAlph.Exists(titg->Ev)) { 00358 FD_DF("mtcSupConParallel: successor " << rSpecGen.SStr(tmpstate) 00359 << "in forbidden and common event " << rSpecGen.EStr(titg->Ev) 00360 << " uncontrollable:"); 00361 FD_DF("mtcSupConParallel: forbidden insert" << rPlantGen.SStr(tmpstate)); 00362 forbidden.Insert(tmpstate); 00363 #ifdef FAUDES_CHECKED 00364 // do not end while loops here for detecting all h transitions 00365 // not in g 00366 FD_DF("mtcSupConParallel: incrementing g transrel (FAUDES_CHECKED)"); 00367 ++titg; 00368 FD_DF("mtcSupConParallel: incrementing h transrel (FAUDES_CHECKED)"); 00369 ++tith; 00370 #else 00371 // exit all loops 00372 titg = titg_end; 00373 tith = tith_end; 00374 #endif 00375 } 00376 // else if successor state in forbidden and event controllable 00377 else { 00378 FD_DF("mtcSupConParallel: incrementing g transrel"); 00379 ++titg; 00380 FD_DF("mtcSupConParallel: incrementing h transrel"); 00381 ++tith; 00382 } 00383 } 00384 // if g got some more transitions try to resync events 00385 else if (titg->Ev < tith->Ev) { 00386 FD_DF("mtcSupConParallel: asynchronous execution of event " 00387 << rPlantGen.EStr(titg->Ev) << " in g while " << rSpecGen.EStr(tith->Ev) 00388 << " in h"); 00389 // if uncontrollable transition leaves specification 00390 // delete state from res and put into forbiddenset 00391 if (rUAlph.Exists(titg->Ev)) { 00392 FD_DF("mtcSupConParallel: asynchronous event " << rPlantGen.EStr(titg->Ev) 00393 << " in g is uncontrollable"); 00394 tmpstate = rReverseCompositionMap[currentstates]; 00395 FD_DF("mtcSupConParallel: forbidden insert" << rPlantGen.SStr(tmpstate)); 00396 forbidden.Insert(tmpstate); 00397 // exit all loops 00398 titg = titg_end; 00399 tith = tith_end; 00400 break; 00401 } 00402 FD_DF("mtcSupConParallel: incrementing g transrel"); 00403 ++titg; 00404 } // if specification leaves plant model emit warning 00405 else { 00406 #ifdef FAUDES_CHECKED 00407 // FD_WARN("mtcSupConParallel: transition " << rSpecGen.SStr(tith->X1) 00408 // << "-" << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00409 // << " in specification h not found in g"); 00410 #endif 00411 FD_DF("mtcSupConParallel: incrementing h transrel"); 00412 ++tith; 00413 } 00414 } 00415 if (rResGen.InitStates().Empty()) FD_DF("mtcSupConParallel: rResGen has no initial states... (2)"); 00416 00417 // if g got some more transitions not in h 00418 while (titg != titg_end) { 00419 FD_DF("mtcSupConParallel: asynchronous execution of event " 00420 << rPlantGen.EStr(titg->Ev) << " in g at end of h"); 00421 FD_DF("mtcSupConParallel: actual g-transition: " << rPlantGen.SStr(titg->X1) 00422 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00423 FD_DF("mtcSupConParallel: actual h-transition: end"); 00424 // if uncontrollable transition leaves specification 00425 if (rUAlph.Exists(titg->Ev)) { 00426 tmpstate = rReverseCompositionMap[currentstates]; 00427 FD_DF("mtcSupConParallel: asynchron executed uncontrollable end " 00428 << "event " << rPlantGen.EStr(titg->Ev) << " leaves specification:"); 00429 FD_DF("mtcSupConParallel: forbidden insert" << rPlantGen.SStr(tmpstate)); 00430 forbidden.Insert(tmpstate); 00431 // exit this loop 00432 // if FAUDES_CHECKED not defined this means exiting all loops 00433 break; 00434 } 00435 FD_DF("mtcSupConParallel: incrementing g transrel"); 00436 ++titg; 00437 } 00438 #ifdef FAUDES_CHECKED 00439 // if h got some more transitions not in g 00440 // while (tith != tith_end) { 00441 // FD_WARN("mtcSupConParallel: transition " << rSpecGen.SStr(tith->X1) << "-" 00442 // << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00443 // << "in specification h not found in g"); 00444 // FD_DF("mtcSupConParallel: incrementing h transrel"); 00445 // ++tith; 00446 // } 00447 #endif 00448 } 00449 FD_DF("mtcSupConParallel: deleting forbidden states..."); 00450 // remove forbidden states from stateset 00451 rResGen.DelStates(forbidden); 00452 } 00453 00454 /* 00455 ***************************************** 00456 * mtcSupConUnchecked: REAL SUPCON FUNCTION * 00457 ***************************************** 00458 */ 00459 00460 00461 // mtcSupConUnchecked(rPlantGen, rSpecGen, rCAlph) 00462 void mtcSupConUnchecked(const MtcSystem& rPlantGen, const EventSet& rCAlph, MtcSystem& rSpecGen) { 00463 00464 FD_DF("mtcSupConUnchecked(" << &rSpecGen << "," << &rPlantGen << ")"); 00465 00466 // HELPERS: 00467 00468 // forbiden states 00469 StateSet forbidden; 00470 // todo stack 00471 std::stack<Idx> todog, todoh; 00472 // set of already discovered states 00473 StateSet discovered; 00474 // reverse sorted transition relation build on the fly 00475 TransSetX2EvX1 rtransrel; 00476 00477 00478 // ALGORITHM: 00479 00480 // bail out if there is no initial state 00481 if (rPlantGen.InitStatesEmpty() || rSpecGen.InitStatesEmpty()); 00482 00483 // push combined initial state on todo stack 00484 todog.push(*rPlantGen.InitStatesBegin()); 00485 todoh.push(*rSpecGen.InitStatesBegin()); 00486 FD_DF("mtcSupCon: todo push: (" << rPlantGen.SStr(*rPlantGen.InitStatesBegin()) << "|" 00487 << rSpecGen.SStr(*rSpecGen.InitStatesBegin()) << ")"); 00488 00489 // process todo stack 00490 while (! todog.empty()) { 00491 // get top elements from todo stack 00492 Idx currentg = todog.top(); 00493 Idx currenth = todoh.top(); 00494 todog.pop(); 00495 todoh.pop(); 00496 FD_DF("mtcSupCon: todo pop: (" << rPlantGen.SStr(currentg) << "|" 00497 << rSpecGen.SStr(currenth) << ")"); 00498 00499 #ifdef FAUDES_DEBUG_FUNCTION 00500 TransSet::Iterator _titg, _tith; 00501 // print all transitions of current states 00502 FD_DF("mtcSupCon: transitions from current states:"); 00503 for (_titg = rPlantGen.TransRelBegin(currentg); _titg != rPlantGen.TransRelEnd(currentg); ++_titg) 00504 FD_DF("mtcSupCon: g: " << rPlantGen.SStr(_titg->X1) << "-" 00505 << rPlantGen.EStr(_titg->Ev) << "-" << rPlantGen.SStr(_titg->X2)); 00506 for (_tith = rSpecGen.TransRelBegin(currenth); _tith != rSpecGen.TransRelEnd(currenth); ++_tith) 00507 FD_DF("mtcSupCon: h: " << rSpecGen.SStr(_tith->X1) << "-" 00508 << rSpecGen.EStr(_tith->Ev) << "-" << rSpecGen.SStr(_tith->X2)); 00509 #endif 00510 00511 // process all h transitions while there could be matching g transitions 00512 TransSet::Iterator titg = rPlantGen.TransRelBegin(currentg); 00513 TransSet::Iterator titg_end = rPlantGen.TransRelEnd(currentg); 00514 TransSet::Iterator tith = rSpecGen.TransRelBegin(currenth); 00515 TransSet::Iterator tith_end = rSpecGen.TransRelEnd(currenth); 00516 while ((tith != tith_end) && (titg != titg_end)) { 00517 FD_DF("mtcSupCon: actual g-transition: " << rPlantGen.SStr(titg->X1) 00518 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00519 FD_DF("mtcSupCon: actual h-transition: " << rSpecGen.SStr(tith->X1) 00520 << "-" << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2)); 00521 // execute common events 00522 if (titg->Ev == tith->Ev) { 00523 FD_DF("mtcSupCon: executing common event " << rPlantGen.EStr(titg->Ev)); 00524 // add to todo list if state is undiscovered 00525 if (! discovered.Exists(currenth)) { 00526 todog.push(titg->X2); 00527 todoh.push(tith->X2); 00528 FD_DF("mtcSupCon: todo push: (" << rPlantGen.SStr(titg->X2) << "|" 00529 << rSpecGen.SStr(tith->X2) << ")"); 00530 } 00531 // if h successor state not in forbidden set add transition to rtransrel 00532 if (! forbidden.Exists(tith->X2)) { 00533 rtransrel.Insert(*tith); 00534 FD_DF("mtcSupCon: incrementing g transrel"); 00535 ++titg; 00536 FD_DF("mtcSupCon: incrementing h transrel"); 00537 ++tith; 00538 } 00539 // if successor state is forbidden and event uncontrollable 00540 else if (!rCAlph.Exists(titg->Ev)) { 00541 FD_DF("mtcSupCon: successor state " << rSpecGen.SStr(tith->X2) << 00542 " forbidden and event " << rPlantGen.EStr(titg->Ev) << " uncontrollable:"); 00543 FD_DF("mtcSupCon: TraverseUncontrollableBackwards(" << rSpecGen.SStr(currenth) << ")"); 00544 TraverseUncontrollableBackwards(rCAlph, rtransrel, forbidden, currenth); 00545 #ifdef FAUDES_CHECKED 00546 // just increment transrel iterators to find all h transitions not in g 00547 FD_DF("mtcSupCon: incrementing g transrel (FAUDES_CHECKED)"); 00548 ++titg; 00549 FD_DF("mtcSupCon: incrementing h transrel (FAUDES_CHECKED)"); 00550 ++tith; 00551 #else 00552 // exit all loops 00553 titg = titg_end; 00554 tith = tith_end; 00555 #endif 00556 break; 00557 } 00558 // else if successor state in forbidden and event controllable 00559 else { 00560 FD_DF("mtcSupCon: incrementing g transrel"); 00561 ++titg; 00562 FD_DF("mtcSupCon: incrementing h transrel"); 00563 ++tith; 00564 } 00565 } 00566 // if g got some more transitions try to resync events 00567 else if (titg->Ev < tith->Ev) { 00568 FD_DF("mtcSupCon: asynchronous execution of event " 00569 << rPlantGen.EStr(titg->Ev) << " in g while " << rSpecGen.EStr(tith->Ev) 00570 << " in h"); 00571 // if uncontrollable transition leaves specification 00572 // delete state from rResGen and put into forbiddenset 00573 if (!rCAlph.Exists(titg->Ev)) { 00574 FD_DF("mtcSupCon: asynchronous event " << rPlantGen.EStr(titg->Ev) 00575 << " in g is uncontrollable"); 00576 FD_DF("mtcSupCon: TraverseUncontrollableBackwards(" << rSpecGen.SStr(currenth) << ")"); 00577 TraverseUncontrollableBackwards(rCAlph, rtransrel, forbidden, currenth); 00578 // exit all loops over g transrel 00579 titg = titg_end; 00580 break; 00581 } 00582 FD_DF("mtcSupCon: incrementing g transrel"); 00583 ++titg; 00584 } 00585 // if specification leaves plant model emit warning 00586 else { 00587 #ifdef FAUDES_CHECKED 00588 FD_WARN("mtcSupCon: transition " << rSpecGen.SStr(tith->X1) << "-" 00589 << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00590 << "in specification h not found in g"); 00591 #endif 00592 FD_DF("mtcSupCon: incrementing h transrel"); 00593 ++tith; 00594 } 00595 } 00596 // process other transitions not in h 00597 while (titg != titg_end) { 00598 FD_DF("mtcSupCon: asynchronous execution of event " 00599 << rPlantGen.EStr(titg->Ev) << " in g at end of h"); 00600 FD_DF("mtcSupCon: actual g-transition: " << rPlantGen.SStr(titg->X1) 00601 << "-" << rPlantGen.EStr(titg->Ev) << "-" << rPlantGen.SStr(titg->X2)); 00602 FD_DF("mtcSupCon: actual h-transition: end"); 00603 // if uncontrollable transition leaves specification 00604 if (!rCAlph.Exists(titg->Ev)) { 00605 FD_DF("mtcSupCon: asynchronous execution of uncontrollable event " 00606 << rPlantGen.EStr(titg->Ev) << " in g"); 00607 FD_DF("mtcSupCon: TraverseUncontrollableBackwards(" << rPlantGen.SStr(currenth) << ")"); 00608 TraverseUncontrollableBackwards(rCAlph, rtransrel, forbidden, currenth); 00609 // exit this loop 00610 break; 00611 } 00612 FD_DF("mtcSupCon: incrementing g transrel"); 00613 ++titg; 00614 } 00615 #ifdef FAUDES_CHECKED 00616 // process other transitions not in g 00617 while (tith != tith_end) { 00618 FD_WARN("mtcSupCon: transition " << rSpecGen.SStr(tith->X1) << "-" 00619 << rSpecGen.EStr(tith->Ev) << "-" << rSpecGen.SStr(tith->X2) 00620 << "in specification h not found in g"); 00621 FD_DF("mtcSupCon: incrementing h transrel"); 00622 ++tith; 00623 } 00624 #endif 00625 discovered.Insert(currenth); 00626 } 00627 00628 // compute complete set of forbidden states 00629 forbidden = rSpecGen.States() - ( discovered - forbidden ); 00630 00631 // remove forbidden states from stateset 00632 rSpecGen.DelStates(forbidden); 00633 } 00634 00635 00636 00637 00638 } // namespace faudes libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |