libFAUDES

Sections

Index

sp_executor.cpp

Go to the documentation of this file.
00001 /** @file sp_executor.cpp Execute transitions in a timed generator  */
00002 
00003 /* 
00004    FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2007  Ruediger Berndt
00007    Copyright (C) 2007  Thomas Moor
00008    Exclusive copyright is granted to Klaus Schmidt
00009   
00010 */
00011 
00012 
00013 #include "sp_executor.h"
00014 
00015 namespace faudes {
00016 
00017 
00018 // Executor(void)
00019 Executor::Executor(void) : tGenerator() {
00020   FD_DX("Executor(" << this << ")::Executor()");
00021   InsInitState("init");
00022   Compile();
00023 }
00024 
00025 // Exector(rGen)
00026 Executor::Executor(const tGenerator& rGen) : tGenerator(rGen) {
00027   FD_DX("Executor(" << this << ")::Executor(rGen)");
00028   Compile();
00029 }  
00030 
00031 // Exector(filename)
00032 Executor::Executor(const std::string& rFileName) : tGenerator() {
00033   FD_DX("Executor(" << this << ")::Executor("<< rFileName <<")");
00034   Read(rFileName);
00035 }  
00036 
00037 // Read(filename)
00038 void Executor::Read(const std::string& rFileName) {
00039   FD_DX("Executor(" << this << ")::Read("<< rFileName <<")");
00040   Clear();
00041   tGenerator::Read(rFileName);
00042   Compile();
00043 }  
00044 
00045 // Read(rTr)
00046 void Executor::Read(TokenReader& rTr) {
00047   FD_DX("Executor(" << this << ")::Read(rTr)");
00048   Clear();  
00049   tGenerator::Read(rTr);
00050   Compile();
00051 }  
00052 
00053 // Generator()
00054 const tGenerator& Executor::Generator(void) const{
00055   return *this;
00056 }
00057 
00058 // Generator(rGen)
00059 void Executor::Generator(const tGenerator& rGen) {
00060   FD_DX("Executor::Generator(" << &rGen << ")");
00061   Assign(*this);
00062   Compile();
00063 }  
00064 
00065 
00066 // Compile()
00067 void Executor::Compile(void) {
00068   FD_DX("Executor(" << this << ")::Compile()");
00069   // throw exception on non deterministic generator
00070   if(!IsDeterministic()) {
00071     std::stringstream errstr;
00072     errstr << "nondeterministic generator in simulation" << std::endl;
00073     throw Exception("Executor::Compile", errstr.str(), 501);
00074   }
00075   // compile guards
00076   TransSet::Iterator tit;
00077   for(tit=TransRelBegin(); tit!= TransRelEnd(); tit++) {
00078     FD_DX("Executor(" << this << ")::Compile(): trans " << TStr(*tit));
00079     TimeConstraint guard=Guard(*tit);
00080     std::map<Idx,TimeInterval> guardtime;
00081     ClockSet aclocks=guard.ActiveClocks();
00082     ClockSet::Iterator cit;
00083     for(cit=aclocks.Begin(); cit!= aclocks.End(); cit++) 
00084       guardtime[*cit]=guard.Interval(*cit);
00085     mTransClockIntervalMap[*tit]=guardtime;
00086   }
00087   // compile invariants
00088   StateSet::Iterator sit;
00089   for(sit=StatesBegin(); sit!= StatesEnd(); sit++) {
00090     FD_DX("Executor(" << this << ")::Compile(): state " << SStr(*sit));
00091     TimeConstraint invariant=Invariant(*sit);
00092     std::map<Idx,TimeInterval> invtime;
00093     ClockSet aclocks=invariant.ActiveClocks();
00094     ClockSet::Iterator cit;
00095     for(cit=aclocks.Begin(); cit!= aclocks.End(); cit++) 
00096       invtime[*cit]=invariant.Interval(*cit);
00097     mStateClockIntervalMap[*sit]=invtime;
00098   }
00099   // get ready
00100   Reset();
00101   FD_DX("Executor(" << this << ")::Compile(): done");
00102 }
00103 
00104 // Clear()
00105 void Executor::Clear(void) {
00106   FD_DX("Executor(" << this << ")::Clear(): invalid executor");
00107   tGenerator::Clear();
00108   mCurrentTimedState.State=0;
00109   mCurrentTimedState.ClockValue.clear();
00110   mCurrentTime=0;
00111   mCurrentStep=0;
00112   mEValid=false;
00113 }
00114 
00115 // Reset()
00116 void Executor::Reset(void) {
00117   mCurrentTimedState.State=*InitStatesBegin();
00118   mCurrentTimedState.ClockValue.clear();
00119   ClockSet::Iterator cit;
00120   for(cit=GlobalAttribute().mClocks.Begin(); cit!=GlobalAttribute().mClocks.End(); cit++)
00121     mCurrentTimedState.ClockValue[*cit]=0;
00122   mCurrentTime=0;
00123   mCurrentStep=0;
00124   mEValid=false;
00125 }
00126 
00127 
00128 // ComputeEnabled() fake const
00129 void Executor::ComputeEnabled(void) const {
00130   Executor* fakeconst = const_cast<Executor*>(this);
00131   fakeconst->ComputeEnabledNonConst();
00132 }
00133 
00134 // ComputeEnabledNoneConst()
00135 void Executor::ComputeEnabledNonConst(void) {
00136   FD_DX("Executor(" << this << ")::ComputeEnabled()");
00137   // time is up: clear all
00138   if(mCurrentTime>=tpTime::Max) {
00139     mAEvents.Clear();
00140     mATrans.Clear();
00141     mETime.SetEmpty();
00142     mEInterval.SetEmpty();
00143     mEEvents.Clear();
00144     mDEvents=Alphabet();
00145     mEGuardInterval.clear();
00146     mEValid=true;
00147     FD_DX("Executor(" << this << ")::ComputeEnabled(): time is up");
00148     return;
00149   }
00150   // set active events/transitions
00151   mAEvents= tGenerator::ActiveEventSet(mCurrentTimedState.State);
00152   mATrans=  tGenerator::ActiveTransSet(mCurrentTimedState.State);
00153   // hypothesis: all time can pass [0,inf)
00154   mETime.SetPositive();
00155   mEInterval.SetPositive();
00156   // hypothesis: no events can occur
00157   mEEvents.Clear();
00158   mDEvents=Alphabet();
00159   mEGuardInterval.clear();
00160   // inspect invariant to restrict enabled time
00161   std::map<Idx,TimeInterval> clockintervalmap=mStateClockIntervalMap[mCurrentTimedState.State];
00162   std::map<Idx,TimeInterval>::const_iterator cit;
00163   for(cit=clockintervalmap.begin(); cit!=clockintervalmap.end(); cit++) {
00164     Idx clock =  cit-> first;
00165     tpTime::Type clockvalue = mCurrentTimedState.ClockValue[clock];
00166     TimeInterval interval = cit->second;
00167     // if a clock violates an invariant constraint return deadlock
00168     if(! interval.In( clockvalue ) ) {
00169       FD_DX("Executor(" << this << ")::ComputeEnabled(): clock " << CStr(cit->first) 
00170         << " at " <<  clockvalue << " violates invariant condition " << interval.Str() );
00171       mETime.SetEmpty();
00172       mEValid=true; 
00173       return;
00174     }
00175     // left shift interval by clock value to obtain an interval relative to current time
00176     interval.PositiveLeftShift(clockvalue);
00177     // intersect with enabled time
00178     mETime.Intersect(interval);
00179   }
00180   FD_DX("Executor(" << this << ")::ComputeEnabled(): invariant is satisfied for " 
00181      << mETime.Str() );
00182   // no events for all time that can pass to begin with ...
00183   mEEvents.Clear();
00184   mEEvents.Name("EnabledEvents");
00185   mDEvents=Alphabet();
00186   mDEvents.Name("DisabledEvents");
00187   mEInterval=mETime;
00188   // iterate over all transitions and check guards
00189   TransSet::Iterator tit;
00190   for(tit=mATrans.Begin(); tit!= mATrans.End(); tit++) {
00191     // hypothesis: transition is enabled for all time
00192     bool enabled=true;
00193     TimeInterval enabledtime;
00194     enabledtime.SetPositive(); 
00195     // check all clocks
00196     std::map<Idx,TimeInterval> clockintervalmap=mTransClockIntervalMap[*tit];
00197     std::map<Idx,TimeInterval>::const_iterator cit;
00198     for(cit=clockintervalmap.begin(); cit!=clockintervalmap.end(); cit++) {
00199       Idx clock =  cit->first;
00200       tpTime::Type clockvalue = mCurrentTimedState.ClockValue[clock];
00201       TimeInterval interval = cit->second;
00202       // reject transition if a clock violates a guard constraint
00203       if(!  interval.In(clockvalue) ) enabled=false;
00204       // left shift interval by clock value to obtain an interval relative to current time
00205       interval.PositiveLeftShift(clockvalue);
00206       // intersect with enabled interval
00207       enabledtime.Intersect(interval);
00208     }
00209     // record guard interval
00210     mEGuardInterval[tit->Ev]=enabledtime;
00211     // intersect with invariant
00212     enabledtime.Intersect(mETime);
00213     // intersect with time hypothesis
00214     if(enabled) {
00215       // easy: intersect enabledtime with mEInterval  
00216       FD_DX("Executor(" << this << ")::ComputeEnabled(): event " << EStr(tit->Ev) 
00217          << " is enabled for " << enabledtime.Str());
00218       mEEvents.Insert(tit->Ev);
00219       mDEvents.Erase(tit->Ev);
00220       mEInterval.Intersect(enabledtime);
00221     } else {
00222       // first compute disabledtime, then intersect
00223       TimeInterval disabledtime;
00224       disabledtime.SetPositive();
00225       if(!enabledtime.Empty()) {
00226         disabledtime.UB(enabledtime.LB());
00227         disabledtime.UBincl(!enabledtime.LBincl());
00228       }
00229       FD_DX("Executor(" << this << ")::ComputeEnabled(): event " << EStr(tit->Ev) 
00230       << " is disabled for " << disabledtime.Str() << " and enabled for " << enabledtime.Str());
00231       mEInterval.Intersect(disabledtime);
00232     }
00233   }  // loop transitions
00234   FD_DX("Executor(" << this << ")::ComputeEnabled(): e/d status constant on "
00235     << mEInterval.Str() );    
00236   mEValid=true; 
00237 }
00238 
00239 // EnabledTime(void)  
00240 const TimeInterval& Executor::EnabledTime(void) const {
00241   if(!mEValid) ComputeEnabled();
00242   return mETime;
00243 }
00244 
00245 // EnabledEvents(void)  
00246 const EventSet& Executor::EnabledEvents(void) const {
00247   if(!mEValid) ComputeEnabled();
00248   return mEEvents;
00249 }
00250 
00251 // DisabledEvents(void)  
00252 const EventSet& Executor::DisabledEvents(void) const {
00253   if(!mEValid) ComputeEnabled();
00254   return mDEvents;
00255 }
00256 
00257 // EnabledInterval(void)  
00258 const TimeInterval& Executor::EnabledInterval(void) const {
00259   if(!mEValid) ComputeEnabled();
00260   return mEInterval;
00261 }
00262 
00263 // ActiveEventSet(void)  
00264 const EventSet& Executor::ActiveEventSet(void) const {
00265   if(!mEValid) ComputeEnabled();
00266   return mAEvents;
00267 }
00268 
00269 // ActiveTransSet(void)  
00270 const TransSet& Executor::ActiveTransSet(void) const {
00271   if(!mEValid) ComputeEnabled();
00272   return mATrans;
00273 }
00274 
00275 // EnabledEventInterval(event)   
00276 TimeInterval Executor::EnabledEventTime(Idx event) const {
00277   if(!mEValid) ComputeEnabled();
00278   TimeInterval res;  
00279   std::map<Idx,TimeInterval>::const_iterator eit;
00280   eit=mEGuardInterval.find(event);
00281   if(eit!= mEGuardInterval.end()) {
00282     res = eit->second;
00283     res.Intersect(mETime);
00284     return res;
00285   }
00286   if(Alphabet().Exists(event)) {
00287      res.SetEmpty();
00288      return res;
00289   }
00290   res.SetPositive();
00291   return res;
00292 }
00293 
00294 // EnabledGuardInterval(event)   
00295 TimeInterval Executor::EnabledGuardTime(Idx event) const {
00296   if(!mEValid) ComputeEnabled();
00297   std::map<Idx,TimeInterval>::const_iterator eit;
00298   eit=mEGuardInterval.find(event);
00299   if(eit!= mEGuardInterval.end()) return eit->second;
00300   TimeInterval res;  
00301   res.SetEmpty();
00302   if(Alphabet().Exists(event)) return res;
00303   res.SetPositive();
00304   return res;
00305 }
00306 
00307 // ExecuteTime(time) 
00308 bool Executor::ExecuteTime(tpTime::Type time) {
00309   if(mCurrentTime>=tpTime::Max) return false;
00310   if(!mEValid) ComputeEnabled();
00311   if(!mETime.In(time) && !((time==tpTime::Max) && mETime.UBinf()) ) {
00312     FD_DX("Executor(" << this << ")::ExecuteTime: execution of  " << time 
00313        << " conflicts with enabled status " );
00314     return false; 
00315   }
00316   FD_DX("Executor(" << this << ")::ExecuteTime(" << time << ")");
00317   // progress current time
00318   mCurrentTime += time;
00319   // progres clocks
00320   ClockSet::Iterator cit;
00321   for(cit=ClocksBegin(); cit!=ClocksEnd(); cit++) 
00322     mCurrentTimedState.ClockValue[*cit]= mCurrentTimedState.ClockValue[*cit]+time;  
00323   // fix infinity
00324   if(time==tpTime::Max) {
00325     mCurrentTime=tpTime::Max;
00326     for(cit=ClocksBegin(); cit!=ClocksEnd(); cit++) 
00327       mCurrentTimedState.ClockValue[*cit]= tpTime::Max;
00328     mEValid=false;
00329   }  
00330   // progress enabled interval or invalidate enabled status 
00331   if(mEInterval.In(time) && mEValid) {
00332     mEInterval.PositiveLeftShift(time);
00333     mETime.PositiveLeftShift(time);
00334     std::map<Idx,TimeInterval>::iterator iit;
00335     for(iit=mEGuardInterval.begin();iit != mEGuardInterval.end(); iit++) {
00336       iit->second.PositiveLeftShift(time);
00337     }
00338   } else {
00339     mEValid=false;
00340   }
00341   return true;
00342 }
00343 
00344 // ExecuteEvent(event) 
00345 bool Executor::ExecuteEvent(Idx event) {
00346   if(mCurrentTime>=tpTime::Max) return false;
00347   if(!mEValid) ComputeEnabled();
00348   if(!mEEvents.Exists(event)) {
00349     FD_DX("Executor(" << this << ")::ExecuteEvent: execution of event " << EStr(event) 
00350        << " conflicts with enabled status " );
00351     return false; 
00352   }
00353   FD_DX("Executor(" << this << ")::ExecuteEvent(" << EStr(event) << ")");
00354   // pick transition
00355   TransSet::Iterator tit=TransRelBegin(mCurrentTimedState.State,event);
00356   // TODO: invalid iterator error     
00357   // execute resets
00358   ClockSet resets=Resets(*tit);
00359   ClockSet::Iterator cit;
00360   for(cit = resets.Begin(); cit!=resets.End(); cit++) 
00361     mCurrentTimedState.ClockValue[*cit]=0;
00362   // progress state
00363   mCurrentTimedState.State=tit->X2;
00364   // progress current time
00365   mCurrentStep += 1;
00366   // invalidate
00367   mEValid=false;
00368   return true;
00369 }  
00370 
00371 
00372 // CurrentTimedState(tstate)
00373 bool Executor::CurrentTimedState(const TimedState& tstate) {
00374   // test consitency
00375   if(!ExistsState(tstate.State)) return false;
00376   if(tstate.ClockValue.size()!=ClocksSize()) return false;
00377   std::map<Idx,tpTime::Type>::const_iterator cvit;
00378   for(cvit=tstate.ClockValue.begin(); cvit!=tstate.ClockValue.end(); cvit++)
00379     if(!ExistsClock(cvit->first)) return false;
00380   // set state
00381   mCurrentTimedState=tstate;
00382   mEValid=false;
00383   return true; 
00384 }
00385   
00386 // CurrentTimedState()
00387 const Executor::TimedState& Executor::CurrentTimedState(void) const {
00388   return mCurrentTimedState;
00389 }
00390   
00391 // CurrentState(idx)
00392 bool Executor::CurrentState(Idx index) {
00393   if(!ExistsState(index)) return false;
00394   mCurrentTimedState.State=index;
00395   mEValid=false;
00396   return true;
00397 }
00398   
00399 // CurrentState()
00400 Idx Executor::CurrentState(void) const {
00401   return mCurrentTimedState.State;
00402 }
00403   
00404 // CurrentClockValue(idx,time)
00405 bool Executor::CurrentClockValue(Idx index, tpTime::Type time) {
00406   if(!ExistsClock(index)) return false;
00407   mCurrentTimedState.ClockValue[index]=time;
00408   mEValid=false;
00409   return true;
00410 }
00411   
00412 // CurrentClockValue(idx)
00413 tpTime::Type Executor::CurrentClockValue(Idx index) const {
00414   std::map<Idx,tpTime::Type>::const_iterator cvit;
00415   cvit=mCurrentTimedState.ClockValue.find(index);
00416   if(cvit==mCurrentTimedState.ClockValue.end()) {}; // todo: error
00417   return cvit->second;
00418 }
00419   
00420 // CurrentTime(time)
00421 void Executor::CurrentTime(tpTime::Type time) {
00422   mCurrentTime=time;
00423   mEValid=false;
00424 }
00425   
00426 // CurrentTime()
00427 tpTime::Type Executor::CurrentTime(void) const {
00428   return mCurrentTime;
00429 }
00430   
00431 // CurrentStep(time)
00432 void Executor::CurrentStep(int step) {
00433   mCurrentStep=step;
00434   mEValid=false;
00435 }
00436   
00437 // CurrentStep()
00438 int Executor::CurrentStep(void) const {
00439   return mCurrentStep;
00440 }
00441   
00442 // IsDeadlocked() 
00443 bool Executor::IsDeadlocked(void) const {
00444   if(!mEValid) ComputeEnabled();
00445   if(!mEEvents.Empty()) return false;
00446   if(!(mETime.UB()<=0)) return false;
00447   return true;
00448 }
00449 
00450 // TSStr(tstate)
00451 std::string Executor::TSStr(const TimedState& tstate) const {
00452   std::stringstream res;
00453   res << "(state " << SStr(tstate.State); 
00454   if(Generator().ExistsMarkedState(tstate.State))  res << " [marked]";
00455   res << ")  (clocks";
00456   ClockSet::Iterator cit;
00457   for(cit=ClocksBegin();cit!=ClocksEnd();cit++){
00458     res << " " << CStr(*cit) << "=";
00459     std::map<Idx,tpTime::Type>::const_iterator cvit=tstate.ClockValue.find(*cit);
00460     if(cvit!=tstate.ClockValue.end()) 
00461       res << cvit->second;
00462     else
00463       res << "undef";
00464   }
00465   res << ")";
00466   return res.str();
00467 }
00468 
00469 // CurrentTimedStateStr()
00470 std::string Executor::CurrentTimedStateStr(void) const {
00471   return TSStr(mCurrentTimedState);
00472 }
00473 
00474 // TEStr(tevent)
00475 std::string Executor::TEStr(const TimedEvent& tevent) const {
00476   std::stringstream res;
00477   res << "(" << EStr(tevent.Event) << " at " << tevent.Time << ")";
00478   return res.str();
00479 }
00480 
00481 // EStr(event)
00482 std::string Executor::EStr(Idx event) const {
00483   return tGenerator::EStr(event);
00484 }
00485 
00486 // CStr(clock)
00487 std::string Executor::CStr(Idx clock) const {
00488   return tGenerator::CStr(clock);
00489 }
00490 
00491 // SStr(clock)
00492 std::string Executor::SStr(Idx state) const {
00493   return tGenerator::SStr(state);
00494 }
00495 
00496 
00497 } // namespace faudes
00498 
00499 

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6