libFAUDES

Sections

Index

syn_wsupcon.cpp

Go to the documentation of this file.
00001 /** @file syn_wsupcon.cpp Supremal controllable sublanguage for infinite time behaviours */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2010 Thomas Moor
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with this library; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00020    
00021 
00022 //#define FAUDES_DEBUG_FUNCTION
00023 
00024 #include "syn_wsupcon.h"
00025 #include "syn_supcon.h"
00026 #include "syn_functions.h"
00027 
00028 
00029 namespace faudes {
00030 
00031 
00032 /*
00033 ***************************************************************************************
00034 ***************************************************************************************
00035  Implementation IsOmegaControllabe
00036 ***************************************************************************************
00037 ***************************************************************************************
00038 */
00039 
00040 // IsOmegaControllable()
00041 bool IsOmegaControllable(
00042   const vGenerator& rGenPlant, 
00043   const EventSet&  rCAlph, 
00044   const vGenerator& rGenCand) 
00045 {
00046   FD_DF("IsOmegaControllable(\"" <<  rGenPlant.Name() << "\", \"" << rGenCand.Name() << "\")");
00047 
00048   // alphabets must match
00049   if ( rGenPlant.Alphabet() != rGenCand.Alphabet()) {
00050     std::stringstream errstr;
00051     errstr << "Alphabets of generators do not match.";
00052     throw Exception("IsOmegaControllable(..)", errstr.str(), 100);
00053   }
00054 
00055 #ifdef FAUDES_CHECKED
00056   // generators are meant to be nonblocking
00057   if( !IsOmegaTrim(rGenCand) ) {
00058     std::stringstream errstr;
00059     errstr << "Argument \"" << rGenCand.Name() << "\" is not omega-trim.";
00060     throw Exception("IsOmegaControllable(..)", errstr.str(), 201);
00061   }
00062   if( !IsOmegaTrim(rGenPlant) ) {
00063     std::stringstream errstr;
00064     errstr << "Argument \"" << rGenPlant.Name() << "\" is not omega-trim.";
00065     throw Exception("IsOmegaControllable(..)", errstr.str(), 201);
00066   }
00067 #endif
00068 
00069   // the trivial case: empty cand is fine
00070   // (we must treat this case because empty generators are not regarded deterministic)
00071   if(rGenCand.Empty()) {
00072     FD_DF("IsOmegaControllable(..): empty candidate, pass");
00073     return true;
00074   }
00075 
00076   // the trivial case: empty plant is fails
00077   // (we must treat this case because empty generators are not regarded deterministic)
00078   if(rGenPlant.Empty()) {
00079     FD_DF("IsOmegaControllable(..): empty plant, fail");
00080     return false;
00081   }
00082 
00083 #ifdef FAUDES_CHECKED
00084   // generators are meant to be deterministic
00085   if ( !IsDeterministic(rGenCand) ||  !IsDeterministic(rGenPlant)) {
00086     std::stringstream errstr;
00087     errstr << "Arguments are expected to be deterministic.";
00088     throw Exception("IsRelativelyOmegaClosed", errstr.str(), 202);
00089   }
00090 #endif
00091 
00092   // test controllability
00093   StateSet dummy;
00094   if(!IsControllableUnchecked(rGenPlant,rCAlph,rGenCand,dummy)) return false;
00095 
00096   // test relative closedness
00097   if(!IsRelativelyOmegaClosedUnchecked(rGenPlant,rGenPlant)) return false;
00098 
00099   // pass
00100   FD_DF("IsOmegaControllable(...): passed");
00101   return true;
00102 }
00103 
00104 
00105 // IsOmegaControllable() wrapper
00106 bool IsOmegaControllable(
00107   const cGenerator& rPlantGen, 
00108   const vGenerator& rCandGen) 
00109 {
00110   return IsOmegaControllable(rPlantGen,rPlantGen.ControllableEvents(),rCandGen);
00111 }
00112 
00113 /*
00114 ***************************************************************************************
00115 ***************************************************************************************
00116  Implementation SupConComplete
00117 ***************************************************************************************
00118 ***************************************************************************************
00119 */
00120 
00121 
00122 // supcon complete
00123 void SupConComplete(
00124   const vGenerator& rPlantGen, 
00125   const EventSet&  rCAlph,
00126   const vGenerator& rSpecGen, 
00127   vGenerator& rResGen)
00128 { 
00129   FD_DF("SupConComplete(" << rPlantGen.Name() << "," << rSpecGen.Name()<< ")");
00130   
00131   // exceptions on invalid parameters, same as std synthesis
00132   ControlProblemConsistencyCheck(rPlantGen,rCAlph,rSpecGen);  
00133 
00134   // prepare result
00135   vGenerator* pResGen = &rResGen;
00136   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00137     pResGen= rResGen.New();
00138   }
00139   pResGen->Clear();
00140   pResGen->Name("SupConComplete("+rPlantGen.Name()+", "+rSpecGen.Name()+")");
00141   pResGen->InjectAlphabet(rPlantGen.Alphabet());
00142   
00143   //check for trivial result
00144   if(rSpecGen.InitStatesEmpty()){
00145     FD_DF("SupConComplete: empty language specification - empty result.");
00146   }  
00147     
00148 
00149   // have a reverse composition map
00150   std::map< std::pair<Idx,Idx>, Idx> revmap;
00151 
00152   // parallel composition (result is reachable)
00153   SupconParallel(rPlantGen, rCAlph, rSpecGen, revmap, *pResGen);
00154 
00155   // make resulting generator complete and controllabel
00156   while(true) {
00157     Idx state_num = pResGen->Size();
00158     if(pResGen->InitStates().Empty()) break;
00159     pResGen->Complete();
00160     if(pResGen->InitStates().Empty()) break;
00161     SupConUnchecked(rPlantGen, rCAlph, *pResGen);
00162     if(pResGen->Size() == state_num) break;
00163   }
00164 
00165   // convenience state names
00166   if(rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00167     SetComposedStateNames(rPlantGen, rSpecGen, revmap, *pResGen);
00168   else
00169     pResGen->ClearStateNames();
00170 
00171   // copy result
00172   if(pResGen != &rResGen) {
00173     pResGen->Move(rResGen);
00174     delete pResGen;
00175   }
00176 
00177 }
00178 
00179 
00180 // user wrapper
00181 void SupConComplete(
00182   const cGenerator& rPlantGen, 
00183   const vGenerator& rSpecGen, 
00184   vGenerator& rResGen) 
00185 {
00186 
00187   // execute 
00188   SupConComplete(rPlantGen, rPlantGen.ControllableEvents(),rSpecGen,rResGen);
00189 
00190   // copy all attributes of input alphabet
00191   rResGen.EventAttributes(rPlantGen.Alphabet());
00192 
00193 }
00194 
00195 
00196 
00197 
00198 /*
00199 ***************************************************************************************
00200 ***************************************************************************************
00201  Implementation SupConCompleteNB
00202 ***************************************************************************************
00203 ***************************************************************************************
00204 */
00205 
00206 
00207 // supcon complete
00208 void SupConCompleteNB(
00209   const vGenerator& rPlantGen, 
00210   const EventSet&  rCAlph,
00211   const vGenerator& rSpecGen, 
00212   vGenerator& rResGen)
00213 { 
00214   FD_DF("SupConCompleteNB(" << rPlantGen.Name() << "," << rSpecGen.Name()<< ")");
00215   
00216   // exceptions on invalid parameters, same as std synthesis
00217   ControlProblemConsistencyCheck(rPlantGen,rCAlph,rSpecGen);  
00218 
00219   // prepare result
00220   vGenerator* pResGen = &rResGen;
00221   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00222     pResGen= rResGen.New();
00223   }
00224   pResGen->Clear();
00225   pResGen->Name("SupConCompleteNB("+rPlantGen.Name()+", "+rSpecGen.Name()+")");
00226   pResGen->InjectAlphabet(rPlantGen.Alphabet());
00227   
00228   //check for trivial result
00229   if(rSpecGen.InitStatesEmpty()){
00230     FD_DF("SupConCompleteNB: empty language specification - empty result.");
00231   }  
00232     
00233 
00234   // have a reverse composition map
00235   std::map< std::pair<Idx,Idx>, Idx> revmap;
00236 
00237   // parallel composition (result is reachable)
00238   SupconParallel(rPlantGen, rCAlph, rSpecGen, revmap, *pResGen);
00239 
00240   // make resulting generator complete and controllabel and coaccessible
00241   while(true) {
00242     Idx state_num = pResGen->Size();
00243     if(pResGen->InitStates().Empty()) break;
00244     pResGen->Coaccessible();
00245     if(pResGen->InitStates().Empty()) break;
00246     pResGen->Complete();
00247     if(pResGen->InitStates().Empty()) break;
00248     SupConUnchecked(rPlantGen, rCAlph, *pResGen);
00249     if(pResGen->Size() == state_num) break;
00250   }
00251 
00252   // convenience state names
00253   if(rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && rResGen.StateNamesEnabled()) 
00254     SetComposedStateNames(rPlantGen, rSpecGen, revmap, *pResGen);
00255   else
00256     pResGen->ClearStateNames();
00257 
00258   // copy result
00259   if(pResGen != &rResGen) {
00260     pResGen->Move(rResGen);
00261     delete pResGen;
00262   }
00263 
00264 }
00265 
00266 
00267 // user wrapper
00268 void SupConCompleteNB(
00269   const cGenerator& rPlantGen, 
00270   const vGenerator& rSpecGen, 
00271   vGenerator& rResGen) 
00272 {
00273 
00274   // execute 
00275   SupConCompleteNB(rPlantGen, rPlantGen.ControllableEvents(),rSpecGen,rResGen);
00276 
00277   // copy all attributes of input alphabet
00278   rResGen.EventAttributes(rPlantGen.Alphabet());
00279 
00280 }
00281 
00282 
00283 
00284 
00285 /*
00286 ***************************************************************************************
00287 ***************************************************************************************
00288  Implementation (experimental)
00289 ***************************************************************************************
00290 ***************************************************************************************
00291 */
00292 
00293 
00294 
00295 
00296 
00297 // OmegaControlledLiveness(...)
00298 bool OmegaControlledLiveness(
00299   vGenerator& rSupCandGen, 
00300   const EventSet& rCAlph,
00301   StateSet& rMarkedPlantStates, 
00302   StateSet& rMarkedSpecStates)
00303 {
00304   FD_DF("OmegaClosedLoopLiveness(...)");
00305 
00306 
00307   // set of critical states
00308   StateSet critical;
00309    
00310   // return true if parallelcomp contains no initial states
00311   if(rSupCandGen.InitStatesEmpty()) {
00312     return true;
00313   }
00314 
00315 #ifdef FAUDES_DEBUG_FUNCTION
00316   FD_DF("OmegaClosedLoopLiveness(): marked states: ");
00317   StateSet ssd= rMarkedPlantStates + rMarkedSpecStates;
00318   ssd.Write();
00319 #endif
00320 
00321   // find un-marked sccs
00322   SccFilter umfilter(SccFilter::IgnoreTrivial | SccFilter::StatesAvoid, 
00323      rMarkedPlantStates + rMarkedSpecStates);
00324   std::list<StateSet> umsccs;
00325   StateSet umroots;
00326   ComputeScc(rSupCandGen,umfilter,umsccs,umroots); 
00327 
00328   // report
00329   std::list<StateSet>::iterator ssit=umsccs.begin();
00330   for(;ssit!=umsccs.end(); ++ssit) {
00331     FD_DF("OmegaClosedLoopLiveness(): unmarked scc: " << ssit->ToString());
00332   }  
00333 
00334 
00335   // good-states iteration
00336   StateSet goodstates = rMarkedSpecStates;
00337 
00338   // drive states to good states
00339   while(true) {
00340     // LoopCallback();
00341     // allow for user interrupt, incl progress report
00342     FD_WPC(1,2,"OmegaClosedLoopLiveness(): iterating states"); 
00343     // test individual states
00344     FD_DF("OmegaClosedLoopLiveness(): iterate over states (#" << rSupCandGen.Size() << ")");
00345     bool found=false;
00346     StateSet::Iterator sit = rSupCandGen.StatesBegin();
00347     StateSet::Iterator sit_end = rSupCandGen.StatesEnd();
00348     for(; sit!=sit_end; ++sit) {
00349       // goodstate anyway
00350       if(goodstates.Exists(*sit)) continue;
00351       // test transitions
00352       TransSet::Iterator tit = rSupCandGen.TransRelBegin(*sit);
00353       TransSet::Iterator tit_end = rSupCandGen.TransRelEnd(*sit);
00354       // no transitions at all
00355       if(tit==tit_end) continue;
00356       // loop over successors
00357       for(; tit!=tit_end; ++tit) {
00358         if(goodstates.Exists(tit->X2)) continue;
00359         if(rCAlph.Exists(tit->Ev)) continue;
00360         break;
00361       }
00362       // good states survive the loop
00363       if(tit==tit_end) {
00364         FD_DF("OmegaClosedLoopLiveness(): good state " << rSupCandGen.SStr(*sit));
00365         goodstates.Insert(*sit);
00366         found=true;
00367       }
00368     }
00369     // test individual unmarked sccs
00370     FD_DF("OmegaClosedLoopLiveness(): iterate over unmarked sccs (#" << umsccs.size() <<")");
00371     std::list<StateSet>::iterator ssit=umsccs.begin();
00372     while(ssit!=umsccs.end()) { 
00373       bool fail=false;
00374       bool positive=false;
00375       sit=ssit->Begin();
00376       sit_end=ssit->End();
00377       for(; sit!=sit_end; ++sit) {
00378         // goodstate anyway
00379         if(goodstates.Exists(*sit)) continue;
00380         // test transitions
00381         TransSet::Iterator tit = rSupCandGen.TransRelBegin(*sit);
00382         TransSet::Iterator tit_end = rSupCandGen.TransRelEnd(*sit);
00383         // no transitions at all
00384         if(tit==tit_end) continue;        
00385         // loop over successors
00386         for(; tit!=tit_end; ++tit) {
00387           if(goodstates.Exists(tit->X2)) { positive=true; continue;}
00388           if(rCAlph.Exists(tit->X2)) continue;
00389           if(ssit->Exists(tit->X2)) continue;
00390           break;
00391         }
00392         // good states survive the loop
00393         if(tit!=tit_end) {
00394           fail=true;
00395           break;
00396         }
00397       }
00398       // prepare next scc iterator
00399       std::list<StateSet>::iterator ssitnext=ssit;
00400       ++ssitnext;
00401       bool lend= (ssitnext==umsccs.end());
00402       // all states passed, then they are all good
00403       if(!fail && positive) {
00404         FD_DF("OmegaClosedLoopLiveness(): good scc " << ssit->ToString());
00405         goodstates.InsertSet(*ssit);
00406         umsccs.erase(ssit);
00407         found=true;
00408       }
00409       // break on end of list
00410       if(lend) break;
00411       // progress
00412       ssit=ssitnext;
00413     }
00414     // exit
00415     if(!found) break;
00416   };
00417 
00418 
00419 
00420   // delete critical states
00421   FD_DF("OmegaClosedLoopLiveness(): good states: " << goodstates.ToString())
00422   StateSet::Iterator sit = rSupCandGen.StatesBegin();
00423   StateSet::Iterator sit_end = rSupCandGen.StatesEnd();
00424   for(; sit!=sit_end; ++sit) {
00425     if(!goodstates.Exists(*sit))
00426       rSupCandGen.DelState(*sit);
00427   }
00428 
00429   // return true
00430   FD_DF("OmegaClosedLoopLiveness(): done");
00431   return true;
00432 }
00433 
00434 
00435 // helper class
00436 class OPSState {
00437 public:
00438   // minimal interface
00439   OPSState() {};
00440   OPSState(const Idx& rq1, const Idx& rq2, const bool& rf) :
00441     q1(rq1), q2(rq2), m1required(rf) {};
00442   std::string Str(void) { return ToStringInteger(q1)+"|"+
00443       ToStringInteger(q2)+"|"+ToStringInteger(m1required); };
00444   // order
00445   bool operator < (const OPSState& other) const {
00446     if (q1 < other.q1) return(true);
00447     if (q1 > other.q1) return(false);
00448     if (q2 < other.q2) return(true);
00449     if (q2 > other.q2) return(false);
00450     if (m1required && !other.m1required) return(true);
00451     return(false);
00452   }
00453   // member variables
00454   Idx q1;
00455   Idx q2;
00456   bool m1required;
00457 };
00458 
00459 
00460 // OmegaSupconParallel(rPlantGen, rCAlph, rSpecGen, rReverseCompositionMap, rResGen)
00461 void OmegaSupconParallel(
00462   const vGenerator& rPlantGen, 
00463   const EventSet& rCAlph,
00464   const vGenerator& rSpecGen,
00465   std::map< OPSState , Idx>& rReverseCompositionMap, 
00466   StateSet& rMarkedPlantStates, 
00467   StateSet& rMarkedSpecStates, 
00468   vGenerator& rResGen) 
00469 {
00470   FD_DF("OmegaSupconParallel(" << &rPlantGen << "," << &rSpecGen << ")");
00471   
00472   // prepare result
00473   rResGen.Clear();
00474   rResGen.InjectAlphabet(rPlantGen.Alphabet());
00475 
00476   // trivial case
00477   if (rPlantGen.InitStatesEmpty()) {
00478     FD_DF("OmegaSupconParallel: plant got no initial states. "
00479             << "parallel composition contains empty language.");
00480     return;
00481   }
00482   if (rSpecGen.InitStatesEmpty()) {
00483     FD_DF("OmegaSupconParallel: spec got no initial states. "
00484               << "parallel composition contains empty language.");
00485     return;
00486   }
00487 
00488   // todo stack
00489   std::stack< OPSState > todo;
00490   // current pair, new pair
00491   OPSState currentstates, newstates;
00492   // state
00493   Idx tmpstate;  
00494   TransSet::Iterator ptit, ptit_end, stit, stit_end;
00495   std::map< OPSState, Idx>::iterator rcit;
00496   // critical states
00497   StateSet critical;
00498 
00499 
00500   // push initial state on todo stack
00501   currentstates = OPSState(*rPlantGen.InitStatesBegin(), *rSpecGen.InitStatesBegin(), true);
00502   todo.push(currentstates);
00503   tmpstate=rResGen.InsInitState();
00504   rReverseCompositionMap[currentstates] = tmpstate;
00505   if(rPlantGen.ExistsMarkedState(currentstates.q1)) 
00506     rMarkedPlantStates.Insert(tmpstate);
00507   if(rSpecGen.ExistsMarkedState(currentstates.q2)) 
00508     rMarkedSpecStates.Insert(tmpstate);
00509 
00510   // start algorithm
00511   FD_DF("OmegaSupconParallel: processing reachable states:");
00512   while(!todo.empty()) {
00513     // allow for user interrupt
00514     // LoopCallback();
00515     // allow for user interrupt, incl progress report
00516     FD_WPC(rReverseCompositionMap.size(),rReverseCompositionMap.size()+todo.size(),"OmegaSupconParallel(): processing"); 
00517     // get next reachable state from todo stack
00518     currentstates = todo.top();
00519     todo.pop();
00520     FD_DF("OmegaSupconParallel: processing (" << currentstates.Str() << " -> " 
00521     << rReverseCompositionMap[currentstates]<<")");
00522     // iterate over all rPlantGen and rSpecGen transitions 
00523     ptit = rPlantGen.TransRelBegin(currentstates.q1);
00524     ptit_end = rPlantGen.TransRelEnd(currentstates.q1);
00525     stit = rSpecGen.TransRelBegin(currentstates.q2);
00526     stit_end = rSpecGen.TransRelEnd(currentstates.q2);
00527     // process all transitions and increment iterators strategically
00528     while((ptit != ptit_end) && (stit != stit_end)) {
00529       FD_DF("OmegaSupconParallel: current plant-transition: " << rPlantGen.TStr(*ptit) );
00530       FD_DF("OmegaSupconParallel: current spec-transition: " << rSpecGen.TStr(*stit));
00531       // increment tit1 and tit2, case A: execute common event
00532       if(ptit->Ev == stit->Ev) {
00533   FD_DF("OmegaSupconParallel: executing common event "  << rPlantGen.EStr(ptit->Ev));
00534         newstates = OPSState(ptit->X2, stit->X2,currentstates.m1required);
00535         // track marking requirement
00536         if(currentstates.m1required) {
00537       if(rPlantGen.ExistsMarkedState(currentstates.q1))
00538       newstates.m1required=false;
00539         } else {
00540       if(rSpecGen.ExistsMarkedState(currentstates.q2)) { 
00541       newstates.m1required=true;
00542           }
00543         }
00544   rcit = rReverseCompositionMap.find(newstates);
00545   // if state is new: add to todo list and result
00546   if(rcit == rReverseCompositionMap.end()) {
00547           todo.push(newstates);
00548           tmpstate = rResGen.InsState();
00549           rReverseCompositionMap[newstates] = tmpstate;
00550           if(!newstates.m1required) 
00551           if(rSpecGen.ExistsMarkedState(newstates.q2)) 
00552             rResGen.SetMarkedState(tmpstate);                   
00553           if(rPlantGen.ExistsMarkedState(newstates.q1)) 
00554             rMarkedPlantStates.Insert(tmpstate);
00555           if(rSpecGen.ExistsMarkedState(newstates.q2)) 
00556             rMarkedSpecStates.Insert(tmpstate);
00557           FD_DF("OmegaSupconParallel:   todo push: (" << newstates.Str() << ") -> " 
00558               << rReverseCompositionMap[newstates]);
00559         } else {
00560           tmpstate = rcit->second;
00561         }
00562   // if successor state is not critical add transition and increment iterators
00563   if(!critical.Exists(tmpstate)) {
00564           rResGen.SetTransition(rReverseCompositionMap[currentstates], 
00565               ptit->Ev, tmpstate);
00566           FD_DF("OmegaSuperParallel:  add transition to new generator: " << 
00567     rResGen.TStr(Transition(rReverseCompositionMap[currentstates], ptit->Ev, tmpstate)));
00568           ++ptit;
00569           ++stit;
00570         }
00571   // if successor state is critical and event is uncontrollable then delete current state 
00572   else if(!rCAlph.Exists(ptit->Ev)) {
00573     FD_DF("OmegaSupconOmegaParallel: successor " << rSpecGen.SStr(tmpstate) 
00574            << "in critical and common event " << rSpecGen.EStr(stit->Ev) 
00575            << " uncontrollable:");
00576     FD_DF("OmegaSupconParallel: critical insert" << rPlantGen.SStr(tmpstate));
00577     critical.Insert(tmpstate);
00578 #ifdef FAUDES_CHECKED
00579     // do not end while loops here for detecting all h transitions 
00580     // not in spec
00581     FD_DF("OmegaSupconParallel: incrementing plant and spec transrel (FAUDES_CHECKED)");
00582     ++ptit;
00583     ++stit;
00584 #else
00585     // exit all loops
00586     ptit = ptit_end;
00587     stit = stit_end;
00588 #endif
00589         }
00590         // else if successor state is critical and event controllable increment iterators
00591         else {
00592     FD_DF("OmegaSupconParallel: incrementing plant and spec transrel");
00593           ++ptit;
00594           ++stit;
00595         }
00596       } // end: if processing common event 
00597       // increment iterators case B: process plant event that is not enebled for h
00598       else if (ptit->Ev < stit->Ev) {
00599   FD_DF("SupconParallel: asynchronous execution of event " 
00600      << rPlantGen.EStr(ptit->Ev) << " in plant while " << rSpecGen.EStr(stit->Ev) << " in spec");
00601   // if uncontrollable transition leaves specification
00602   // delete state from res and put into criticalset
00603   if (!rCAlph.Exists(ptit->Ev)) {
00604     FD_DF("OmegaSupconParallel: asynchronous event " << rPlantGen.EStr(ptit->Ev) 
00605        << " in g is uncontrollable");
00606     tmpstate = rReverseCompositionMap[currentstates]; 
00607     FD_DF("OmegaSupconParallel: critical insert" << rPlantGen.SStr(tmpstate));
00608     critical.Insert(tmpstate);
00609     // exit all loops
00610     ptit = ptit_end;
00611     stit = stit_end;
00612     break;
00613   }
00614   FD_DF("OmegaSupconParallel: incrementing plant transrel");
00615   ++ptit;
00616       } 
00617       // increment titg and titg, case C: process h event that is not enabled for g
00618       else {
00619   //#ifdef FAUDES_CHECKED
00620   // FD_WARN("SupconParallel:  transition " << rSpecGen.TStr(*tith) << " in specification h not found in g");
00621   //#endif
00622   FD_DF("OmegaSupconParallel: incrementing spec transrel");
00623   ++stit;
00624       }
00625     } // end while incrementing 
00626     // increment iterators case D: process leftover events of plant
00627     while (ptit != ptit_end) {
00628       FD_DF("OmegaSupconParallel: asynchronous execution of event " 
00629          << rPlantGen.EStr(ptit->Ev) << " in plant at end of spec");
00630       FD_DF("OmegaSupconParallel: curremt g-transition: " << rPlantGen.SStr(ptit->X1) 
00631          << "-" << rPlantGen.EStr(ptit->Ev) << "-" << rPlantGen.SStr(ptit->X2));
00632       FD_DF("OmegaSupconParallel: current h-transition: end");
00633       // if uncontrollable transition leaves specification
00634       if (!rCAlph.Exists(ptit->Ev)) {
00635   tmpstate = rReverseCompositionMap[currentstates];
00636   FD_DF("OmegaSupconParallel: asynchron executed uncontrollable end "
00637            << "event " << rPlantGen.EStr(ptit->Ev) << " leaves specification:");
00638   FD_DF("SupconParallel: critical insert" << rPlantGen.SStr(tmpstate));
00639   critical.Insert(tmpstate);
00640   // exit this loop 
00641   break;
00642       }
00643       FD_DF("OmegaSupconParallel: incrementing g transrel");
00644       ++ptit;
00645     }
00646   } // while todo
00647   FD_DF("OmegaSupconParallel: deleting critical states: " << critical.ToString());
00648   rResGen.DelStates(critical);
00649   rMarkedPlantStates.EraseSet(critical);
00650   rMarkedSpecStates.EraseSet(critical);
00651 
00652 }
00653 
00654 
00655 
00656 // OmegaSupConNBUnchecked(rPlantGen, rCAlph, rSpecGen, rReverseCompositionMap, rResGen)
00657 void OmegaSupConNBUnchecked(
00658   const vGenerator& rPlantGen,
00659   const EventSet& rCAlph,  
00660   const vGenerator& rSpecGen,
00661   std::map< OPSState , Idx>& rReverseCompositionMap, 
00662   vGenerator& rResGen) 
00663 {
00664   FD_DF("OmegaSupConNB(\"" <<  rPlantGen.Name() << "\", \"" << rSpecGen.Name() << "\")");
00665 
00666   // PREPARE RESULT:  
00667   vGenerator* pResGen = &rResGen;
00668   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00669     pResGen= rResGen.New();
00670   }
00671   pResGen->Clear();
00672   pResGen->Name(CollapsString("OmegaSupConNB(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"));
00673   pResGen->InjectAlphabet(rPlantGen.Alphabet());
00674 
00675   // controllable events
00676   FD_DF("OmegaSupConNB: controllable events: "   << rCAlph.ToString());
00677 
00678   // ALGORITHM:
00679   StateSet plantmarking;
00680   StateSet specmarking;
00681   OmegaSupconParallel(rPlantGen, rCAlph, rSpecGen, rReverseCompositionMap, plantmarking, specmarking, *pResGen);
00682 
00683 
00684 
00685   // fix statenames ...
00686   std::map< OPSState, Idx>::iterator rcit;
00687   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00688     Idx x1=rcit->first.q1;
00689     Idx x2=rcit->first.q2;
00690     bool m1requ=rcit->first.m1required;
00691     Idx x12=rcit->second;
00692     if(!pResGen->ExistsState(x12)) continue;
00693     std::string name1= rPlantGen.StateName(x1);
00694     if(name1=="") name1=ToStringInteger(x1);
00695     std::string name2= rSpecGen.StateName(x2);
00696     if(name2=="") name1=ToStringInteger(x2);
00697     std::string name12;
00698     if(m1requ) name12= name1 + "|" + name2 + "|r1m";
00699     else name12= name1 + "|" + name2 + "|r2m";
00700     name12=pResGen->UniqueStateName(name12);
00701     pResGen->StateName(x12,name12);
00702   }
00703 
00704 #ifdef FAUDES_DEBUG_FUNCTION
00705   pResGen->DWrite();
00706   pResGen->Write("tmp_syn_xxx_"+pResGen->Name()+".gen");
00707   pResGen->WriteStateSet(specmarking);
00708   pResGen->WriteStateSet(plantmarking);
00709 #endif
00710 
00711   // make resulting generator trim until it's fully controllable
00712   while (1) {
00713     if (pResGen->Empty()) {
00714       break;
00715     }
00716     Idx state_num = pResGen->Size();
00717     SupConUnchecked(rPlantGen, rCAlph, *pResGen);
00718     pResGen->Trim();
00719     pResGen->Complete();
00720     OmegaControlledLiveness(*pResGen,rCAlph,plantmarking,specmarking);
00721     if(pResGen->Size() == state_num) {
00722       break;
00723     }
00724   }
00725 
00726   // fix statenames ...
00727   //std::map< OPSState, Idx>::iterator rcit;
00728   if(rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && pResGen->StateNamesEnabled()) 
00729   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00730     Idx x1=rcit->first.q1;
00731     Idx x2=rcit->first.q2;
00732     bool m1requ=rcit->first.m1required;
00733     Idx x12=rcit->second;
00734     if(!pResGen->ExistsState(x12)) continue;
00735     std::string name1= rPlantGen.StateName(x1);
00736     if(name1=="") name1=ToStringInteger(x1);
00737     std::string name2= rSpecGen.StateName(x2);
00738     if(name2=="") name1=ToStringInteger(x2);
00739     std::string name12;
00740     if(m1requ) name12= name1 + "|" + name2 + "|r1m";
00741     else name12= name1 + "|" + name2 + "|r2m";
00742     name12=pResGen->UniqueStateName(name12);
00743     pResGen->StateName(x12,name12);
00744   }
00745 
00746   // .. or clear them (?)
00747   if(!(rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && pResGen->StateNamesEnabled())) 
00748     pResGen->ClearStateNames();
00749 
00750   // copy result
00751   if(pResGen != &rResGen) {
00752     pResGen->Move(rResGen);
00753     delete pResGen;
00754   }
00755 
00756 }
00757 
00758 
00759 /*
00760 ****************************************
00761 * SUPCON: WRAPPER / USER FUNCTIONS     *
00762 ****************************************
00763 */
00764 
00765 
00766 // OmegaSupConNB(rPlantGen, rCAlph, rSpecGen, rResGen)
00767 void OmegaSupConNB(
00768   const vGenerator& rPlantGen, 
00769   const EventSet& rCAlph, 
00770   const vGenerator& rSpecGen, 
00771   vGenerator& rResGen) 
00772 {
00773 
00774   // CONSISTENCY CHECK:
00775   ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSpecGen);
00776 
00777   // HELPERS:
00778   std::map< OPSState , Idx> rcmap;
00779 
00780   // ALGORITHM:
00781   OmegaSupConNBUnchecked(rPlantGen, rCAlph, rSpecGen, rcmap, rResGen);
00782 }
00783 
00784 
00785 
00786 
00787 
00788 // omega supcon for cGenerators:
00789 // uses and maintains controllablity from plant 
00790 void OmegaSupConNB(
00791   const cGenerator& rPlantGen, 
00792   const vGenerator& rSpecGen, 
00793   vGenerator& rResGen) {
00794 
00795   // prepare result
00796   vGenerator* pResGen = &rResGen;
00797   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00798     pResGen= rResGen.New();
00799   }
00800 
00801   // execute 
00802   OmegaSupConNB(rPlantGen, rPlantGen.ControllableEvents(),rSpecGen,*pResGen);
00803 
00804   // copy all attributes of input alphabet
00805   pResGen->EventAttributes(rPlantGen.Alphabet());
00806 
00807   // copy result
00808   if(pResGen != &rResGen) {
00809     pResGen->Move(rResGen);
00810     delete pResGen;
00811   }
00812 }
00813 
00814 
00815 } // name space 

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3