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     std::stringstream errstr;
00079     errstr << "Alphabets of generators do not match. Only in L: " 
00080        << only_in_L.ToString() << ". Only in K: "
00081        << only_in_K.ToString() << ".";
00082     throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
00083   }
00084   
00085   // K must be subset of L
00086   if (!LanguageInclusion(rK,rL)) {
00087     std::stringstream errstr;
00088     errstr << "K is not subset of L.";
00089     throw Exception("NormalityConsistencyCheck", errstr.str(), 0);
00090   }
00091 }
00092 
00093 // IsNormal(rK,rL,rOAlph)
00094 bool IsNormal(
00095   const Generator& rL,
00096   const EventSet& rOAlph,
00097   const Generator& rK) 
00098 {
00099   FD_DF("IsNormal(...)");
00100   
00101   NormalityConsistencyCheck(rL,rOAlph,rK);
00102   
00103   //extract overall alphabet:
00104   EventSet Sigma;
00105   Sigma=rL.Alphabet();
00106   
00107   //extract alphabet of rK:
00108   EventSet Kevents;
00109   Kevents=rK.Alphabet();
00110   
00111   //calculate p(K)
00112   Generator Ktest1, Ktest2;
00113   Project(rK,rOAlph,Ktest1);
00114   
00115   //calculate pinv(p(K))
00116   InvProject(Ktest1, Sigma);
00117   
00118   //check normality: pinv(p(K)) intersect L = K?
00119   LanguageIntersection(Ktest1,rL,Ktest2);
00120   return LanguageInclusion(Ktest2,rK);
00121   // Remark: LanguageEquality is not necessary, as inclusion
00122   // in the reverse direction is always met.
00123 }
00124 
00125 // IsNormalAlt(rK,rL,rOAlph)
00126 bool IsNormalAlt(
00127   const Generator& rL,
00128   const EventSet& rOAlph,
00129     const Generator& rK) 
00130 {
00131   FD_DF("IsNormalAlt(...)");
00132   
00133   NormalityConsistencyCheck(rL,rOAlph,rK);
00134   
00135   //extract overall alphabet:
00136   EventSet Sigma;
00137   Sigma=rL.Alphabet();
00138   
00139   //extract alphabet of rK:
00140   EventSet Kevents;
00141   Kevents=rK.Alphabet();
00142   
00143   //calculate p(K)
00144   Generator Ktest1, Ktest2;
00145   Project(rK,rOAlph,Ktest1);
00146   
00147   //calculate pinv(p(K))
00148   InvProject(Ktest1, Sigma);
00149   
00150   //check normality: p(K) || L = K?
00151   Parallel(Ktest1,rL,Ktest2);
00152   return LanguageInclusion(Ktest2,rK);
00153   // Remark: LanguageEquality is not necessary, as inclusion
00154   // in the reverse direction is always met.
00155 }
00156 
00157 
00158 // IsNormal rti wrapper 
00159 void IsNormal(
00160   const vGenerator& rPlantGen, 
00161   const EventSet&  rOAlph,
00162   const vGenerator& rSupCandGen, 
00163   bool& rRes) 
00164 {
00165   rRes=IsNormal(rPlantGen, rOAlph, rSupCandGen);
00166 }
00167 
00168 // IsNormal rti wrapper
00169 void IsNormal(
00170   const cGenerator& rPlantGen, 
00171   const vGenerator& rSupCandGen,
00172   bool& rRes) 
00173 {
00174   IsNormal(rPlantGen, rPlantGen.ObservableEvents(), rSupCandGen, rRes);
00175 }
00176 
00177 
00178 
00179 
00180 // ConcatenateFullLanguage(rGen)
00181 void ConcatenateFullLanguage(vGenerator& rGen) {
00182   FD_DF("ConcatenateFullLanguage(" << rGen.Name() << ")");
00183   
00184   // prepare result
00185   rGen.Name("ConcatenateFullLanguage(" + rGen.Name() + ")");
00186   
00187   // treat trivial empty result in case of empty marked language
00188   if(rGen.MarkedStatesSize()==0) {
00189     rGen.Clear();
00190     return;
00191   }
00192   
00193   // helpers
00194   EventSet alph=rGen.Alphabet();
00195   StateSet StatesToClear;
00196   TransSet TransToClear,TransToSet;
00197   StateSet::Iterator sit;
00198   TransSet::Iterator tit;
00199   EventSet::Iterator evit;
00200   
00201   // clear all transitions in marked states
00202   for (sit = rGen.MarkedStatesBegin(); sit != rGen.MarkedStatesEnd(); ++sit) {
00203       for (tit = rGen.TransRelBegin(*sit); tit != rGen.TransRelEnd(*sit); ++tit) {
00204           TransToClear.Insert(*tit);
00205       }
00206   }
00207   
00208   for (tit = TransToClear.Begin(); tit != TransToClear.End(); ++tit) {
00209       rGen.ClrTransition(*tit);
00210   }
00211   TransToClear.Clear();
00212   rGen.Accessible();
00213   
00214   // all marked states become eqivalent -> switch transitions leading to marked states to one remaining marked state
00215   // and delete all the others; note: for this special purpose, this procedure is faster than running StateMin.
00216   // if an init state is marked the effort is even less (as the result is Sigma* itself, see "else" below)
00217   bool initmarked = !( (rGen.InitStates() * rGen.MarkedStates()).Empty() );
00218   if (!initmarked) {
00219     // define remaining marked state (there is one because of nonzero MarkedStatesSize)
00220     sit = rGen.MarkedStatesBegin();
00221     Idx marked = *sit;
00222     // switch transitions to all other marked states if there are any
00223     if(rGen.MarkedStatesSize()>1) {
00224       // extract transitions sorted by target state X2
00225       TransSetX2EvX1 trel;
00226       rGen.TransRel(trel);
00227       TransSetX2EvX1::Iterator tit2;
00228       
00229       // switch transitions to all other marked states to the one remaining marked state
00230       ++sit;
00231       for (; sit != rGen.MarkedStatesEnd(); ++sit) {
00232           for (tit2 = trel.BeginByX2(*sit); tit2 != trel.EndByX2(*sit); ++tit2) {
00233           // switch transition target to remaining marked state
00234           TransToSet.Insert(tit2->X1,tit2->Ev,marked);
00235           // note: original transitions are cleared later with clearing the corresp. marked states.
00236           }
00237       }
00238       
00239       // delete all but remaining marked state (note: by doing so, also corresp. transitions are cleared.)
00240       sit = rGen.MarkedStatesBegin();
00241       ++sit;
00242       for (; sit != rGen.MarkedStatesEnd(); ++sit) {
00243       StatesToClear.Insert(*sit);
00244       }
00245       for (sit=StatesToClear.Begin(); sit != StatesToClear.End(); ++sit) {
00246       rGen.DelState(*sit);
00247       }
00248       StatesToClear.Clear();
00249       
00250       // insert switched transitions
00251       for (tit = TransToSet.Begin(); tit != TransToSet.End(); ++tit) {
00252           rGen.SetTransition(*tit);
00253       }
00254       TransToSet.Clear();
00255       }
00256 
00257     // now concatenate Sigma* by selflooping marked state with all events
00258     for (evit = alph.Begin(); evit != alph.End(); ++evit) {
00259       rGen.SetTransition(marked,*evit,marked);
00260     }
00261     
00262   }
00263   // consider marked init state case
00264   else {
00265     // reduce to empty string language
00266     rGen.ClearStates();
00267     rGen.ClearTransRel();
00268     Idx state=rGen.InsInitState();
00269     rGen.SetMarkedState(state);
00270     // now concatenate Sigma* by selflooping marked state with all events
00271     for (evit = alph.Begin(); evit != alph.End(); ++evit) {
00272       rGen.SetTransition(state,*evit,state);
00273     }
00274     
00275     }
00276   
00277   return;
00278 }
00279 
00280 
00281 //  SupNorm(rL,rOAlph,rK,rResult)
00282 bool SupNorm(
00283   Generator& rL,
00284   const EventSet& rOAlph,
00285   const Generator& rK, 
00286   Generator& rResult)
00287 {
00288   FD_DF("SupNorm(" << rK.Name() << "," << rL.Name() << "," << rOAlph.Name() << ")");
00289   
00290   NormalityConsistencyCheck(rL,rOAlph,rK);
00291   
00292   // prepare result
00293   rResult.Clear();
00294   
00295   //extract overall alphabet:
00296   EventSet allevents;
00297   allevents=rL.Alphabet();
00298   
00299   //extract alphabet of rK:
00300   EventSet Kevents=rK.Alphabet();
00301   
00302   // remember name and marked states of rL
00303   std::string rLname=rL.Name();
00304   StateSet rLmarked=rL.MarkedStates();
00305   
00306   // involved operations from regular.h operate on the marked
00307   // languages -> turn generated languages into marked langs
00308   rL.InjectMarkedStates(rL.States());
00309   //###PrefixClosure(rL);
00310   Generator prK=rK;
00311   prK.InjectMarkedStates(prK.States());
00312   //###PrefixClosure(prK);
00313   rResult = prK;
00314   
00315   // calculate "L-K" (ToDo: use LanguageDifference):
00316   LanguageComplement(rResult);
00317   FD_DF("SupNorm: size of complement(K): "<<rResult.Size()<<",marked: "<<rResult.MarkedStatesSize());
00318   Generator tempgen;
00319   LanguageIntersection(rL, rResult, tempgen);
00320   rResult.Clear();
00321   FD_DF("SupNorm: sizeof L U complement(K)=L-K: "<<tempgen.Size());
00322   
00323   // calculate Pinv(P(L-K)):
00324   Project(tempgen,rOAlph,rResult);
00325   tempgen.Clear();
00326   FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size());
00327   InvProject(rResult,allevents);
00328   FD_DF("SupNorm: sizeof pinv(p(L-K)): "<<rResult.Size());
00329   
00330   //concatenate Pinv(P(L-K)) with Sigma*:
00331   ConcatenateFullLanguage(rResult); // special function for fast concatenation of Sigma*.
00332   
00333 //  FD_DF("SupNorm: sizeof pinv(p(L-K))Sigma*: "<<rResult.Size());
00334 
00335   //calculate remaining set difference -> supnorm(K)
00336   LanguageComplement(rResult);
00337   LanguageIntersection(prK, rResult, tempgen);
00338   rResult=tempgen;
00339   tempgen.Clear();
00340   FD_DF("SupNorm: sizeof K - pinv(p(L-K))Sigma* (result): "<<rResult.Size());
00341   
00342   // language MARKED by rResult is the result -> remove blocking states, mark all remaining states.
00343   rResult.Trim();
00344   rResult.InjectMarkedStates(rResult.States());
00345   
00346   // restore original rL
00347   rL.Name(rLname);
00348   rL.InjectMarkedStates(rLmarked);
00349   
00350   // mark result corresponding to rL
00351   LanguageIntersection(rResult,rL,rResult);
00352   
00353   return !( rResult.InitStatesEmpty() );
00354 }
00355 
00356 // SupPrefixClosed(rK,rResult)
00357 bool SupPrefixClosed(
00358   const Generator& rK,
00359   Generator& rResult) {
00360   
00361   FD_DF("SupPrefixClosed("<<rK.Name()<<")");
00362   
00363   // prepare Result:
00364   rResult.Clear();
00365   rResult.Name("SupPrefixClosed("+rK.Name()+")");
00366   
00367   // check for marked initial state, empty result if not
00368   if( (rK.InitStates() * rK.MarkedStates()).Empty() ) return false;
00369   
00370   rResult=rK;  
00371   
00372   // erase all transitions not leading to a marked state
00373   // todo: Depth-first-search could be faster
00374   TransSet trel=rResult.TransRel();
00375   TransSet::Iterator tit=trel.Begin();
00376   TransSet::Iterator tit_end=trel.End();
00377   for(;tit!=tit_end;tit++) {
00378     if(!(rResult.ExistsMarkedState(tit->X2))) {
00379       rResult.ClrTransition(*tit);
00380       }
00381   }
00382   
00383   // make reachable (cosmetic)
00384   rResult.Trim();
00385   
00386   // as there is at least one marked init state, result is nonempty
00387   return true;
00388 }
00389 
00390 // SupNormAlt(rK,rL,rOAlph,ClosedResult,rResult)
00391 bool SupNormAlt(
00392   Generator& rL,
00393   const EventSet& rOAlph,
00394   const Generator& rK, 
00395   Generator& rResult) 
00396 {
00397   FD_DF("SupNorm(...)");
00398   
00399   NormalityConsistencyCheck(rL,rOAlph,rK);
00400   
00401   // prepare result
00402   rResult.Clear();
00403   rResult = rK;
00404   
00405   //extract overall alphabet:
00406   EventSet allevents;
00407   allevents=rL.Alphabet();
00408   
00409   //extract alphabet of rK:
00410   EventSet Kevents;
00411   Kevents=rK.Alphabet();
00412   
00413   // remember name and marked states of rL
00414   std::string rLname=rL.Name();
00415   StateSet rLmarked=rL.MarkedStates();
00416   
00417   // involved operations from regular.h treat only the marked
00418   // languages -> turn generated languages into marked langs
00419   rResult.InjectMarkedStates(rResult.States());
00420   //###PrefixClosure(rResult);
00421   rL.InjectMarkedStates(rL.States());
00422   //##PrefixClosure(rL);
00423   Generator Kquer=rK;
00424   Kquer.InjectMarkedStates(Kquer.States());
00425   //###PrefixClosure(Kquer);
00426   
00427   // calculate "L-K" (ToDo: use LanguageDifference):
00428   LanguageComplement(rResult);
00429   FD_DF("SupNorm: size of complement(K): "<<rResult.Size()<<",marked: "<<rResult.MarkedStatesSize());
00430   Generator tempgen;
00431   LanguageIntersection(rL, rResult, tempgen);
00432   rResult.Clear();
00433   FD_DF("SupNorm: sizeof L U complement(K)=L-K: "<<tempgen.Size());
00434   
00435   // calculate Pinv(P(L-K)):
00436   Project(tempgen,rOAlph,rResult);
00437   tempgen.Clear();
00438   FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size());
00439   InvProject(rResult,allevents);
00440   FD_DF("SupNorm: sizeof pinv(p(L-K)): "<<rResult.Size());
00441   
00442   // Remark: different from the above supnorm version, we do not
00443   // concatenate Sigma* here, but make the result prefix-closed
00444   // at the end.
00445 
00446   //calculate remaining set difference
00447   LanguageComplement(rResult);
00448   LanguageIntersection(Kquer, rResult, tempgen);
00449   rResult=tempgen;
00450   FD_DF("SupNorm: sizeof K - pinv(p(L-K))Sigma* (result): "<<rResult.Size());
00451   
00452   // make prefix-closed
00453   SupPrefixClosed(tempgen,rResult);
00454 
00455   // language MARKED by rResult is the result -> turn marked language into generated language
00456   rResult.Trim(); //may be unnecessesary
00457   
00458   // restore original rL
00459   rL.Name(rLname);
00460   rL.InjectMarkedStates(rLmarked);
00461   
00462   // mark result corresponding to rL
00463   LanguageIntersection(rResult,rL,rResult);
00464   
00465   return rResult.Empty();
00466 
00467 }
00468 
00469 
00470 
00471 /** rti wrapper */
00472 void SupNorm(
00473   const vGenerator& rPlantGen, 
00474   const EventSet&  rOAlph,
00475   const vGenerator& rSpecGen, 
00476   vGenerator& rResGen) {
00477 
00478   // trust deferred copy ...
00479   vGenerator pg=rPlantGen;
00480   SupNorm(pg,rOAlph,rSpecGen,rResGen);
00481 
00482 }
00483 
00484 /** rti wrapper */
00485 void SupNorm(
00486   const cGenerator& rPlantGen, 
00487   const vGenerator& rSpecGen, 
00488   vGenerator& rResGen) {
00489 
00490   // trust deferred copy ...
00491   vGenerator pg=rPlantGen;
00492   SupNorm(pg,rPlantGen.ObservableEvents(),rSpecGen,rResGen);
00493 
00494 }
00495 
00496 } // end namespace

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6