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