syn_tsupcon.cpp

Go 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