syn_tsupcon.cppGo to the documentation of this file.00001 /** @file tp_synthesis.cpp Supremal TDES-controllable sublanguage */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2013 Thomas Moor 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00020 00021 00022 #include "syn_tsupcon.h" 00023 00024 00025 namespace faudes { 00026 00027 00028 00029 00030 /* 00031 *************************************************************************************** 00032 *************************************************************************************** 00033 Implementation 00034 *************************************************************************************** 00035 *************************************************************************************** 00036 */ 00037 00038 00039 // SupTconUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, rCPAlph, rSupCandGen) 00040 void SupTconUnchecked( 00041 const Generator& rPlantGen, // aka G 00042 const EventSet& rCAlph, 00043 const EventSet& rFAlph, 00044 const EventSet& rPAlph, 00045 const EventSet& rCPAlph, 00046 Generator& rSupCandGen // aka H 00047 ) 00048 { 00049 FD_DF("SupTconUnchecked(" << &rSupCandGen << "," << &rPlantGen << ")"); 00050 00051 // bail out if plant or candidate contain no initial states 00052 if(rPlantGen.InitStatesEmpty() || rSupCandGen.InitStatesEmpty()) 00053 return; 00054 00055 // todo stack (pairs of states) 00056 std::stack<Idx> todog, todoh; 00057 // set of already processed states of H (this is why we need H-states) 00058 StateSet processed; 00059 00060 // critical states 00061 StateSet critical; 00062 00063 // push combined initial state on todo stack 00064 todog.push(*rPlantGen.InitStatesBegin()); 00065 todoh.push(*rSupCandGen.InitStatesBegin()); 00066 FD_DF("SupCon: todo push: (" << rPlantGen.SStr(*rPlantGen.InitStatesBegin()) << "|" 00067 << rSupCandGen.SStr(*rSupCandGen.InitStatesBegin()) << ")"); 00068 00069 // process todo stack 00070 while(!todog.empty()) { 00071 // allow for user interrupt 00072 // LoopCallback(); 00073 // allow for user interrupt, incl progress report 00074 FD_WPC(1,2,"TdesControllability(): iterating states"); 00075 // get top element from todo stack 00076 Idx currentg = todog.top(); 00077 Idx currenth = todoh.top(); 00078 todog.pop(); 00079 todoh.pop(); 00080 FD_DF("SupCon: todo pop: (" << rPlantGen.SStr(currentg) << "|" 00081 << rSupCandGen.SStr(currenth) << ")"); 00082 00083 // break on doublets (tmoor 201104) 00084 if(processed.Exists(currenth)) continue; 00085 processed.Insert(currenth); 00086 00087 #ifdef FAUDES_DEBUG_FUNCTION 00088 TransSet::Iterator _titg, _tith; 00089 // print all transitions of current states 00090 FD_DF("SupCon: transitions from current states:"); 00091 for (_titg = rPlantGen.TransRelBegin(currentg); _titg != rPlantGen.TransRelEnd(currentg); ++_titg) 00092 FD_DF("SupCon: g: " << rPlantGen.SStr(_titg->X1) << "-" 00093 << rPlantGen.EStr(_titg->Ev) << "-" << rPlantGen.SStr(_titg->X2)); 00094 for (_tith = rSupCandGen.TransRelBegin(currenth); _tith != rSupCandGen.TransRelEnd(currenth); ++_tith) 00095 FD_DF("SupCon: h: " << rSupCandGen.SStr(_tith->X1) << "-" 00096 << rSupCandGen.EStr(_tith->Ev) << "-" << rSupCandGen.SStr(_tith->X2)); 00097 #endif 00098 00099 // loop vars 00100 TransSet::Iterator tith, tith_end, titg, titg_end; 00101 00102 // test current state ... 00103 bool pass=false; 00104 00105 // 1. figure disabled in the plant g by the loop g x h 00106 EventSet disabled; 00107 tith = rSupCandGen.TransRelBegin(currenth); 00108 tith_end = rSupCandGen.TransRelEnd(currenth); 00109 titg = rPlantGen.TransRelBegin(currentg); 00110 titg_end = rPlantGen.TransRelEnd(currentg); 00111 while( (tith != tith_end) && (titg != titg_end)) { 00112 if(tith->Ev > titg->Ev) { 00113 disabled.Insert(titg->Ev); 00114 ++titg; 00115 } else if(tith->Ev == titg->Ev) { 00116 ++titg; 00117 ++tith; 00118 } else { 00119 ++tith; // cannot happen 00120 } 00121 } 00122 00123 // 2. pass, if all disabled are controllable 00124 if(disabled <= rCAlph) { 00125 pass=true; 00126 } 00127 00128 // 3. is a forcible event enabled for the loop g x h ? 00129 bool fenabled=false; 00130 if(!pass) { 00131 tith = rSupCandGen.TransRelBegin(currenth); 00132 tith_end = rSupCandGen.TransRelEnd(currenth); 00133 titg = rPlantGen.TransRelBegin(currentg); 00134 titg_end = rPlantGen.TransRelEnd(currentg); 00135 while( (tith != tith_end) && (titg != titg_end)) { 00136 if(tith->Ev > titg->Ev) { 00137 ++titg; 00138 } else if(tith->Ev == titg->Ev) { 00139 if(rFAlph.Exists(titg->Ev)) {fenabled=true; break;} 00140 ++titg; 00141 ++tith; 00142 } else { 00143 ++tith; // cannot happen 00144 } 00145 } 00146 } 00147 00148 // 4. pass if all uncontr. disabled events are preempted by a forcible event 00149 if((!pass) && fenabled) { 00150 if(disabled <= rCPAlph) pass=true; 00151 } 00152 00153 // 5. record non-passed as critical 00154 if(!pass) { 00155 critical.Insert(currenth); 00156 FD_DF("SupCon: todo pop: (" << rPlantGen.SStr(currentg) << "|" 00157 << rSupCandGen.SStr(currenth) << "): FAIL"); 00158 continue; 00159 } 00160 00161 // 6. if passed, stack successor state 00162 if(pass) { 00163 // process all h transitions while there could be matching g transitions 00164 titg = rPlantGen.TransRelBegin(currentg); 00165 titg_end = rPlantGen.TransRelEnd(currentg); 00166 tith = rSupCandGen.TransRelBegin(currenth); 00167 tith_end = rSupCandGen.TransRelEnd(currenth); 00168 while ((tith != tith_end) && (titg != titg_end)) { 00169 // increment tith and titg case A: process common events 00170 if(titg->Ev == tith->Ev) { 00171 FD_DF("SupCon: processing common event " << rPlantGen.EStr(titg->Ev)); 00172 // add to todo list if state not processed (tmoor 201104: record next H state on stack) 00173 if(!processed.Exists(tith->X2)) { 00174 todog.push(titg->X2); 00175 todoh.push(tith->X2); 00176 FD_DF("SupCon: todo push: (" << rPlantGen.SStr(titg->X2) << "|" 00177 << rSupCandGen.SStr(tith->X2) << ")"); 00178 } 00179 FD_DF("SupCon: incrementing g and h transrel"); 00180 ++titg; 00181 ++tith; 00182 } 00183 // increment tith and titg case B: process g event that is not enabled in h 00184 else if (titg->Ev < tith->Ev) { 00185 FD_DF("SupCon: incrementing g transrel"); 00186 ++titg; 00187 } 00188 // increment tith and titg case C: process h event that is not enabled in g 00189 else { 00190 FD_DF("SupCon: incrementing h transrel"); // cannot happen 00191 ++tith; 00192 } 00193 } // end while tith and titg 00194 } // end if passed 00195 00196 } //end while todog 00197 00198 00199 // remove all states that have been identified as critical or that have 00200 // been not processed 00201 critical = rSupCandGen.States() - ( processed - critical ); 00202 rSupCandGen.DelStates(critical); 00203 } 00204 00205 00206 00207 00208 00209 00210 // SupTconNBUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, rSpecGen, rCompositionMap, rResGen) 00211 void SupTconNBUnchecked( 00212 const Generator& rPlantGen, 00213 const EventSet& rCAlph, 00214 const EventSet& rFAlph, 00215 const EventSet& rPAlph, 00216 const Generator& rSpecGen, 00217 std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 00218 Generator& rResGen) 00219 { 00220 FD_DF("SupTconNB(" << &rPlantGen << "," << &rSpecGen << ")"); 00221 00222 // PREPARE RESULT: 00223 Generator* pResGen = &rResGen; 00224 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00225 pResGen= rResGen.New(); 00226 } 00227 pResGen->Clear(); 00228 pResGen->Name(CollapsString("SupTconNB(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))")); 00229 pResGen->InjectAlphabet(rPlantGen.Alphabet()); 00230 00231 // controllable events 00232 FD_DF("SupTconNB: controllable events: " << rCAlph.ToString()); 00233 FD_DF("SupTconNB: forcible events: " << rFAlph.ToString()); 00234 FD_DF("SupTconNB: preemptyble events: " << rPAlph.ToString()); 00235 00236 // weackly controllable 00237 EventSet cpalph = rCAlph + rPAlph; 00238 00239 // ALGORITHM: 00240 FD_DF("SupTconNB(): SupConProduct on #" << rPlantGen.Size() << "/ #" << rSpecGen.Size()); 00241 SupConProduct(rPlantGen, cpalph, rSpecGen, rCompositionMap, *pResGen); 00242 00243 00244 // make resulting generator trim until it's fully tdes controllable 00245 while(true) { 00246 if(pResGen->Empty()) break; 00247 Idx state_num = pResGen->Size(); 00248 FD_DF("SupTconNB(): SupConClosed on #" << rPlantGen.Size() << "/ #" << pResGen->Size()); 00249 SupConClosedUnchecked(rPlantGen, cpalph, *pResGen); 00250 FD_DF("SupTconNB(): SupTcon on #" << rPlantGen.Size() << "/ #" << pResGen->Size()); 00251 SupTconUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, cpalph, *pResGen); 00252 FD_DF("SupTconNB(): Trim on #" << pResGen->Size()); 00253 pResGen->Trim(); 00254 if(pResGen->Size() == state_num) break; 00255 } 00256 00257 // convenience state names 00258 if(rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && rResGen.StateNamesEnabled()) 00259 SetComposedStateNames(rPlantGen, rSpecGen, rCompositionMap, *pResGen); 00260 else 00261 pResGen->StateNamesEnabled(false); 00262 00263 // copy result 00264 if(pResGen != &rResGen) { 00265 pResGen->Move(rResGen); 00266 delete pResGen; 00267 } 00268 00269 } 00270 00271 00272 00273 // SupTconNB(rPlantGen, rCAlph, rFAlph, rSpecGen, rResGen) 00274 void SupTconNB( 00275 const Generator& rPlantGen, 00276 const EventSet& rCAlph, 00277 const EventSet& rFAlph, 00278 const EventSet& rPAlph, 00279 const Generator& rSpecGen, 00280 Generator& rResGen) 00281 { 00282 00283 // CONSISTENCY CHECK: 00284 ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSpecGen); 00285 00286 // HELPERS: 00287 std::map< std::pair<Idx,Idx>, Idx> rcmap; 00288 00289 // ALGORITHM: 00290 SupTconNBUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, rSpecGen, rcmap, rResGen); 00291 } 00292 00293 00294 00295 // supcon for Systems 00296 // uses and maintains controllablity from plant 00297 void SupTconNB( 00298 const System& rPlantGen, 00299 const Generator& rSpecGen, 00300 Generator& rResGen) { 00301 00302 // prepare result 00303 Generator* pResGen = &rResGen; 00304 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00305 pResGen= rResGen.New(); 00306 } 00307 00308 // default preemptable but not controllable 00309 EventSet palph; 00310 palph.Insert("tick"); 00311 EventSet calph(rPlantGen.ControllableEvents()); 00312 calph=calph - palph; 00313 00314 // execute 00315 SupTconNB(rPlantGen, calph, rPlantGen.ForcibleEvents(), palph, rSpecGen,*pResGen); 00316 00317 // copy all attributes of input alphabet 00318 pResGen->EventAttributes(rPlantGen.Alphabet()); 00319 00320 // copy result 00321 if(pResGen != &rResGen) { 00322 pResGen->Move(rResGen); 00323 delete pResGen; 00324 } 00325 00326 } 00327 00328 } // name space libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |