About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

mtc_supcon.cpp

Go 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.20s --- 2011.10.12 --- c++ source docu by doxygen