| |
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 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