sp_executor.cpp

Go to the documentation of this file.
00001 
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   rGen.Copy(*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=mGlobalAttribute.mClocks.Begin(); cit!=mGlobalAttribute.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     return;
00148   }
00149   // set active events/transitions
00150   mAEvents= tGenerator::ActiveEventSet(mCurrentTimedState.State);
00151   mATrans=  tGenerator::ActiveTransSet(mCurrentTimedState.State);
00152   // hypothesis: all time can pass [0,inf)
00153   mETime.SetPositive();
00154   mEInterval.SetPositive();
00155   // hypothesis: no events can occur
00156   mEEvents.Clear();
00157   mDEvents=Alphabet();
00158   mEGuardInterval.clear();
00159   // inspect invariant to restrict enabled time
00160   std::map<Idx,TimeInterval> clockintervalmap=mStateClockIntervalMap[mCurrentTimedState.State];
00161   std::map<Idx,TimeInterval>::const_iterator cit;
00162   for(cit=clockintervalmap.begin(); cit!=clockintervalmap.end(); cit++) {
00163     Idx clock =  cit-> first;
00164     tpTime::Type clockvalue = mCurrentTimedState.ClockValue[clock];
00165     TimeInterval interval = cit->second;
00166     // if a clock violates an invariant constraint return deadlock
00167     if(! interval.In( clockvalue ) ) {
00168       FD_DX("Executor(" << this << ")::ComputeEnabled(): clock " << CStr(cit->first) 
00169         << " at " <<  clockvalue << " violates invariant condition " << interval.Str() );
00170       mETime.SetEmpty();
00171       mEValid=true; 
00172       return;
00173     }
00174     // left shift interval by clock value to obtain an interval relative to current time
00175     interval.PositiveLeftShift(clockvalue);
00176     // intersect with enabled time
00177     mETime.Intersect(interval);
00178   }
00179   FD_DX("Executor(" << this << ")::ComputeEnabled(): invariant is satisfied for " 
00180      << mETime.Str() );
00181   // no events for all time that can pass to begin with ...
00182   mEEvents.Clear();
00183   mEEvents.Name("EnabledEvents");
00184   mDEvents=Alphabet();
00185   mDEvents.Name("DisabledEvents");
00186   mEInterval=mETime;
00187   // iterate over all transitions and check guards
00188   TransSet::Iterator tit;
00189   for(tit=mATrans.Begin(); tit!= mATrans.End(); tit++) {
00190     // hypothesis: transition is enabled for all time
00191     bool enabled=true;
00192     TimeInterval enabledtime;
00193     enabledtime.SetPositive(); 
00194     // check all clocks
00195     std::map<Idx,TimeInterval> clockintervalmap=mTransClockIntervalMap[*tit];
00196     std::map<Idx,TimeInterval>::const_iterator cit;
00197     for(cit=clockintervalmap.begin(); cit!=clockintervalmap.end(); cit++) {
00198       Idx clock =  cit->first;
00199       tpTime::Type clockvalue = mCurrentTimedState.ClockValue[clock];
00200       TimeInterval interval = cit->second;
00201       // reject transition if a clock violates a guard constraint
00202       if(!  interval.In(clockvalue) ) enabled=false;
00203       // left shift interval by clock value to obtain an interval relative to current time
00204       interval.PositiveLeftShift(clockvalue);
00205       // intersect with enabled interval
00206       enabledtime.Intersect(interval);
00207     }
00208     // record guard interval
00209     mEGuardInterval[tit->Ev]=enabledtime;
00210     // intersect with invariant
00211     enabledtime.Intersect(mETime);
00212     // intersect with time hypothesis
00213     if(enabled) {
00214       // easy: intersect enabledtime with mEInterval  
00215       FD_DX("Executor(" << this << ")::ComputeEnabled(): event " << EStr(tit->Ev) 
00216          << " is enabled for " << enabledtime.Str());
00217       mEEvents.Insert(tit->Ev);
00218       mDEvents.Erase(tit->Ev);
00219       mEInterval.Intersect(enabledtime);
00220     } else {
00221       // first compute disabledtime, then intersect
00222       TimeInterval disabledtime;
00223       disabledtime.SetPositive();
00224       if(!enabledtime.Empty()) {
00225         disabledtime.UB(enabledtime.LB());
00226         disabledtime.UBincl(!enabledtime.LBincl());
00227       }
00228       FD_DX("Executor(" << this << ")::ComputeEnabled(): event " << EStr(tit->Ev) 
00229       << " is disabled for " << disabledtime.Str() << " and enabled for " << enabledtime.Str());
00230       mEInterval.Intersect(disabledtime);
00231     }
00232   }  // loop transitions
00233   FD_DX("Executor(" << this << ")::ComputeEnabled(): e/d stutus constant on "
00234     << mEInterval.Str() );    
00235   mEValid=true; 
00236 }
00237 
00238 // EnabledTime(void)  
00239 const TimeInterval& Executor::EnabledTime(void) const {
00240   if(!mEValid) ComputeEnabled();
00241   return mETime;
00242 }
00243 
00244 // EnabledEvents(void)  
00245 const EventSet& Executor::EnabledEvents(void) const {
00246   if(!mEValid) ComputeEnabled();
00247   return mEEvents;
00248 }
00249 
00250 // DisabledEvents(void)  
00251 const EventSet& Executor::DisabledEvents(void) const {
00252   if(!mEValid) ComputeEnabled();
00253   return mDEvents;
00254 }
00255 
00256 // EnabledInterval(void)  
00257 const TimeInterval& Executor::EnabledInterval(void) const {
00258   if(!mEValid) ComputeEnabled();
00259   return mEInterval;
00260 }
00261 
00262 // ActiveEventSet(void)  
00263 const EventSet& Executor::ActiveEventSet(void) const {
00264   if(!mEValid) ComputeEnabled();
00265   return mAEvents;
00266 }
00267 
00268 // ActiveTransSet(void)  
00269 const TransSet& Executor::ActiveTransSet(void) const {
00270   if(!mEValid) ComputeEnabled();
00271   return mATrans;
00272 }
00273 
00274 // EnabledEventInterval(event)   
00275 TimeInterval Executor::EnabledEventTime(Idx event) const {
00276   if(!mEValid) ComputeEnabled();
00277   TimeInterval res;  
00278   std::map<Idx,TimeInterval>::const_iterator eit;
00279   eit=mEGuardInterval.find(event);
00280   if(eit!= mEGuardInterval.end()) {
00281     res = eit->second;
00282     res.Intersect(mETime);
00283     return res;
00284   }
00285   if(Alphabet().Exists(event)) {
00286      res.SetEmpty();
00287      return res;
00288   }
00289   res.SetPositive();
00290   return res;
00291 }
00292 
00293 // EnabledGuardInterval(event)   
00294 TimeInterval Executor::EnabledGuardTime(Idx event) const {
00295   if(!mEValid) ComputeEnabled();
00296   std::map<Idx,TimeInterval>::const_iterator eit;
00297   eit=mEGuardInterval.find(event);
00298   if(eit!= mEGuardInterval.end()) return eit->second;
00299   TimeInterval res;  
00300   res.SetEmpty();
00301   if(Alphabet().Exists(event)) return res;
00302   res.SetPositive();
00303   return res;
00304 }
00305 
00306 // ExecuteTime(time) 
00307 bool Executor::ExecuteTime(tpTime::Type time) {
00308   if(mCurrentTime>=tpTime::Max) return false;
00309   if(!mEValid) ComputeEnabled();
00310   if(!mETime.In(time) && !((time==tpTime::Max) && mETime.UBinf()) ) {
00311     FD_DX("Executor(" << this << ")::ExecuteTime: execution of  " << time 
00312        << " conflicts with enabled status " );
00313     return false; 
00314   }
00315   FD_DX("Executor(" << this << ")::ExecuteTime(" << time << ")");
00316   // progress current time
00317   mCurrentTime += time;
00318   // progres clocks
00319   ClockSet::Iterator cit;
00320   for(cit=ClocksBegin(); cit!=ClocksEnd(); cit++) 
00321     mCurrentTimedState.ClockValue[*cit]= mCurrentTimedState.ClockValue[*cit]+time;  
00322   // fix infinity
00323   if(time==tpTime::Max) {
00324     mCurrentTime=tpTime::Max;
00325     for(cit=ClocksBegin(); cit!=ClocksEnd(); cit++) 
00326       mCurrentTimedState.ClockValue[*cit]= tpTime::Max;
00327     mEValid=false;
00328   }  
00329   // progress enabled interval or invalidate enabled status 
00330   if(mEInterval.In(time) && mEValid) {
00331     mEInterval.PositiveLeftShift(time);
00332     mETime.PositiveLeftShift(time);
00333     std::map<Idx,TimeInterval>::iterator iit;
00334     for(iit=mEGuardInterval.begin();iit != mEGuardInterval.end(); iit++) {
00335       iit->second.PositiveLeftShift(time);
00336     }
00337   } else {
00338     mEValid=false;
00339   }
00340   return true;
00341 }
00342 
00343 // ExecuteEvent(event) 
00344 bool Executor::ExecuteEvent(Idx event) {
00345   if(mCurrentTime>=tpTime::Max) return false;
00346   if(!mEValid) ComputeEnabled();
00347   if(!mEEvents.Exists(event)) {
00348     FD_DX("Executor(" << this << ")::ExecuteEvent: execution of event " << EStr(event) 
00349        << " conflicts with enabled status " );
00350     return false; 
00351   }
00352   FD_DX("Executor(" << this << ")::ExecuteEvent(" << EStr(event) << ")");
00353   // pick transition
00354   TransSet::Iterator tit=TransRelBegin(mCurrentTimedState.State,event);
00355   // TODO: invalid iterator error     
00356   // execute resets
00357   ClockSet resets=Resets(*tit);
00358   ClockSet::Iterator cit;
00359   for(cit = resets.Begin(); cit!=resets.End(); cit++) 
00360     mCurrentTimedState.ClockValue[*cit]=0;
00361   // progress state
00362   mCurrentTimedState.State=tit->X2;
00363   // progress current time
00364   mCurrentStep += 1;
00365   // invalidate
00366   mEValid=false;
00367   return true;
00368 }  
00369 
00370 
00371 // CurrentTimedState(tstate)
00372 bool Executor::CurrentTimedState(const TimedState& tstate) {
00373   // test consitency
00374   if(!ExistsState(tstate.State)) return false;
00375   if(tstate.ClockValue.size()!=ClocksSize()) return false;
00376   std::map<Idx,tpTime::Type>::const_iterator cvit;
00377   for(cvit=tstate.ClockValue.begin(); cvit!=tstate.ClockValue.end(); cvit++)
00378     if(!ExistsClock(cvit->first)) return false;
00379   // set state
00380   mCurrentTimedState=tstate;
00381   mEValid=false;
00382   return true; 
00383 }
00384   
00385 // CurrentTimedState()
00386 const Executor::TimedState& Executor::CurrentTimedState(void) const {
00387   return mCurrentTimedState;
00388 }
00389   
00390 // CurrentState(idx)
00391 bool Executor::CurrentState(Idx index) {
00392   if(!ExistsState(index)) return false;
00393   mCurrentTimedState.State=index;
00394   mEValid=false;
00395   return true;
00396 }
00397   
00398 // CurrentState()
00399 Idx Executor::CurrentState(void) const {
00400   return mCurrentTimedState.State;
00401 }
00402   
00403 // CurrentClockValue(idx,time)
00404 bool Executor::CurrentClockValue(Idx index, tpTime::Type time) {
00405   if(!ExistsClock(index)) return false;
00406   mCurrentTimedState.ClockValue[index]=time;
00407   mEValid=false;
00408   return true;
00409 }
00410   
00411 // CurrentClockValue(idx)
00412 tpTime::Type Executor::CurrentClockValue(Idx index) const {
00413   std::map<Idx,tpTime::Type>::const_iterator cvit;
00414   cvit=mCurrentTimedState.ClockValue.find(index);
00415   if(cvit==mCurrentTimedState.ClockValue.end()) {}; // todo: error
00416   return cvit->second;
00417 }
00418   
00419 // CurrentTime(time)
00420 void Executor::CurrentTime(tpTime::Type time) {
00421   mCurrentTime=time;
00422   mEValid=false;
00423 }
00424   
00425 // CurrentTime()
00426 tpTime::Type Executor::CurrentTime(void) const {
00427   return mCurrentTime;
00428 }
00429   
00430 // CurrentStep(time)
00431 void Executor::CurrentStep(int step) {
00432   mCurrentStep=step;
00433   mEValid=false;
00434 }
00435   
00436 // CurrentStep()
00437 int Executor::CurrentStep(void) const {
00438   return mCurrentStep;
00439 }
00440   
00441 // IsDeadlocked() 
00442 bool Executor::IsDeadlocked(void) const {
00443   if(!mEValid) ComputeEnabled();
00444   if(!mEEvents.Empty()) return false;
00445   if(!(mETime.UB()<=0)) return false;
00446   return true;
00447 }
00448 
00449 // TSStr(tstate)
00450 std::string Executor::TSStr(const TimedState& tstate) const {
00451   std::stringstream res;
00452   res << "(state " << SStr(tstate.State); 
00453   if(Generator().ExistsMarkedState(tstate.State))  res << " [marked]";
00454   res << ")  (clocks";
00455   ClockSet::Iterator cit;
00456   for(cit=ClocksBegin();cit!=ClocksEnd();cit++){
00457     res << " " << CStr(*cit) << "=";
00458     std::map<Idx,tpTime::Type>::const_iterator cvit=tstate.ClockValue.find(*cit);
00459     if(cvit!=tstate.ClockValue.end()) 
00460       res << cvit->second;
00461     else
00462       res << "undef";
00463   }
00464   res << ")";
00465   return res.str();
00466 }
00467 
00468 // CurrentTimedStateStr()
00469 std::string Executor::CurrentTimedStateStr(void) const {
00470   return TSStr(mCurrentTimedState);
00471 }
00472 
00473 // TEStr(tevent)
00474 std::string Executor::TEStr(const TimedEvent& tevent) const {
00475   std::stringstream res;
00476   res << "(" << EStr(tevent.Event) << " at " << tevent.Time << ")";
00477   return res.str();
00478 }
00479 
00480 // EStr(event)
00481 std::string Executor::EStr(Idx event) const {
00482   return tGenerator::EStr(event);
00483 }
00484 
00485 // CStr(clock)
00486 std::string Executor::CStr(Idx clock) const {
00487   return tGenerator::CStr(clock);
00488 }
00489 
00490 // SStr(clock)
00491 std::string Executor::SStr(Idx state) const {
00492   return tGenerator::SStr(state);
00493 }
00494 
00495 
00496 } // namespace faudes
00497 
00498 

Generated on Mon Nov 10 08:13:15 2008 for libFAUDES 2.11v by  doxygen 1.4.4