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 #include "syn_supcon.h" 00025 00026 00027 namespace faudes { 00028 00029 00030 00031 00032 /* 00033 *************************************************************************************** 00034 *************************************************************************************** 00035 Implementation 00036 *************************************************************************************** 00037 *************************************************************************************** 00038 */ 00039 00040 00041 //void NormalityConsistencyCheck(rL,rOAlph,rK) 00042 void NormalityConsistencyCheck( 00043 const Generator& rL, 00044 const EventSet& rOAlph, 00045 const Generator& rK) { 00046 00047 FD_DF("NormalityConsistencyCheck(...)"); 00048 00049 if (!(rK.IsDeterministic())) { 00050 std::stringstream errstr; 00051 errstr << "Nondeterministic parameter rK."; 00052 if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL."; 00053 throw Exception("NormalityConsistencyCheck", errstr.str(), 101); 00054 } 00055 if (!(rL.IsDeterministic())) { 00056 std::stringstream errstr; 00057 errstr << "Nondeterministic parameter rL."; 00058 if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL."; 00059 throw Exception("NormalityConsistencyCheck", errstr.str(), 101); 00060 } 00061 00062 EventSet Kevents,Sigma; 00063 Sigma=rL.Alphabet(); 00064 Kevents=rK.Alphabet(); 00065 00066 // observable events have to be subset of Sigma 00067 if(!(rOAlph<=Sigma)) { 00068 EventSet only_in_OAlph = rOAlph - Sigma; 00069 std::stringstream errstr; 00070 errstr << "Not all observable events are contained in Sigma: " 00071 << only_in_OAlph.ToString() << "."; 00072 throw Exception("NormalityConsistencyCheck", errstr.str(), 100); 00073 } 00074 00075 // alphabets must match 00076 if ( Sigma != Kevents) { 00077 EventSet only_in_L = Sigma - Kevents; 00078 EventSet only_in_K = Kevents - Sigma; 00079 only_in_L.Name("Only_In_L"); 00080 only_in_L.Name("Only_In_K"); 00081 std::stringstream errstr; 00082 errstr << "Alphabets of generators do not match."; 00083 if(!only_in_L.Empty()) 00084 errstr << " " << only_in_L.ToString() << "."; 00085 if(!only_in_K.Empty()) 00086 errstr << " " << only_in_K.ToString() << "."; 00087 throw Exception("NormalityConsistencyCheck", errstr.str(), 100); 00088 } 00089 00090 // K must be subset of L 00091 if (!LanguageInclusion(rK,rL)) { 00092 std::stringstream errstr; 00093 errstr << "K is not subset of L."; 00094 throw Exception("NormalityConsistencyCheck", errstr.str(), 0); 00095 } 00096 } 00097 00098 // IsNormal(rK,rL,rOAlph) 00099 bool IsNormal( 00100 const Generator& rL, 00101 const EventSet& rOAlph, 00102 const Generator& rK) 00103 { 00104 FD_DF("IsNormal(...)"); 00105 00106 // bail out on empty K 00107 // note: this is required to survive the 00108 // determinism test when rK has no states at all 00109 if(IsEmptyLanguage(rK)) return true; 00110 00111 // determinism required 00112 NormalityConsistencyCheck(rL,rOAlph,rK); 00113 00114 //extract overall alphabet: 00115 EventSet Sigma; 00116 Sigma=rL.Alphabet(); 00117 00118 //extract alphabet of rK: 00119 EventSet Kevents; 00120 Kevents=rK.Alphabet(); 00121 00122 //calculate p(K) 00123 Generator Ktest1, Ktest2; 00124 Ktest1.StateNamesEnabled(false); 00125 Ktest2.StateNamesEnabled(false); 00126 Project(rK,rOAlph,Ktest1); 00127 00128 //calculate pinv(p(K)) 00129 InvProject(Ktest1, Sigma); 00130 00131 //check normality: pinv(p(K)) intersect L = K? 00132 LanguageIntersection(Ktest1,rL,Ktest2); 00133 return LanguageInclusion(Ktest2,rK); 00134 00135 // Remark: testing for LanguageEquality is not required, as inclusion 00136 // in the reverse direction is always met (assuming K\subseteq L) 00137 } 00138 00139 00140 00141 // IsNormal rti wrapper 00142 bool IsNormal(const System& rPlantGen, const Generator& rSupCandGen) { 00143 return IsNormal(rPlantGen, rPlantGen.ObservableEvents(),rSupCandGen); 00144 } 00145 00146 00147 // ConcatenateFullLanguage(rGen) 00148 void ConcatenateFullLanguage(Generator& rGen) { 00149 FD_DF("ConcatenateFullLanguage(" << rGen.Name() << ")"); 00150 00151 // prepare result 00152 rGen.Name("ConcatenateFullLanguage(" + rGen.Name() + ")"); 00153 00154 // treat trivial empty result in case of empty marked language 00155 if(rGen.MarkedStatesSize()==0) { 00156 rGen.Clear(); 00157 return; 00158 } 00159 00160 // helpers 00161 EventSet alph=rGen.Alphabet(); 00162 StateSet StatesToClear; 00163 TransSet TransToClear,TransToSet; 00164 StateSet::Iterator sit; 00165 TransSet::Iterator tit; 00166 EventSet::Iterator evit; 00167 00168 // clear all transitions in marked states 00169 for (sit = rGen.MarkedStatesBegin(); sit != rGen.MarkedStatesEnd(); ++sit) { 00170 for (tit = rGen.TransRelBegin(*sit); tit != rGen.TransRelEnd(*sit); ++tit) { 00171 TransToClear.Insert(*tit); 00172 } 00173 } 00174 00175 for (tit = TransToClear.Begin(); tit != TransToClear.End(); ++tit) { 00176 rGen.ClrTransition(*tit); 00177 } 00178 TransToClear.Clear(); 00179 rGen.Accessible(); 00180 00181 // all marked states become eqivalent -> switch transitions leading to marked states to one remaining marked state 00182 // and delete all the others; note: for this special purpose, this procedure is faster than running StateMin. 00183 // if an init state is marked the effort is even less (as the result is Sigma* itself, see "else" below) 00184 bool initmarked = !( (rGen.InitStates() * rGen.MarkedStates()).Empty() ); 00185 if (!initmarked) { 00186 // define remaining marked state (there is one because of nonzero MarkedStatesSize) 00187 sit = rGen.MarkedStatesBegin(); 00188 Idx marked = *sit; 00189 // switch transitions to all other marked states if there are any 00190 if(rGen.MarkedStatesSize()>1) { 00191 // extract transitions sorted by target state X2 00192 TransSetX2EvX1 trel; 00193 rGen.TransRel(trel); 00194 TransSetX2EvX1::Iterator tit2; 00195 00196 // switch transitions to all other marked states to the one remaining marked state 00197 ++sit; 00198 for (; sit != rGen.MarkedStatesEnd(); ++sit) { 00199 for (tit2 = trel.BeginByX2(*sit); tit2 != trel.EndByX2(*sit); ++tit2) { 00200 // switch transition target to remaining marked state 00201 TransToSet.Insert(tit2->X1,tit2->Ev,marked); 00202 // note: original transitions are cleared later with clearing the corresp. marked states. 00203 } 00204 } 00205 00206 // delete all but remaining marked state (note: by doing so, also corresp. transitions are cleared.) 00207 sit = rGen.MarkedStatesBegin(); 00208 ++sit; 00209 for (; sit != rGen.MarkedStatesEnd(); ++sit) { 00210 StatesToClear.Insert(*sit); 00211 } 00212 for (sit=StatesToClear.Begin(); sit != StatesToClear.End(); ++sit) { 00213 rGen.DelState(*sit); 00214 } 00215 StatesToClear.Clear(); 00216 00217 // insert switched transitions 00218 for (tit = TransToSet.Begin(); tit != TransToSet.End(); ++tit) { 00219 rGen.SetTransition(*tit); 00220 } 00221 TransToSet.Clear(); 00222 } 00223 00224 // now concatenate Sigma* by selflooping marked state with all events 00225 for (evit = alph.Begin(); evit != alph.End(); ++evit) { 00226 rGen.SetTransition(marked,*evit,marked); 00227 } 00228 00229 } 00230 // consider marked init state case 00231 else { 00232 FD_DF("ConcatenateFullLanguage(" << rGen.Name() << "): marked initial state"); 00233 // reduce to empty string language 00234 rGen.ClearStates(); 00235 rGen.ClearTransRel(); 00236 Idx state=rGen.InsInitState(); 00237 rGen.SetMarkedState(state); 00238 // now concatenate Sigma* by selflooping marked state with all events 00239 for (evit = alph.Begin(); evit != alph.End(); ++evit) { 00240 rGen.SetTransition(state,*evit,state); 00241 } 00242 00243 } 00244 00245 return; 00246 } 00247 00248 00249 // SupNorm(rL,rOAlph,rK,rResult) 00250 bool SupNorm( 00251 const Generator& rL, 00252 const EventSet& rOAlph, 00253 const Generator& rK, 00254 Generator& rResult) 00255 { 00256 FD_DF("SupNorm(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")"); 00257 00258 // exceprions 00259 NormalityConsistencyCheck(rL,rOAlph,rK); 00260 00261 //extract overall alphabet: 00262 EventSet allevents; 00263 allevents=rL.Alphabet(); 00264 00265 // involved operations from cfl_regular.h operate on the marked 00266 // languages -> turn generated languages into marked langusges 00267 Generator prL=rL; 00268 prL.InjectMarkedStates(rL.States()); 00269 Generator prK=rK; 00270 prK.InjectMarkedStates(prK.States()); 00271 00272 // calculate "L-K" 00273 LanguageDifference(prL,prK,rResult); 00274 00275 // calculate Pinv(P(L-K)): 00276 Project(rResult,rOAlph,rResult); 00277 FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size()); 00278 InvProject(rResult,allevents); 00279 FD_DF("SupNorm: sizeof pinv(p(L-K)): "<< rResult.Size()); 00280 00281 //calculate remaining set difference -> supnorm(K) 00282 LanguageDifference(prK,rResult,rResult); 00283 00284 // cosmetics: remove blocking states 00285 rResult.Trim(); 00286 00287 // done 00288 rResult.Name("SupNorm("+rL.Name()+", "+rK.Name()+")"); 00289 return !( rResult.InitStatesEmpty() ); 00290 } 00291 00292 // SupNormClosed(rL,rOAlph,rK,rResult) 00293 bool SupNormClosed( 00294 const Generator& rL, 00295 const EventSet& rOAlph, 00296 const Generator& rK, 00297 Generator& rResult) 00298 { 00299 FD_DF("SupNormClosed(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")"); 00300 00301 // involved operations from regular.h operate on the marked 00302 // languages -> turn generated languages into marked langs 00303 Generator prL=rL; 00304 prL.InjectMarkedStates(prL.States()); 00305 Generator prK=rK; 00306 prK.InjectMarkedStates(prK.States()); 00307 00308 // concitency check on closed languages 00309 NormalityConsistencyCheck(prL,rOAlph,prK); 00310 00311 //extract overall alphabet: 00312 EventSet allevents; 00313 allevents=rL.Alphabet(); 00314 00315 // calculate "L-K" 00316 LanguageDifference(prL,prK,rResult); 00317 00318 // calculate Pinv(P(L-K)): 00319 Project(rResult,rOAlph,rResult); 00320 FD_DF("SupNormClosed: sizeof p(L-K): "<< rResult.Size()); 00321 InvProject(rResult,allevents); 00322 FD_DF("SupNormClosed: sizeof pinv(p(L-K)): "<< rResult.Size()); 00323 00324 //concatenate Pinv(P(L-K)) with Sigma*: this leads to closed result 00325 ConcatenateFullLanguage(rResult); // special function for efficient concatenation of Sigma*. 00326 00327 FD_DF("SupNormClosed: sizeof pinv(p(L-K))Sigma*: "<< rResult.Size()); 00328 00329 //calculate remaining set difference -> supnormClosed(K) 00330 LanguageDifference(prK,rResult,rResult); 00331 00332 // cosmetics: remove blocking states 00333 rResult.Trim(); 00334 00335 // done 00336 rResult.Name("SupNormClosed("+rL.Name()+", "+rK.Name()+")"); 00337 return !( rResult.InitStatesEmpty() ); 00338 } 00339 00340 00341 // SupConNormClosed(rL,rCAlph,rOAlph,rK,rResult) 00342 void SupConNormClosed( 00343 const Generator& rL, 00344 const EventSet& rCAlph, 00345 const EventSet& rOAlph, 00346 const Generator& rK, 00347 Generator& rResult) 00348 { 00349 FD_DF("SupConNormClosed(" << rL.Name() << "," << rK.Name() << ")"); 00350 // determinism required 00351 ControlProblemConsistencyCheck(rL,rCAlph,rOAlph,rK); 00352 // 0.: intersect K with L to match requirements of SupNormClosed 00353 Generator K; 00354 K.StateNamesEnabled(false); 00355 Product(rL,rK,K); 00356 // 1. normal and closed sublanguage (operates on / returns generated language) 00357 Generator N; 00358 N.StateNamesEnabled(false); 00359 SupNormClosed(rL,rOAlph,K,N); 00360 // 2. project to sigma_o (generated languages) 00361 Generator N0,L0; 00362 N0.StateNamesEnabled(false); 00363 L0.StateNamesEnabled(false); 00364 Project(N,rOAlph,N0); 00365 Project(rL,rOAlph,L0); 00366 // 3. supremal controllable sublanguage (generated languages) 00367 EventSet sig_co = rCAlph * rOAlph; 00368 Generator K0; 00369 K0.StateNamesEnabled(false); 00370 SupConClosed(L0,sig_co,N0,K0); 00371 // 4. inverese project to sigma (on generated language) 00372 InvProject(K0,rL.Alphabet()); 00373 // 5. intersect with L (generated languages) 00374 LanguageIntersection(K0,rL,rResult); 00375 // convenience: mark the generated language 00376 rResult.InjectMarkedStates(rResult.States()); 00377 } 00378 00379 00380 // SupConNormNB(rL,rCAlph,rOAlph,rK,rResult) 00381 void SupConNormNB( 00382 const Generator& rL, 00383 const EventSet& rCAlph, 00384 const EventSet& rOAlph, 00385 const Generator& rK, 00386 Generator& rResult) 00387 { 00388 FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << ")"); 00389 // determinism required 00390 ControlProblemConsistencyCheck(rL,rCAlph,rOAlph,rK); 00391 // initialize: K0 00392 Generator K0; 00393 K0.StateNamesEnabled(false); 00394 Product(rL,rK,K0); 00395 K0.Coaccessible(); 00396 // initialize: closure(rL) 00397 Generator L=rL; 00398 L.StateNamesEnabled(false); 00399 L.Trim(); 00400 L.InjectMarkedStates(L.States()); 00401 // loop 00402 Generator Ki=K0; 00403 Ki.StateNamesEnabled(false); 00404 while(1) { 00405 FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << "): #" << Ki.Size() << " m#" << Ki.MarkedStatesSize()); 00406 // keep copy of recent 00407 rResult=Ki; 00408 // cheep closure (for coreachable generator) 00409 Ki.InjectMarkedStates(Ki.States()); 00410 // synthesise closed 00411 SupConNormClosed(L,rCAlph,rOAlph,Ki,Ki); 00412 // restrict 00413 Product(K0,Ki,Ki); 00414 Ki.Coaccessible(); 00415 // test (sequence is decreasing anyway) 00416 if(LanguageInclusion(rResult,Ki)) break; 00417 } 00418 FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << "): done"); 00419 } 00420 00421 00422 // SupPrefixClosed(rK,rResult) 00423 bool SupPrefixClosed( 00424 const Generator& rK, 00425 Generator& rResult) 00426 { 00427 00428 FD_DF("SupPrefixClosed("<<rK.Name()<<")"); 00429 00430 // prepare Result: 00431 rResult.Name("SupPrefixClosed("+rK.Name()+")"); 00432 00433 // check for marked initial state, empty result if not 00434 if( (rK.InitStates() * rK.MarkedStates()).Empty() ) { 00435 rResult.Clear(); 00436 return false; 00437 } 00438 00439 rResult.Assign(rK); 00440 00441 // erase all transitions not leading to a marked state 00442 // todo: Depth-first-search could be faster 00443 TransSet::Iterator tit=rResult.TransRelBegin(); 00444 TransSet::Iterator tit_end=rResult.TransRelEnd(); 00445 while(tit!=tit_end) { 00446 if(rResult.ExistsMarkedState(tit->X2)) { ++tit; continue;} 00447 rResult.ClrTransition(tit++); 00448 } 00449 00450 // make reachable (cosmetic) 00451 rResult.Trim(); 00452 00453 // as there is at least one marked init state, result is nonempty 00454 return true; 00455 } 00456 00457 00458 // helper class 00459 class SNOState { 00460 public: 00461 // minimal interface 00462 SNOState() {}; 00463 SNOState(const Idx& rq, const Idx& rx, const bool& rz) : 00464 q(rq), x(rx), z(rz) {}; 00465 std::string Str(void) { return ToStringInteger(q)+"|"+ 00466 ToStringInteger(x)+"|"+ToStringInteger(z); }; 00467 // order 00468 bool operator < (const SNOState& other) const { 00469 if (q < other.q) return(true); 00470 if (q > other.q) return(false); 00471 if (x < other.x) return(true); 00472 if (x > other.x) return(false); 00473 if (z < other.z) return(true); 00474 return(false); 00475 } 00476 // member variables 00477 Idx q; 00478 Idx x; 00479 Idx z; 00480 }; 00481 00482 00483 // SupConNormClosedUnchecked(rPlantGen, rCAlph, rObserverGen, rSupCandGen) 00484 void SupConNormClosedUnchecked( 00485 const Generator& rPlantGen, // aka G 00486 const EventSet& rCAlph, 00487 const EventSet& rOAlph, 00488 Generator& rObserverGen, // aka Hobs 00489 Generator& rSupCandGen // aka H 00490 ) 00491 { 00492 FD_DF("SupConNormClosedUnchecked(" << &rSupCandGen << "," << &rPlantGen << ")"); 00493 00494 // bail out on L(G)=0 --> closed-lopp language inclusion trivialy satisfied 00495 if(rPlantGen.InitStatesEmpty()) return; 00496 00497 // debugging: compare result with Lin-Brandt fromula at end of function 00498 // Generator K; 00499 // SupConNormClosed(rPlantGen, rCAlph, rOAlph, rSupCandGen, K); 00500 00501 // loop until fixpoint 00502 while(true) { 00503 FD_DF("SupConNormClosedUnchecked(" << &rSupCandGen << "," << &rPlantGen << "): until fixpoint #" << rSupCandGen.Size()); 00504 00505 // record size to break loop 00506 Idx ssz = rSupCandGen.TransRelSize(); 00507 Idx osz = rObserverGen.TransRelSize(); 00508 00509 // bail out if L(H)-0 --> closed-loop language fixpoint 00510 if(rSupCandGen.InitStatesEmpty()) break; 00511 00512 // todo stack (state triplets) 00513 std::stack<SNOState> todo; 00514 // relevant H states 00515 StateSet processed, critical; 00516 00517 // various iterators 00518 TransSet::Iterator titg, titg_end; 00519 TransSet::Iterator tith, tith_end; 00520 TransSet::Iterator titho, titho_end; 00521 00522 // current and successsor state 00523 SNOState current, successor; 00524 00525 // push combined initial state on todo stack 00526 FD_DF("SupNorm: todo push initial state"); 00527 current.q = *rPlantGen.InitStatesBegin(); 00528 current.x = *rSupCandGen.InitStatesBegin(); 00529 current.z = *rObserverGen.InitStatesBegin(); 00530 todo.push(current); 00531 00532 // process todo stack 00533 while(!todo.empty()) { 00534 // allow for user interrupt, incl progress report 00535 FD_WPC(1,2,"Normality(): iterating states"); 00536 // get top element from todo stack 00537 current = todo.top(); 00538 todo.pop(); 00539 FD_DF("SupNorm: todo #" << todo.size() << " processed #" << processed.Size()); 00540 FD_DF("SupNorm: pop: (" << rPlantGen.SStr(current.q) << "|" << rSupCandGen.SStr(current.x) << ")"); 00541 00542 // break cycles 00543 if(processed.Exists(current.x)) continue; 00544 if(critical.Exists(current.x)) continue; 00545 00546 // record processed 00547 processed.Insert(current.x); 00548 00549 // figure events disbabled by candidate H w.r.t plant G 00550 EventSet disabled = rPlantGen.ActiveEventSet(current.q) - rSupCandGen.ActiveEventSet(current.x); 00551 00552 // if an unobservabel event is disabled, current state becomes critical 00553 if(!(disabled <= rCAlph)) { 00554 critical.Insert(current.x); 00555 continue; 00556 } 00557 00558 // disable respective transition in observer Hobs 00559 titho = rObserverGen.TransRelBegin(current.z); 00560 titho_end = rObserverGen.TransRelEnd(current.z); 00561 while(titho!=titho_end) { 00562 if(!disabled.Exists(titho->Ev)) { ++titho; continue; } 00563 rObserverGen.ClrTransition(titho++); 00564 } 00565 00566 // find successor states to push on stack 00567 titg = rPlantGen.TransRelBegin(current.q); 00568 titg_end = rPlantGen.TransRelEnd(current.q); 00569 tith = rSupCandGen.TransRelBegin(current.x); 00570 tith_end = rSupCandGen.TransRelEnd(current.x); 00571 titho = rObserverGen.TransRelBegin(current.z); 00572 titho_end = rObserverGen.TransRelEnd(current.z); 00573 while( (titg != titg_end) && (tith != tith_end) && (titho != titho_end) ) { 00574 FD_DF("SupNorm: processing g-transition: " << rPlantGen.TStr(*titg)); 00575 FD_DF("SupNorm: processing h-transition: " << rSupCandGen.TStr(*tith)); 00576 // increment case A: process common events 00577 if( (titg->Ev == tith->Ev) && (tith->Ev == titho->Ev) ) { 00578 FD_DF("SupNorm: processing common event " << rPlantGen.EStr(titg->Ev)); 00579 // push successor 00580 if(!processed.Exists(tith->X2)) { 00581 successor.q=titg->X2; 00582 successor.x=tith->X2; 00583 successor.z=titho->X2; 00584 todo.push(successor); 00585 } 00586 // increment 00587 ++titg; ++tith; ++titho; 00588 } 00589 // increment case B: increment H transitions for events disabled by Hobs (when we disabled events in Hobs) 00590 else if (tith->Ev < titho->Ev) { 00591 rSupCandGen.ClrTransition(tith++); 00592 } 00593 // increment case C: increment Hobs transitions for events disabled by H (for removed critical states)) 00594 else if (titho->Ev < tith->Ev) { 00595 ++titho; 00596 } 00597 // increment case D: increment G transitions for events disabled by H 00598 else if (titg->Ev < tith->Ev) { 00599 ++titg; 00600 } 00601 // increment case E: increment Hobs transitions for events disabled by G 00602 else { 00603 ++titho; 00604 } 00605 } // end accessible states 00606 // reasoning for leftovers: 00607 // a) if tith==end then we dont need to restrict H by Hobs anymore 00608 // b) if titg=end then (by L subseteq K) we have tith=end, and we argue as in a) 00609 // c) if titho=end then we need to restrict H by Hobs ... 00610 while( (tith != tith_end) ) { 00611 // increment case B: increment H transitions for events disabled by Hobs (when we disabled events in Hobs) 00612 rSupCandGen.ClrTransition(tith++); 00613 } 00614 00615 } // end: todo stack 00616 00617 // remove critical 00618 //rSupCandGen.DelStates((rSupCandGen.States()-processed) + critical); 00619 rSupCandGen.DelStates(critical); 00620 00621 // break on fixpoint 00622 if(ssz != rSupCandGen.TransRelSize()) continue; 00623 if(osz != rObserverGen.TransRelSize()) continue; 00624 break; 00625 00626 } //end: until fixpoint 00627 00628 // cosmetic 00629 rSupCandGen.Accessible(); 00630 00631 /* 00632 // debugging: compare with Lin-Brandt formula 00633 Generator Rpr = rSupCandGen; 00634 MarkAllStates(Rpr); 00635 if(!LanguageEquality(K,Rpr)) FD_WARN("SUPNORM ERROR??? Supremal?"); 00636 */ 00637 00638 } 00639 00640 00641 00642 /** rti wrapper */ 00643 void SupNorm( 00644 const System& rPlantGen, 00645 const Generator& rSpecGen, 00646 Generator& rResGen) 00647 { 00648 // prepare result 00649 Generator* pResGen = &rResGen; 00650 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00651 pResGen= rResGen.New(); 00652 } 00653 // execute 00654 SupNorm(rPlantGen,rPlantGen.ObservableEvents(),rSpecGen,*pResGen); 00655 // copy all attributes of input alphabet 00656 pResGen->EventAttributes(rPlantGen.Alphabet()); 00657 // copy result 00658 if(pResGen != &rResGen) { 00659 pResGen->Move(rResGen); 00660 delete pResGen; 00661 } 00662 } 00663 00664 /** rti wrapper */ 00665 void SupNormClosed( 00666 const System& rPlantGen, 00667 const Generator& rSpecGen, 00668 Generator& rResGen) 00669 { 00670 // prepare result 00671 Generator* pResGen = &rResGen; 00672 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00673 pResGen= rResGen.New(); 00674 } 00675 // execute 00676 SupNormClosed(rPlantGen,rPlantGen.ObservableEvents(),rSpecGen,*pResGen); 00677 // copy all attributes of input alphabet 00678 pResGen->EventAttributes(rPlantGen.Alphabet()); 00679 // copy result 00680 if(pResGen != &rResGen) { 00681 pResGen->Move(rResGen); 00682 delete pResGen; 00683 } 00684 } 00685 00686 00687 /** rti wrapper */ 00688 void SupConNormClosed( 00689 const System& rPlantGen, 00690 const Generator& rSpecGen, 00691 Generator& rResGen) 00692 { 00693 // prepare result 00694 Generator* pResGen = &rResGen; 00695 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00696 pResGen= rResGen.New(); 00697 } 00698 // execute 00699 SupConNormClosed(rPlantGen,rPlantGen.ControllableEvents(),rPlantGen.ObservableEvents(),rSpecGen,*pResGen); 00700 // copy all attributes of input alphabet 00701 pResGen->EventAttributes(rPlantGen.Alphabet()); 00702 // copy result 00703 if(pResGen != &rResGen) { 00704 pResGen->Move(rResGen); 00705 delete pResGen; 00706 } 00707 } 00708 00709 /** rti wrapper */ 00710 void SupConNormNB( 00711 const System& rPlantGen, 00712 const Generator& rSpecGen, 00713 Generator& rResGen) 00714 { 00715 FD_DF("SupConNormNB(" << rPlantGen.Name() << "," << rSpecGen.Name() << "): rti wrapper"); 00716 // prepare result 00717 Generator* pResGen = &rResGen; 00718 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00719 pResGen= rResGen.New(); 00720 } 00721 // execute 00722 SupConNormNB(rPlantGen,rPlantGen.ControllableEvents(),rPlantGen.ObservableEvents(),rSpecGen,*pResGen); 00723 // copy all attributes of input alphabet 00724 pResGen->EventAttributes(rPlantGen.Alphabet()); 00725 // copy result 00726 if(pResGen != &rResGen) { 00727 pResGen->Move(rResGen); 00728 delete pResGen; 00729 } 00730 } 00731 00732 } // end namespace libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |