libFAUDES
Sections
Index
|
syn_supnorm.cppGo 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