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>& 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