syn_supnorm.cpp

Go to the documentation of this file.
00001 /** @file syn_supnorm.cpp Supremal normal sublanguage */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2006  Bernd Opitz
00006    Exclusive copyright is granted to Klaus Schmidt
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2.1 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with this library; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00021    
00022 
00023 #include "syn_supnorm.h"
00024 #include "syn_supcon.h"
00025 
00026 
00027 namespace faudes {
00028 
00029 
00030 
00031 
00032 /*
00033 ***************************************************************************************
00034 ***************************************************************************************
00035  Implementation
00036 ***************************************************************************************
00037 ***************************************************************************************
00038 */
00039 
00040 
00041 //void NormalityConsistencyCheck(rL,rOAlph,rK) 
00042 void NormalityConsistencyCheck(
00043   const Generator& rL,
00044   const EventSet& rOAlph,
00045   const Generator& rK) {
00046   
00047   FD_DF("NormalityConsistencyCheck(...)");
00048   
00049   if (!(rK.IsDeterministic())) {
00050    std::stringstream errstr;
00051      errstr << "Nondeterministic parameter rK.";
00052    if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL.";
00053      throw Exception("NormalityConsistencyCheck", errstr.str(), 101);
00054   }
00055   if (!(rL.IsDeterministic())) {
00056    std::stringstream errstr;
00057    errstr << "Nondeterministic parameter rL.";
00058    if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL.";
00059    throw Exception("NormalityConsistencyCheck", errstr.str(), 101);
00060     }
00061   
00062   EventSet Kevents,Sigma;
00063   Sigma=rL.Alphabet();
00064   Kevents=rK.Alphabet();
00065   
00066   // observable events have to be subset of Sigma
00067   if(!(rOAlph<=Sigma)) {
00068     EventSet only_in_OAlph = rOAlph - Sigma;
00069     std::stringstream errstr;
00070     errstr << "Not all observable events are contained in Sigma: " 
00071        << only_in_OAlph.ToString() << ".";
00072     throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
00073   } 
00074    
00075   // alphabets must match  
00076   if ( Sigma != Kevents) {
00077     EventSet only_in_L = Sigma - Kevents;
00078     EventSet only_in_K = Kevents - Sigma;
00079     only_in_L.Name("Only_In_L");
00080     only_in_L.Name("Only_In_K");
00081     std::stringstream errstr;
00082     errstr << "Alphabets of generators do not match.";
00083     if(!only_in_L.Empty())
00084       errstr <<  " " << only_in_L.ToString() << ".";
00085     if(!only_in_K.Empty())
00086       errstr <<  " " << only_in_K.ToString() << ".";
00087     throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
00088   }
00089   
00090   // K must be subset of L
00091   if (!LanguageInclusion(rK,rL)) {
00092     std::stringstream errstr;
00093     errstr << "K is not subset of L.";
00094     throw Exception("NormalityConsistencyCheck", errstr.str(), 0);
00095   }
00096 }
00097 
00098 // IsNormal(rK,rL,rOAlph)
00099 bool IsNormal(
00100   const Generator& rL,
00101   const EventSet& rOAlph,
00102   const Generator& rK) 
00103 {
00104   FD_DF("IsNormal(...)");
00105 
00106   // bail out on empty K
00107   // note: this is required to survive the
00108   // determinism test when rK has no states at all
00109   if(IsEmptyLanguage(rK)) return true;
00110   
00111   // determinism required
00112   NormalityConsistencyCheck(rL,rOAlph,rK);
00113   
00114   //extract overall alphabet:
00115   EventSet Sigma;
00116   Sigma=rL.Alphabet();
00117   
00118   //extract alphabet of rK:
00119   EventSet Kevents;
00120   Kevents=rK.Alphabet();
00121   
00122   //calculate p(K)
00123   Generator Ktest1, Ktest2;
00124   Ktest1.StateNamesEnabled(false);
00125   Ktest2.StateNamesEnabled(false);
00126   Project(rK,rOAlph,Ktest1);
00127   
00128   //calculate pinv(p(K))
00129   InvProject(Ktest1, Sigma);
00130   
00131   //check normality: pinv(p(K)) intersect L = K?
00132   LanguageIntersection(Ktest1,rL,Ktest2);
00133   return LanguageInclusion(Ktest2,rK);
00134   
00135   // Remark: testing for LanguageEquality is not required, as inclusion
00136   // in the reverse direction is always met (assuming K\subseteq L)
00137 }
00138 
00139 
00140 
00141 // IsNormal rti wrapper
00142 bool IsNormal(const System& rPlantGen, const Generator& rSupCandGen) {
00143   return IsNormal(rPlantGen, rPlantGen.ObservableEvents(),rSupCandGen);
00144 }
00145 
00146 
00147 // ConcatenateFullLanguage(rGen)
00148 void ConcatenateFullLanguage(Generator& rGen) {
00149   FD_DF("ConcatenateFullLanguage(" << rGen.Name() << ")");
00150   
00151   // prepare result
00152   rGen.Name("ConcatenateFullLanguage(" + rGen.Name() + ")");
00153   
00154   // treat trivial empty result in case of empty marked language
00155   if(rGen.MarkedStatesSize()==0) {
00156     rGen.Clear();
00157     return;
00158   }
00159   
00160   // helpers
00161   EventSet alph=rGen.Alphabet();
00162   StateSet StatesToClear;
00163   TransSet TransToClear,TransToSet;
00164   StateSet::Iterator sit;
00165   TransSet::Iterator tit;
00166   EventSet::Iterator evit;
00167   
00168   // clear all transitions in marked states
00169   for (sit = rGen.MarkedStatesBegin(); sit != rGen.MarkedStatesEnd(); ++sit) {
00170       for (tit = rGen.TransRelBegin(*sit); tit != rGen.TransRelEnd(*sit); ++tit) {
00171           TransToClear.Insert(*tit);
00172       }
00173   }
00174   
00175   for (tit = TransToClear.Begin(); tit != TransToClear.End(); ++tit) {
00176       rGen.ClrTransition(*tit);
00177   }
00178   TransToClear.Clear();
00179   rGen.Accessible();
00180   
00181   // all marked states become eqivalent -> switch transitions leading to marked states to one remaining marked state
00182   // and delete all the others; note: for this special purpose, this procedure is faster than running StateMin.
00183   // if an init state is marked the effort is even less (as the result is Sigma* itself, see "else" below)
00184   bool initmarked = !( (rGen.InitStates() * rGen.MarkedStates()).Empty() );
00185   if (!initmarked) {
00186     // define remaining marked state (there is one because of nonzero MarkedStatesSize)
00187     sit = rGen.MarkedStatesBegin();
00188     Idx marked = *sit;
00189     // switch transitions to all other marked states if there are any
00190     if(rGen.MarkedStatesSize()>1) {
00191       // extract transitions sorted by target state X2
00192       TransSetX2EvX1 trel;
00193       rGen.TransRel(trel);
00194       TransSetX2EvX1::Iterator tit2;
00195       
00196       // switch transitions to all other marked states to the one remaining marked state
00197       ++sit;
00198       for (; sit != rGen.MarkedStatesEnd(); ++sit) {
00199           for (tit2 = trel.BeginByX2(*sit); tit2 != trel.EndByX2(*sit); ++tit2) {
00200           // switch transition target to remaining marked state
00201           TransToSet.Insert(tit2->X1,tit2->Ev,marked);
00202           // note: original transitions are cleared later with clearing the corresp. marked states.
00203           }
00204       }
00205       
00206       // delete all but remaining marked state (note: by doing so, also corresp. transitions are cleared.)
00207       sit = rGen.MarkedStatesBegin();
00208       ++sit;
00209       for (; sit != rGen.MarkedStatesEnd(); ++sit) {
00210       StatesToClear.Insert(*sit);
00211       }
00212       for (sit=StatesToClear.Begin(); sit != StatesToClear.End(); ++sit) {
00213       rGen.DelState(*sit);
00214       }
00215       StatesToClear.Clear();
00216       
00217       // insert switched transitions
00218       for (tit = TransToSet.Begin(); tit != TransToSet.End(); ++tit) {
00219           rGen.SetTransition(*tit);
00220       }
00221       TransToSet.Clear();
00222       }
00223 
00224     // now concatenate Sigma* by selflooping marked state with all events
00225     for (evit = alph.Begin(); evit != alph.End(); ++evit) {
00226       rGen.SetTransition(marked,*evit,marked);
00227     }
00228     
00229   }
00230   // consider marked init state case
00231   else {
00232                 FD_DF("ConcatenateFullLanguage(" << rGen.Name() << "): marked initial state");
00233     // reduce to empty string language
00234     rGen.ClearStates();
00235     rGen.ClearTransRel();
00236     Idx state=rGen.InsInitState();
00237     rGen.SetMarkedState(state);
00238     // now concatenate Sigma* by selflooping marked state with all events
00239     for (evit = alph.Begin(); evit != alph.End(); ++evit) {
00240       rGen.SetTransition(state,*evit,state);
00241     }
00242     
00243     }
00244   
00245   return;
00246 }
00247 
00248 
00249 //  SupNorm(rL,rOAlph,rK,rResult)
00250 bool SupNorm(
00251   const Generator& rL,
00252   const EventSet& rOAlph,
00253   const Generator& rK, 
00254   Generator& rResult)
00255 {
00256   FD_DF("SupNorm(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
00257   
00258   // exceprions
00259   NormalityConsistencyCheck(rL,rOAlph,rK);
00260   
00261   //extract overall alphabet:
00262   EventSet allevents;
00263   allevents=rL.Alphabet();
00264       
00265   // involved operations from cfl_regular.h operate on the marked
00266   // languages -> turn generated languages into marked langusges
00267   Generator prL=rL;
00268   prL.InjectMarkedStates(rL.States());
00269   Generator prK=rK;
00270   prK.InjectMarkedStates(prK.States());
00271   
00272   // calculate "L-K" 
00273   LanguageDifference(prL,prK,rResult);
00274   
00275   // calculate Pinv(P(L-K)):
00276   Project(rResult,rOAlph,rResult);
00277   FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size());
00278   InvProject(rResult,allevents);
00279   FD_DF("SupNorm: sizeof pinv(p(L-K)): "<< rResult.Size());
00280 
00281   //calculate remaining set difference -> supnorm(K)
00282   LanguageDifference(prK,rResult,rResult);
00283   
00284   // cosmetics: remove blocking states
00285   rResult.Trim();
00286    
00287   // done
00288   rResult.Name("SupNorm("+rL.Name()+", "+rK.Name()+")");  
00289   return !( rResult.InitStatesEmpty() );
00290 }
00291 
00292 //  SupNormClosed(rL,rOAlph,rK,rResult)
00293 bool SupNormClosed(
00294   const Generator& rL,
00295   const EventSet& rOAlph,
00296   const Generator& rK, 
00297   Generator& rResult)
00298 {
00299   FD_DF("SupNormClosed(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
00300   
00301   // involved operations from regular.h operate on the marked
00302   // languages -> turn generated languages into marked langs
00303   Generator prL=rL;
00304   prL.InjectMarkedStates(prL.States());
00305   Generator prK=rK;
00306   prK.InjectMarkedStates(prK.States());
00307 
00308   // concitency check on closed languages
00309   NormalityConsistencyCheck(prL,rOAlph,prK);
00310   
00311   //extract overall alphabet:
00312   EventSet allevents;
00313   allevents=rL.Alphabet();
00314   
00315   // calculate "L-K" 
00316   LanguageDifference(prL,prK,rResult);
00317 
00318   // calculate Pinv(P(L-K)):
00319   Project(rResult,rOAlph,rResult);
00320   FD_DF("SupNormClosed: sizeof p(L-K): "<< rResult.Size());
00321   InvProject(rResult,allevents);
00322   FD_DF("SupNormClosed: sizeof pinv(p(L-K)): "<< rResult.Size());
00323   
00324   //concatenate Pinv(P(L-K)) with Sigma*: this leads to closed result
00325   ConcatenateFullLanguage(rResult); // special function for efficient concatenation of Sigma*.
00326   
00327   FD_DF("SupNormClosed: sizeof pinv(p(L-K))Sigma*: "<< rResult.Size());
00328 
00329   //calculate remaining set difference -> supnormClosed(K)
00330   LanguageDifference(prK,rResult,rResult);
00331 
00332   // cosmetics: remove blocking states
00333   rResult.Trim();
00334 
00335   // done
00336   rResult.Name("SupNormClosed("+rL.Name()+", "+rK.Name()+")"); 
00337   return !( rResult.InitStatesEmpty() );
00338 }
00339 
00340 
00341 //  SupConNormClosed(rL,rCAlph,rOAlph,rK,rResult)
00342 void SupConNormClosed(
00343   const Generator& rL,
00344   const EventSet& rCAlph,
00345   const EventSet& rOAlph,
00346   const Generator& rK, 
00347   Generator& rResult)
00348 {
00349   FD_DF("SupConNormClosed(" << rL.Name() << "," << rK.Name() << ")");
00350   // determinism required
00351   ControlProblemConsistencyCheck(rL,rCAlph,rOAlph,rK);
00352   // 0.: intersect K with L to match requirements of SupNormClosed
00353   Generator K;
00354   K.StateNamesEnabled(false);
00355   Product(rL,rK,K);
00356   // 1. normal and closed sublanguage (operates on / returns generated language)
00357   Generator N;
00358   N.StateNamesEnabled(false);
00359   SupNormClosed(rL,rOAlph,K,N);
00360   // 2. project to sigma_o (generated languages)
00361   Generator N0,L0;
00362   N0.StateNamesEnabled(false);
00363   L0.StateNamesEnabled(false);
00364   Project(N,rOAlph,N0);
00365   Project(rL,rOAlph,L0);
00366   // 3. supremal controllable sublanguage (generated languages)
00367   EventSet sig_co = rCAlph * rOAlph;
00368   Generator K0;
00369   K0.StateNamesEnabled(false);
00370   SupConClosed(L0,sig_co,N0,K0);
00371   // 4. inverese project to sigma  (on generated language)
00372   InvProject(K0,rL.Alphabet());
00373   // 5. intersect with L (generated languages)
00374   LanguageIntersection(K0,rL,rResult);
00375   // convenience: mark the generated language
00376   rResult.InjectMarkedStates(rResult.States());
00377 }  
00378 
00379 
00380 //  SupConNormNB(rL,rCAlph,rOAlph,rK,rResult)
00381 void SupConNormNB(
00382   const Generator& rL,
00383   const EventSet& rCAlph,
00384   const EventSet& rOAlph,
00385   const Generator& rK, 
00386   Generator& rResult)
00387 {
00388   FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << ")");
00389   // determinism required
00390   ControlProblemConsistencyCheck(rL,rCAlph,rOAlph,rK);
00391   // initialize: K0
00392   Generator K0;
00393   K0.StateNamesEnabled(false);
00394   Product(rL,rK,K0);
00395   K0.Coaccessible();
00396   // initialize: closure(rL)
00397   Generator L=rL;
00398   L.StateNamesEnabled(false);
00399   L.Trim();
00400   L.InjectMarkedStates(L.States());
00401   // loop
00402   Generator Ki=K0;
00403   Ki.StateNamesEnabled(false);
00404   while(1) {
00405     FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << "): #" << Ki.Size() << " m#" << Ki.MarkedStatesSize());
00406     // keep copy of recent
00407     rResult=Ki;
00408     // cheep closure (for coreachable generator)
00409     Ki.InjectMarkedStates(Ki.States());
00410     // synthesise closed
00411     SupConNormClosed(L,rCAlph,rOAlph,Ki,Ki);
00412     // restrict
00413     Product(K0,Ki,Ki);
00414     Ki.Coaccessible();
00415     // test (sequence is decreasing anyway)
00416     if(LanguageInclusion(rResult,Ki)) break;
00417   }  
00418   FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << "): done");
00419 }  
00420 
00421 
00422 // SupPrefixClosed(rK,rResult)
00423 bool SupPrefixClosed(
00424   const Generator& rK,
00425   Generator& rResult) 
00426 {
00427   
00428   FD_DF("SupPrefixClosed("<<rK.Name()<<")");
00429   
00430   // prepare Result:
00431   rResult.Name("SupPrefixClosed("+rK.Name()+")");
00432   
00433   // check for marked initial state, empty result if not
00434   if( (rK.InitStates() * rK.MarkedStates()).Empty() ) {
00435     rResult.Clear();
00436     return false;
00437   }
00438 
00439   rResult.Assign(rK);  
00440   
00441   // erase all transitions not leading to a marked state
00442   // todo: Depth-first-search could be faster
00443   TransSet::Iterator tit=rResult.TransRelBegin();
00444   TransSet::Iterator tit_end=rResult.TransRelEnd();
00445   while(tit!=tit_end) {
00446     if(rResult.ExistsMarkedState(tit->X2)) { ++tit; continue;}
00447     rResult.ClrTransition(tit++);
00448   }
00449 
00450   // make reachable (cosmetic)
00451   rResult.Trim();
00452   
00453   // as there is at least one marked init state, result is nonempty
00454   return true;
00455 }
00456 
00457 
00458 // helper class
00459 class SNOState {
00460 public:
00461   // minimal interface
00462   SNOState() {};
00463   SNOState(const Idx& rq, const Idx& rx, const bool& rz) :
00464     q(rq), x(rx), z(rz) {};
00465   std::string Str(void) { return ToStringInteger(q)+"|"+
00466       ToStringInteger(x)+"|"+ToStringInteger(z); };
00467   // order
00468   bool operator < (const SNOState& other) const {
00469     if (q < other.q) return(true);
00470     if (q > other.q) return(false);
00471     if (x < other.x) return(true);
00472     if (x > other.x) return(false);
00473     if (z < other.z) return(true);
00474     return(false);
00475   }
00476   // member variables
00477   Idx q;
00478   Idx x;
00479   Idx z;
00480 };
00481 
00482 
00483 // SupConNormClosedUnchecked(rPlantGen, rCAlph, rObserverGen, rSupCandGen)
00484 void SupConNormClosedUnchecked(
00485   const Generator& rPlantGen,  // aka G
00486   const EventSet& rCAlph,  
00487   const EventSet& rOAlph,  
00488   Generator& rObserverGen,     // aka Hobs
00489   Generator& rSupCandGen       // aka H
00490 ) 
00491 {
00492   FD_DF("SupConNormClosedUnchecked(" << &rSupCandGen << "," << &rPlantGen << ")");
00493 
00494   // bail out on L(G)=0 --> closed-lopp language inclusion trivialy satisfied 
00495   if(rPlantGen.InitStatesEmpty()) return;
00496 
00497   // debugging: compare result with Lin-Brandt fromula at end of function
00498   // Generator K;
00499   // SupConNormClosed(rPlantGen, rCAlph, rOAlph, rSupCandGen, K);
00500  
00501   // loop until fixpoint
00502   while(true) {
00503     FD_DF("SupConNormClosedUnchecked(" << &rSupCandGen << "," << &rPlantGen << "): until fixpoint #" << rSupCandGen.Size());
00504 
00505     // record size to break loop
00506     Idx ssz = rSupCandGen.TransRelSize();
00507     Idx osz = rObserverGen.TransRelSize();
00508 
00509     // bail out if L(H)-0 --> closed-loop language fixpoint
00510     if(rSupCandGen.InitStatesEmpty()) break;
00511 
00512     // todo stack (state triplets)
00513     std::stack<SNOState> todo; 
00514     // relevant H states
00515     StateSet processed, critical;
00516 
00517     // various iterators
00518     TransSet::Iterator titg, titg_end;
00519     TransSet::Iterator tith, tith_end;
00520     TransSet::Iterator titho, titho_end;
00521 
00522     // current and successsor state
00523     SNOState current, successor;
00524 
00525     // push combined initial state on todo stack
00526     FD_DF("SupNorm: todo push initial state");
00527     current.q = *rPlantGen.InitStatesBegin();
00528     current.x = *rSupCandGen.InitStatesBegin();
00529     current.z = *rObserverGen.InitStatesBegin();
00530     todo.push(current);
00531 
00532     // process todo stack
00533     while(!todo.empty()) {
00534       // allow for user interrupt, incl progress report
00535       FD_WPC(1,2,"Normality(): iterating states"); 
00536       // get top element from todo stack
00537       current = todo.top();
00538       todo.pop();
00539       FD_DF("SupNorm: todo #" << todo.size() << " processed #" << processed.Size());
00540       FD_DF("SupNorm: pop: (" << rPlantGen.SStr(current.q) << "|" << rSupCandGen.SStr(current.x) << ")");
00541 
00542       // break cycles 
00543       if(processed.Exists(current.x)) continue;
00544       if(critical.Exists(current.x)) continue;
00545 
00546       // record processed
00547       processed.Insert(current.x);
00548 
00549       // figure events disbabled by candidate H w.r.t plant G
00550       EventSet disabled = rPlantGen.ActiveEventSet(current.q) - rSupCandGen.ActiveEventSet(current.x);
00551 
00552       // if an unobservabel event is disabled, current state becomes critical
00553       if(!(disabled <= rCAlph)) {
00554         critical.Insert(current.x);
00555         continue;
00556       }
00557   
00558       // disable respective transition in observer Hobs
00559       titho = rObserverGen.TransRelBegin(current.z);
00560       titho_end = rObserverGen.TransRelEnd(current.z);
00561       while(titho!=titho_end) {
00562         if(!disabled.Exists(titho->Ev)) { ++titho; continue; }
00563         rObserverGen.ClrTransition(titho++);
00564       }
00565 
00566       // find successor states to push on stack
00567       titg = rPlantGen.TransRelBegin(current.q);
00568       titg_end = rPlantGen.TransRelEnd(current.q);
00569       tith = rSupCandGen.TransRelBegin(current.x);
00570       tith_end = rSupCandGen.TransRelEnd(current.x);
00571       titho = rObserverGen.TransRelBegin(current.z);
00572       titho_end = rObserverGen.TransRelEnd(current.z);
00573       while( (titg != titg_end) && (tith != tith_end) && (titho != titho_end) ) {
00574         FD_DF("SupNorm: processing g-transition: " << rPlantGen.TStr(*titg)); 
00575         FD_DF("SupNorm: processing h-transition: " << rSupCandGen.TStr(*tith));
00576         // increment case A: process common events
00577         if( (titg->Ev == tith->Ev) && (tith->Ev == titho->Ev) )   {
00578         FD_DF("SupNorm: processing common event " << rPlantGen.EStr(titg->Ev));
00579           // push successor
00580           if(!processed.Exists(tith->X2)) {
00581             successor.q=titg->X2;
00582             successor.x=tith->X2;
00583             successor.z=titho->X2;
00584             todo.push(successor);
00585     }
00586     // increment
00587       ++titg; ++tith; ++titho;
00588         }
00589         // increment case B: increment H transitions for events disabled by Hobs (when we disabled events in Hobs)
00590         else if (tith->Ev < titho->Ev) {
00591           rSupCandGen.ClrTransition(tith++);
00592         }
00593         // increment case C: increment Hobs transitions for events disabled by H (for removed critical states))
00594         else if (titho->Ev < tith->Ev) {
00595     ++titho;
00596         }
00597         // increment case D: increment G transitions for events disabled by H
00598         else if (titg->Ev < tith->Ev) {
00599     ++titg;
00600         }
00601         // increment case E: increment Hobs transitions for events disabled by G
00602         else {
00603           ++titho;
00604         }
00605       } // end accessible states
00606       // reasoning for leftovers:
00607       // a) if tith==end then we dont need to restrict H by Hobs anymore
00608       // b) if titg=end then (by L subseteq K) we have tith=end, and we argue as in a)
00609       // c) if titho=end then we need to restrict H by Hobs ...
00610       while( (tith != tith_end) ) {
00611         // increment case B: increment H transitions for events disabled by Hobs (when we disabled events in Hobs)
00612         rSupCandGen.ClrTransition(tith++);
00613       }
00614   
00615     } // end: todo stack
00616 
00617     // remove critical
00618     //rSupCandGen.DelStates((rSupCandGen.States()-processed) + critical);
00619     rSupCandGen.DelStates(critical);
00620   
00621     // break on fixpoint
00622     if(ssz != rSupCandGen.TransRelSize()) continue;
00623     if(osz != rObserverGen.TransRelSize()) continue;
00624     break;
00625       
00626   } //end: until fixpoint
00627 
00628   // cosmetic
00629   rSupCandGen.Accessible();
00630 
00631   /*
00632   // debugging: compare with Lin-Brandt formula
00633   Generator Rpr = rSupCandGen;
00634   MarkAllStates(Rpr);
00635   if(!LanguageEquality(K,Rpr)) FD_WARN("SUPNORM ERROR??? Supremal?");
00636   */
00637 
00638 }
00639 
00640 
00641 
00642 /** rti wrapper */
00643 void SupNorm(
00644   const System& rPlantGen, 
00645   const Generator& rSpecGen, 
00646   Generator& rResGen) 
00647 {
00648   // prepare result
00649   Generator* pResGen = &rResGen;
00650   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00651     pResGen= rResGen.New();
00652   }
00653   // execute
00654   SupNorm(rPlantGen,rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
00655   // copy all attributes of input alphabet
00656   pResGen->EventAttributes(rPlantGen.Alphabet());
00657   // copy result
00658   if(pResGen != &rResGen) {
00659     pResGen->Move(rResGen);
00660     delete pResGen;
00661   }
00662 }
00663 
00664 /** rti wrapper */
00665 void SupNormClosed(
00666   const System& rPlantGen, 
00667   const Generator& rSpecGen, 
00668   Generator& rResGen) 
00669 {
00670   // prepare result
00671   Generator* pResGen = &rResGen;
00672   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00673     pResGen= rResGen.New();
00674   }
00675   // execute
00676   SupNormClosed(rPlantGen,rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
00677   // copy all attributes of input alphabet
00678   pResGen->EventAttributes(rPlantGen.Alphabet());
00679   // copy result
00680   if(pResGen != &rResGen) {
00681     pResGen->Move(rResGen);
00682     delete pResGen;
00683   }
00684 }
00685 
00686 
00687 /** rti wrapper */
00688 void SupConNormClosed(
00689   const System& rPlantGen, 
00690   const Generator& rSpecGen, 
00691   Generator& rResGen) 
00692 {
00693   // prepare result
00694   Generator* pResGen = &rResGen;
00695   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00696     pResGen= rResGen.New();
00697   }
00698   // execute
00699   SupConNormClosed(rPlantGen,rPlantGen.ControllableEvents(),rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
00700   // copy all attributes of input alphabet
00701   pResGen->EventAttributes(rPlantGen.Alphabet());
00702   // copy result
00703   if(pResGen != &rResGen) {
00704     pResGen->Move(rResGen);
00705     delete pResGen;
00706   }
00707 }
00708 
00709 /** rti wrapper */
00710 void SupConNormNB(
00711   const System& rPlantGen, 
00712   const Generator& rSpecGen, 
00713   Generator& rResGen) 
00714 {
00715   FD_DF("SupConNormNB(" << rPlantGen.Name() << "," << rSpecGen.Name() << "): rti wrapper");
00716   // prepare result
00717   Generator* pResGen = &rResGen;
00718   if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
00719     pResGen= rResGen.New();
00720   }
00721   // execute
00722   SupConNormNB(rPlantGen,rPlantGen.ControllableEvents(),rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
00723   // copy all attributes of input alphabet
00724   pResGen->EventAttributes(rPlantGen.Alphabet());
00725   // copy result
00726   if(pResGen != &rResGen) {
00727     pResGen->Move(rResGen);
00728     delete pResGen;
00729   }
00730 }
00731 
00732 } // end namespace

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen