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

Sections

Index

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 
00025 
00026 namespace faudes {
00027 
00028 
00029 
00030 
00031 /*
00032 ***************************************************************************************
00033 ***************************************************************************************
00034  Implementation
00035 ***************************************************************************************
00036 ***************************************************************************************
00037 */
00038 
00039 
00040 //void NormalityConsistencyCheck(rL,rOAlph,rK) 
00041 void NormalityConsistencyCheck(
00042   const Generator& rL,
00043   const EventSet& rOAlph,
00044   const Generator& rK) {
00045   
00046   FD_DF("NormalityConsistencyCheck(...)");
00047   
00048   if (!(rK.IsDeterministic())) {
00049    std::stringstream errstr;
00050      errstr << "Nondeterministic parameter rK.";
00051    if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL.";
00052      throw Exception("NormalityConsistencyCheck", errstr.str(), 101);
00053   }
00054   if (!(rL.IsDeterministic())) {
00055    std::stringstream errstr;
00056    errstr << "Nondeterministic parameter rL.";
00057    if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL.";
00058    throw Exception("NormalityConsistencyCheck", errstr.str(), 101);
00059     }
00060   
00061   EventSet Kevents,Sigma;
00062   Sigma=rL.Alphabet();
00063   Kevents=rK.Alphabet();
00064   
00065   // observable events have to be subset of Sigma
00066   if(!(rOAlph<=Sigma)) {
00067     EventSet only_in_OAlph = rOAlph - Sigma;
00068     std::stringstream errstr;
00069     errstr << "Not all observable events are contained in Sigma: " 
00070        << only_in_OAlph.ToString() << ".";
00071     throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
00072   } 
00073    
00074   // alphabets must match  
00075   if ( Sigma != Kevents) {
00076     EventSet only_in_L = Sigma - Kevents;
00077     EventSet only_in_K = Kevents - Sigma;
00078     only_in_L.Name("Only_In_L");
00079     only_in_L.Name("Only_In_K");
00080     std::stringstream errstr;
00081     errstr << "Alphabets of generators do not match.";
00082     if(!only_in_L.Empty())
00083       errstr <<  " " << only_in_L.ToString() << ".";
00084     if(!only_in_K.Empty())
00085       errstr <<  " " << only_in_K.ToString() << ".";
00086     throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
00087   }
00088   
00089   // K must be subset of L
00090   if (!LanguageInclusion(rK,rL)) {
00091     std::stringstream errstr;
00092     errstr << "K is not subset of L.";
00093     throw Exception("NormalityConsistencyCheck", errstr.str(), 0);
00094   }
00095 }
00096 
00097 // IsNormal(rK,rL,rOAlph)
00098 bool IsNormal(
00099   const Generator& rL,
00100   const EventSet& rOAlph,
00101   const Generator& rK) 
00102 {
00103   FD_DF("IsNormal(...)");
00104 
00105   // bail out on empty K
00106   // note: this is required to survive the
00107   // determinism test when rK has no states at all
00108   if(IsEmptyLanguage(rK)) return true;
00109   
00110   // determinism required
00111   NormalityConsistencyCheck(rL,rOAlph,rK);
00112   
00113   //extract overall alphabet:
00114   EventSet Sigma;
00115   Sigma=rL.Alphabet();
00116   
00117   //extract alphabet of rK:
00118   EventSet Kevents;
00119   Kevents=rK.Alphabet();
00120   
00121   //calculate p(K)
00122   Generator Ktest1, Ktest2;
00123   Project(rK,rOAlph,Ktest1);
00124   
00125   //calculate pinv(p(K))
00126   InvProject(Ktest1, Sigma);
00127   
00128   //check normality: pinv(p(K)) intersect L = K?
00129   LanguageIntersection(Ktest1,rL,Ktest2);
00130   return LanguageInclusion(Ktest2,rK);
00131   
00132   // Remark: testing for LanguageEquality is not required, as inclusion
00133   // in the reverse direction is always met.
00134 }
00135 
00136 
00137 
00138 // IsNormal rti wrapper
00139 bool IsNormal(const System& rPlantGen, const Generator& rSupCandGen) {
00140   return IsNormal(rPlantGen, rPlantGen.ObservableEvents(),rSupCandGen);
00141 }
00142 
00143 
00144 // ConcatenateFullLanguage(rGen)
00145 void ConcatenateFullLanguage(Generator& rGen) {
00146   FD_DF("ConcatenateFullLanguage(" << rGen.Name() << ")");
00147   
00148   // prepare result
00149   rGen.Name("ConcatenateFullLanguage(" + rGen.Name() + ")");
00150   
00151   // treat trivial empty result in case of empty marked language
00152   if(rGen.MarkedStatesSize()==0) {
00153     rGen.Clear();
00154     return;
00155   }
00156   
00157   // helpers
00158   EventSet alph=rGen.Alphabet();
00159   StateSet StatesToClear;
00160   TransSet TransToClear,TransToSet;
00161   StateSet::Iterator sit;
00162   TransSet::Iterator tit;
00163   EventSet::Iterator evit;
00164   
00165   // clear all transitions in marked states
00166   for (sit = rGen.MarkedStatesBegin(); sit != rGen.MarkedStatesEnd(); ++sit) {
00167       for (tit = rGen.TransRelBegin(*sit); tit != rGen.TransRelEnd(*sit); ++tit) {
00168           TransToClear.Insert(*tit);
00169       }
00170   }
00171   
00172   for (tit = TransToClear.Begin(); tit != TransToClear.End(); ++tit) {
00173       rGen.ClrTransition(*tit);
00174   }
00175   TransToClear.Clear();
00176   rGen.Accessible();
00177   
00178   // all marked states become eqivalent -> switch transitions leading to marked states to one remaining marked state
00179   // and delete all the others; note: for this special purpose, this procedure is faster than running StateMin.
00180   // if an init state is marked the effort is even less (as the result is Sigma* itself, see "else" below)
00181   bool initmarked = !( (rGen.InitStates() * rGen.MarkedStates()).Empty() );
00182   if (!initmarked) {
00183     // define remaining marked state (there is one because of nonzero MarkedStatesSize)
00184     sit = rGen.MarkedStatesBegin();
00185     Idx marked = *sit;
00186     // switch transitions to all other marked states if there are any
00187     if(rGen.MarkedStatesSize()>1) {
00188       // extract transitions sorted by target state X2
00189       TransSetX2EvX1 trel;
00190       rGen.TransRel(trel);
00191       TransSetX2EvX1::Iterator tit2;
00192       
00193       // switch transitions to all other marked states to the one remaining marked state
00194       ++sit;
00195       for (; sit != rGen.MarkedStatesEnd(); ++sit) {
00196           for (tit2 = trel.BeginByX2(*sit); tit2 != trel.EndByX2(*sit); ++tit2) {
00197           // switch transition target to remaining marked state
00198           TransToSet.Insert(tit2->X1,tit2->Ev,marked);
00199           // note: original transitions are cleared later with clearing the corresp. marked states.
00200           }
00201       }
00202       
00203       // delete all but remaining marked state (note: by doing so, also corresp. transitions are cleared.)
00204       sit = rGen.MarkedStatesBegin();
00205       ++sit;
00206       for (; sit != rGen.MarkedStatesEnd(); ++sit) {
00207       StatesToClear.Insert(*sit);
00208       }
00209       for (sit=StatesToClear.Begin(); sit != StatesToClear.End(); ++sit) {
00210       rGen.DelState(*sit);
00211       }
00212       StatesToClear.Clear();
00213       
00214       // insert switched transitions
00215       for (tit = TransToSet.Begin(); tit != TransToSet.End(); ++tit) {
00216           rGen.SetTransition(*tit);
00217       }
00218       TransToSet.Clear();
00219       }
00220 
00221     // now concatenate Sigma* by selflooping marked state with all events
00222     for (evit = alph.Begin(); evit != alph.End(); ++evit) {
00223       rGen.SetTransition(marked,*evit,marked);
00224     }
00225     
00226   }
00227   // consider marked init state case
00228   else {
00229     // reduce to empty string language
00230     rGen.ClearStates();
00231     rGen.ClearTransRel();
00232     Idx state=rGen.InsInitState();
00233     rGen.SetMarkedState(state);
00234     // now concatenate Sigma* by selflooping marked state with all events
00235     for (evit = alph.Begin(); evit != alph.End(); ++evit) {
00236       rGen.SetTransition(state,*evit,state);
00237     }
00238     
00239     }
00240   
00241   return;
00242 }
00243 
00244 
00245 //  SupNorm(rL,rOAlph,rK,rResult)
00246 bool SupNorm(
00247   const Generator& rL,
00248   const EventSet& rOAlph,
00249   const Generator& rK, 
00250   Generator& rResult)
00251 {
00252   FD_DF("SupNorm(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
00253   
00254   // exceprions
00255   NormalityConsistencyCheck(rL,rOAlph,rK);
00256   
00257   //extract overall alphabet:
00258   EventSet allevents;
00259   allevents=rL.Alphabet();
00260   
00261   //extract alphabet of rK:
00262   EventSet Kevents=rK.Alphabet();
00263     
00264   // involved operations from cfl_regular.h operate on the marked
00265   // languages -> turn generated languages into marked langusges
00266   Generator prL=rL;
00267   prL.InjectMarkedStates(rL.States());
00268   Generator prK=rK;
00269   prK.InjectMarkedStates(prK.States());
00270   
00271   // calculate "L-K" 
00272   LanguageDifference(prL,prK,rResult);
00273   
00274   // calculate Pinv(P(L-K)):
00275   Project(rResult,rOAlph,rResult);
00276   FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size());
00277   InvProject(rResult,allevents);
00278   FD_DF("SupNorm: sizeof pinv(p(L-K)): "<< rResult.Size());
00279 
00280   //calculate remaining set difference -> supnorm(K)
00281   LanguageDifference(prK,rResult,rResult);
00282   
00283   // cosmetics: remove blocking states
00284   rResult.Trim();
00285    
00286   // done
00287   rResult.Name("SupNorm("+rL.Name()+", "+rK.Name()+")");  
00288   return !( rResult.InitStatesEmpty() );
00289 }
00290 
00291 //  SupNormClosed(rL,rOAlph,rK,rResult)
00292 bool SupNormClosed(
00293   const Generator& rL,
00294   const EventSet& rOAlph,
00295   const Generator& rK, 
00296   Generator& rResult)
00297 {
00298   FD_DF("SupNormClosed(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
00299   
00300   NormalityConsistencyCheck(rL,rOAlph,rK);
00301   
00302   //extract overall alphabet:
00303   EventSet allevents;
00304   allevents=rL.Alphabet();
00305   
00306   //extract alphabet of rK:
00307   EventSet Kevents=rK.Alphabet();
00308   
00309   // involved operations from regular.h operate on the marked
00310   // languages -> turn generated languages into marked langs
00311   Generator prL=rL;
00312   prL.InjectMarkedStates(prL.States());
00313   Generator prK=rK;
00314   prK.InjectMarkedStates(prK.States());
00315   
00316   // calculate "L-K" 
00317   LanguageDifference(prL,prK,rResult);
00318 
00319   // calculate Pinv(P(L-K)):
00320   Project(rResult,rOAlph,rResult);
00321   FD_DF("SupNormClosed: sizeof p(L-K): "<< rResult.Size());
00322   InvProject(rResult,allevents);
00323   FD_DF("SupNormClosed: sizeof pinv(p(L-K)): "<< rResult.Size());
00324   
00325   //concatenate Pinv(P(L-K)) with Sigma*: this leads to closed result
00326   ConcatenateFullLanguage(rResult); // special function for fast concatenation of Sigma*.
00327   
00328   FD_DF("SupNormClosed: sizeof pinv(p(L-K))Sigma*: "<< rResult.Size());
00329 
00330   //calculate remaining set difference -> supnormClosed(K)
00331   LanguageDifference(prK,rResult,rResult);
00332 
00333   // cosmetics: remove blocking states
00334   rResult.Trim();
00335 
00336   // done
00337   rResult.Name("SupNormClosed("+rL.Name()+", "+rK.Name()+")"); 
00338   return !( rResult.InitStatesEmpty() );
00339 }
00340 
00341 
00342 
00343 // SupPrefixClosed(rK,rResult)
00344 bool SupPrefixClosed(
00345   const Generator& rK,
00346   Generator& rResult) {
00347   
00348   FD_DF("SupPrefixClosed("<<rK.Name()<<")");
00349   
00350   // prepare Result:
00351   rResult.Name("SupPrefixClosed("+rK.Name()+")");
00352   
00353   // check for marked initial state, empty result if not
00354   if( (rK.InitStates() * rK.MarkedStates()).Empty() ) {
00355     rResult.Clear();
00356     return false;
00357   }
00358 
00359   rResult.Assign(rK);  
00360   
00361   // erase all transitions not leading to a marked state
00362   // todo: Depth-first-search could be faster
00363   TransSet trel=rResult.TransRel();
00364   TransSet::Iterator tit=trel.Begin();
00365   TransSet::Iterator tit_end=trel.End();
00366   for(;tit!=tit_end;tit++) {
00367     if(!(rResult.ExistsMarkedState(tit->X2))) {
00368       rResult.ClrTransition(*tit);
00369       }
00370   }
00371   
00372   // make reachable (cosmetic)
00373   rResult.Trim();
00374   
00375   // as there is at least one marked init state, result is nonempty
00376   return true;
00377 }
00378 
00379 
00380 
00381 /** rti wrapper */
00382 void SupNorm(
00383   const System& rPlantGen, 
00384   const Generator& rSpecGen, 
00385   Generator& rResGen) {
00386 
00387   // trust deferred copy ...
00388   Generator pg=rPlantGen;
00389   SupNorm(pg,rPlantGen.ObservableEvents(),rSpecGen,rResGen);
00390 
00391 }
00392 
00393 /** rti wrapper */
00394 void SupNormClosed(
00395   const System& rPlantGen, 
00396   const Generator& rSpecGen, 
00397   Generator& rResGen) {
00398 
00399   // trust deferred copy ...
00400   Generator pg=rPlantGen;
00401   SupNormClosed(pg,rPlantGen.ObservableEvents(),rSpecGen,rResGen);
00402 
00403 }
00404 
00405 } // end namespace

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen