About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

sp_plpexecutor.cpp

Go to the documentation of this file.
00001 /** @file sp_plpexecutor.cpp Executor that proposes transitions to execute */
00002 
00003 /* 
00004    FAU Discrete Event System Simulator 
00005 
00006    Copyright (C) 2007  Christoph Doerr
00007    Copyright (C) 2008  Thomas Moor
00008    Exclusive copyright is granted to Thomas Moor
00009 
00010 */
00011 
00012 #include "sp_plpexecutor.h"
00013 #include <cmath>
00014 #include <ctime>
00015 
00016 namespace faudes {
00017 
00018 // std faudes type
00019 FAUDES_TYPE_IMPLEMENTATION(ProposingExecutor, ProposingExecutor, ParallelExecutor)
00020 
00021 // constructor
00022 ProposingExecutor::ProposingExecutor(void) : LoggingExecutor() { 
00023   mPValid=false;
00024 }
00025 
00026 // copy constructor
00027 ProposingExecutor::ProposingExecutor(const ProposingExecutor& rOther) : LoggingExecutor() 
00028 { 
00029   mPValid=false;
00030   Assign(rOther);
00031 }
00032 
00033 // clear static data
00034 void ProposingExecutor::Clear(void){
00035   LoggingExecutor::Clear();
00036   mSimEvents.Clear();
00037   mPValid=false;
00038 }
00039 
00040 // DoAssign(other)
00041 void ProposingExecutor::DoAssign(const ProposingExecutor& rOther) {
00042   FD_DX("ProposingExecutor(" << this << ")::DoAssign(other)");
00043   // my members
00044   mSimEvents.Assign(rOther.mSimEvents);
00045   // base
00046   LoggingExecutor::DoAssign(rOther);
00047 }
00048 
00049 // lookup event attribute
00050 const SimEventAttribute& ProposingExecutor::EventAttribute(Idx index) const {
00051   return mSimEvents.Attribute(index);
00052 }
00053      
00054 // set simulation event attribute
00055 void ProposingExecutor::EventAttribute(Idx index, const SimEventAttribute& rAttr) {
00056   mSimEvents.Attribute(index,rAttr);
00057 }
00058 
00059 // set execution properties from attributed event set
00060 void ProposingExecutor::Alphabet(const sEventSet& rAlphabet) {
00061   // set ...
00062   mSimEvents=rAlphabet;
00063   // ... and ensure to cover all relevant alphabet
00064   mSimEvents.InsertSet(LoggingExecutor::Alphabet()); 
00065 }
00066 
00067 // clear dynamic data (reset state) 
00068 void ProposingExecutor::ResetProposer(long int seed){
00069   FD_DS("ProposingExecutor::ResetProposer()");
00070   //Initialize random number generator with computer system time as seed
00071   if(seed == 0) seed = static_cast<long>(time(NULL));
00072   ran_init(seed);
00073   // schedule all events
00074   EventSet::Iterator eit;
00075   const EventSet aevents=ActiveEventSet(CurrentParallelState());
00076   for(eit=Alphabet().Begin(); eit!=Alphabet().End(); ++eit){
00077     SimEventAttribute* pattr= mSimEvents.Attributep(*eit);
00078     pattr->mScheduledFor=tpTime::UnDef;
00079     pattr->mDelayFor=tpTime::UnDef;
00080     pattr->mExpiresAt=0;
00081     if(pattr->IsPriority()) continue;
00082     if(!pattr->IsStochastic()) continue;
00083     Schedule(*eit,pattr);
00084   }
00085   // invalidate proposal
00086   mPValid=false;
00087   FD_DS("ProposingExecutor::ResetProposer(): done");
00088 }
00089 
00090 // clear dynamic data (reset state) 
00091 void ProposingExecutor::Reset(long int seed){
00092   FD_DS("ProposingExecutor::Reset()");
00093   LoggingExecutor::Reset();
00094   mSimEvents.InsertSet(LoggingExecutor::Alphabet()); 
00095   ResetProposer(seed);
00096   FD_DS("ProposingExecutor::Reset(): done");
00097 }
00098 
00099 
00100 //EventStatesToString
00101 std::string ProposingExecutor::EventStatesToString() const {
00102   std::stringstream retstr;
00103   EventSet::Iterator eit;
00104   for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit){
00105     const SimEventAttribute attr= mSimEvents.Attribute(*eit);
00106     retstr<< "% simulation state: "<< ExpandString(mSimEvents.Str(*eit),FD_NAMELEN) << ": ";
00107     retstr<< "enabled: " << ExpandString(EnabledEventTime(*eit).Str(),FD_NAMELEN) << ": ";
00108     if(attr.IsPriority()) {
00109       retstr<< "priority: " << attr.Priority().mPriority;
00110     }
00111     if(attr.IsStochastic()) {
00112       retstr<< "stochastic: " << SimStochasticEventAttribute::TStr(attr.Stochastic().mType) ;
00113       retstr<< " scheduled " << tpTime::Str(attr.mScheduledFor);
00114       retstr<< " expires " << tpTime::Str(attr.mExpiresAt);
00115       retstr<< " delta " << tpTime::Str(attr.mDelayFor);
00116     }
00117     if( eit!= --mSimEvents.End()) {
00118       retstr << std::endl;
00119     }
00120   }
00121   return retstr.str();
00122 }
00123 
00124 
00125 
00126 //ExecuteTime: todo: may hang + performance issue 
00127 bool ProposingExecutor::ExecuteTime(tpTime::Type duration){
00128   FD_DS("ProposingExecutor::ExecuteTime(): LoggingExecutor to execute time "<< duration);
00129   if(!LoggingExecutor::ExecuteTime(duration)) return false;
00130   // update stochastic event state
00131   EventSet::Iterator eit;
00132   for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit) {
00133     SimEventAttribute* pattr= mSimEvents.Attributep(*eit);
00134     // stochastic only
00135     if(!pattr->IsStochastic()) continue;
00136     // shift relative time: schedule/expiring time
00137     if(pattr->mScheduledFor!=tpTime::UnDef) 
00138     if(pattr->mScheduledFor!=tpTime::Max) 
00139       pattr->mScheduledFor -= duration;
00140     if(pattr->mExpiresAt!=tpTime::UnDef) 
00141     if(pattr->mExpiresAt!=tpTime::Max) 
00142       pattr->mExpiresAt -= duration;
00143     // shift reference interval for type trigger
00144     if(pattr->Stochastic().mType==SimStochasticEventAttribute::Trigger) {
00145       pattr->mReferenceInterval.PositiveLeftShift(duration);
00146     }
00147     // shift reference interval for type delay
00148     if(pattr->Stochastic().mType==SimStochasticEventAttribute::Delay) {
00149       if(!pattr->mReferenceInterval.Empty()) {
00150         tpTime::Type delay = duration - pattr->mReferenceInterval.LB();
00151         if(delay>0) pattr->mDelayFor-=delay;
00152         pattr->mReferenceInterval.PositiveLeftShift(duration);
00153       }
00154     }
00155     // re-schedule (required for type extern and delay)
00156     if(pattr->mExpiresAt<=0) Schedule(*eit,pattr);
00157   }
00158   FD_DS("ProposingExecutor::ExecuteTime(): LoggingExecutor to execute time: done ");
00159   // case a: no valid proposal anyway
00160   if(!mPValid) return true;
00161   // case b: proposal remains valid
00162   if(mProposal.Time==tpTime::Max) return true;
00163   // case c: proposal becomes invalid
00164   if(mProposal.Time < duration) { mPValid=false; return true;}
00165   // case d: adjust proposal
00166   mProposal.Time-=duration;
00167   mPValid= (mProposal.Time>0) || (mProposal.Event!=0);
00168   return true;
00169 }
00170 
00171 //ExecuteEvent
00172 bool ProposingExecutor::ExecuteEvent(Idx event){
00173   FD_DS("ProposingExecutor::ExecuteEvent(): LoggingExecutor to execute event "<< mSimEvents.Str(event));
00174 
00175   // (try to) execute
00176   if(!LoggingExecutor::ExecuteEvent(event)) return false;
00177   FD_DS("ProposingExecutor::ExecuteEvent(): executed "<< EventName(event));  
00178 
00179   // record enabled events
00180   const EventSet newActiveEvents=ActiveEventSet(CurrentParallelState());    
00181   FD_DS("ProposingExecutor::ExecuteEvent(): new active events "<< newActiveEvents.ToString());   
00182 
00183 
00184   // invalidate/re-schedule event states
00185   EventSet::Iterator eit;
00186   for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit) {
00187     SimEventAttribute* pattr= mSimEvents.Attributep(*eit);
00188     // stochastic only
00189     if(!pattr->IsStochastic()) continue;
00190     // invalidate schedule: type trigger 
00191     if(pattr->Stochastic().mType==SimStochasticEventAttribute::Trigger) {
00192       TimeInterval gtime=EnabledGuardTime(*eit);
00193       gtime.Canonical();
00194       if(gtime!=pattr->mReferenceInterval) {
00195         FD_DS("ProposingExecutor::ExecuteEvent(): invalidating trigger type event "<< EStr(*eit));
00196         pattr->mExpiresAt = 0;
00197       }
00198     }
00199     // update state: type delay
00200     if(pattr->Stochastic().mType==SimStochasticEventAttribute::Delay) {
00201       TimeInterval etime=EnabledEventTime(*eit);
00202       etime.Canonical();
00203       pattr->mReferenceInterval=etime;
00204       pattr->mScheduledFor=tpTime::UnDef;
00205       pattr->mExpiresAt=tpTime::Max;
00206       tpTime::Type schedule= etime.LB()+ pattr->mDelayFor;
00207       if(etime.In(schedule)) {
00208         pattr->mScheduledFor=schedule;
00209         pattr->mExpiresAt=pattr->mScheduledFor+1;
00210         FD_DS("ProposingExecutor::ExecuteEvent(): delay event " << EStr(*eit) << ": etime " 
00211              << etime.Str() << " scheduled " << schedule);
00212       }
00213     }
00214     // invalidate schedule: event executed
00215     if(*eit==event) {
00216       FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for executed event "<< EStr(*eit));
00217       pattr->mExpiresAt = 0;
00218     }
00219     /*
00220     // invalidate schedule: type all reset
00221     if(pattr->Stochastic().mType==SimStochasticEventAttribute::State) {
00222       pattr->mExpiresAt = 0;
00223       pattr->mScheduledFor = 0;
00224       pattr->mDelayFor = tpTime::UnDef;
00225       FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for state-type " << EStr(*eit));
00226     }
00227     */
00228     /*
00229     // invalidate schedule: type intern
00230     if(pattr->Stochastic().mType==SimStochasticEventAttribute::Intern) {
00231       if(!EventValidity(*eit, event, oldActiveStateVec,newActiveStateVec)){
00232         pattr->mExpiresAt = 0;
00233         pattr->mScheduledFor = 0;
00234         pattr->mDelayFor = tpTime::UnDef;
00235         FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for intern-type " << EStr(*eit));
00236       }
00237     }
00238     */
00239     // re-schedule
00240     if(newActiveEvents.Exists(*eit))
00241     if(pattr->mExpiresAt<=0) Schedule(*eit,pattr);
00242   } // loop all events
00243 
00244   // invalidate proposal
00245   mPValid=false;
00246   // done
00247   FD_DS("ProposingExecutor::ExecuteEvent(): done");
00248   return true;  
00249 }
00250 
00251 
00252 //ExecuteTransition (rel time!) (event 0 for time only)
00253 bool ProposingExecutor::ExecuteTransition(const TimedEvent& executeEvent){
00254 
00255   if(!ExecuteTime(executeEvent.Time)) return false;
00256   if(executeEvent.Event==0) return true;
00257   if(!ExecuteEvent(executeEvent.Event)) return false;  
00258 
00259   return true;
00260 }
00261 
00262 
00263 
00264 //ProposeNextTransition (event 0 for time only)
00265 // todo: combine loops for performance
00266 const TimedEvent& ProposingExecutor::ProposeNextTransition(void){
00267 
00268   FD_DS("ProposingExecutor::ProposeNextTransition()");
00269 
00270   // return valid proposal
00271   if(mPValid) return mProposal;
00272 
00273   // compute valid proposal now
00274   mPValid=true;
00275 
00276   // vars
00277   EventSet::Iterator eit;
00278   TimeInterval enabledInterval=EnabledInterval();
00279   TimeInterval enabledTime=EnabledTime();
00280   const EventSet enabledEvents = EnabledEvents();
00281 
00282   // report
00283   FD_DS("\n" << EventStatesToString());
00284   FD_DS("ProposingExecutor::ProposeNextTransition(): current time: " << 
00285     CurrentTime()); 
00286   FD_DS("ProposingExecutor::ProposeNextTransition(): timed state: " <<
00287     CurrentParallelTimedStateStr());
00288   FD_DS("ProposingExecutor::ProposeNextTransition(): active events: " <<
00289       ActiveEventSet(CurrentParallelState()).ToString());
00290   FD_DS("ProposingExecutor::ProposeNextTransition(): enabled interval: " <<
00291     enabledInterval.Str());
00292   FD_DS("ProposingExecutor::ProposeNextTransition(): enabled time: " <<
00293     enabledTime.Str());
00294   FD_DS("ProposingExecutor::ProposeNextTransition(): enabled events: " << std::endl <<
00295     EnabledEvents().ToString());
00296 
00297   // find candidate to execute
00298   Idx candidate=0;
00299   std::vector<faudes::Idx> candidates;
00300   tpTime::Type passtime=0;
00301 
00302   //check if a priority event occurs in analyzed interval 
00303   long int prio = -1;
00304   for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit) {
00305     SimEventAttribute* pattr= mSimEvents.Attributep(*eit);
00306     if(!pattr->IsPriority()) continue;
00307     // priority wins
00308     if(pattr->Priority().mPriority >prio) {
00309       prio= pattr->Priority().mPriority;
00310       candidate=*eit;
00311       candidates.clear();
00312       candidates.push_back(candidate);
00313     }
00314     // indicate non determinism
00315     if((pattr->Priority().mPriority ==prio) && (prio>=0)) 
00316       candidates.push_back(*eit);
00317   }
00318 
00319   // choose arbitrarily
00320   if(candidates.size()>1) {
00321     candidate=candidates[ran_uniform_int(0,candidates.size())];
00322   }
00323 
00324   // propose priority candidate now
00325   if(candidate>0) {
00326     FD_DS("ProposingExecutor::ProposeNextTransition(): propose by priority: " << mSimEvents.Str(candidate));
00327     mProposal.Event=candidate;
00328     mProposal.Time=0;
00329     return mProposal;
00330   }
00331 
00332   //check if stochastic  events are enabled
00333   tpTime::Type occurence = -1;
00334   for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit){
00335     SimEventAttribute* pattr= mSimEvents.Attributep(*eit);
00336     if(!pattr->IsStochastic()) continue;
00337     if(pattr->mScheduledFor == tpTime::UnDef) continue; // dont need this anyway
00338     if(enabledInterval.In(pattr->mScheduledFor)) { 
00339       // occurence wins
00340       if(pattr->mScheduledFor < occurence || occurence < 0) {
00341         occurence= pattr->mScheduledFor;
00342         candidate=*eit;
00343         candidates.clear();
00344         candidates.push_back(candidate);
00345       }
00346       // indicate non determinism
00347       if(pattr->mScheduledFor == occurence) 
00348         candidates.push_back(*eit);
00349     }
00350   }
00351 
00352   // choose arbitrarily
00353   if(candidates.size()>1) {
00354     candidate=candidates[ran_uniform_int(0,candidates.size())];
00355   }
00356 
00357   // propose stochastic candidate now
00358   if(candidate>0) {
00359     FD_DS("ProposingExecutor::ProposeNextTransition(): propose by stochastic: " << mSimEvents.Str(candidate) << " for " << tpTime::Str(occurence));
00360     mProposal.Event=candidate;
00361     mProposal.Time=occurence;
00362     return mProposal;
00363   }
00364 
00365   // check if we can pass time
00366   if(!enabledTime.Empty()) {
00367     // pass enabled interval
00368     passtime=enabledInterval.UB();
00369     if(enabledInterval.Empty()) passtime=0;
00370     // be sure to be beyond enabled interval but within enabled time
00371     if(enabledInterval.UBincl()) passtime+=tpTime::Step;
00372     // be sure to be within enabled time
00373     if(!enabledTime.In(passtime)) passtime-=tpTime::Step;
00374     // fix infty
00375     if(enabledTime.UBinf() && enabledInterval.UBinf()) passtime=tpTime::Max;
00376     // if we can go for ever,  step with minstep 
00377     // if(passtime==tpTime::Max) passtime=tpTime::Step; 
00378     // only execute relevant steps -- otherwise max execute priority event
00379     if(passtime!=0) {    
00380       FD_DS("ProposingExecutor::ProposeNextTransition(): propose to pass time: "<< tpTime::Str(passtime));
00381       mProposal.Event=0;
00382       mProposal.Time=passtime;
00383       return mProposal;
00384     }
00385   }
00386 
00387   //check if prevent priority event occurs in analyzed interval 
00388   prio =0;
00389   for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit){
00390     SimEventAttribute* pattr= mSimEvents.Attributep(*eit);
00391     if(!pattr->IsPriority()) continue;
00392     // priority wins
00393     if(pattr->Priority().mPriority >prio || prio==0) {
00394       prio= pattr->Priority().mPriority;
00395       candidate=*eit;
00396       candidates.clear();
00397       candidates.push_back(candidate);
00398     }
00399     // alphabetical  
00400     if((pattr->Priority().mPriority ==prio) && (prio <0)) 
00401       candidates.push_back(*eit);
00402   }
00403 
00404   // choose arbitrarily
00405   if(candidates.size()>1) {
00406     candidate=candidates[ran_uniform_int(0,candidates.size())];
00407   }
00408 
00409   // propose prevent priority candidate now
00410   if(candidate>0) {
00411     FD_DS("ProposingExecutor::ProposeNextTransition(): propose by priority: " << mSimEvents.Str(candidate));
00412     mProposal.Event=candidate;
00413     mProposal.Time=passtime;
00414     return mProposal;
00415   }
00416 
00417   //Deadlock request
00418   if(IsDeadlocked()){
00419     FD_DS("ProposingExecutor::ProposeNextTransition(): Deadlocked");
00420     mProposal.Event=0; 
00421     mProposal.Time=tpTime::UnDef;
00422     return mProposal;
00423   }                           
00424 
00425   // nothing to propose but time 
00426   FD_DS("ProposingExecutor::ProposeNextTransition(): Lifelock");
00427   mProposal.Event=0; 
00428   mProposal.Time=tpTime::Step;
00429   return mProposal;
00430 }
00431 
00432 
00433 //ExecuteNextTransition
00434 TimedEvent ProposingExecutor::ExecuteNextTransition(void){
00435   FD_DS("ProposingExecutor::ExecuteNextTransition() *********************************************************** ");
00436 
00437   tpTime::Type currentTime=0;
00438   TimedEvent execTimedEvent;
00439 
00440   //********************************************
00441   //Execution loop
00442   //********************************************
00443   while(true){
00444 
00445     // get proposal
00446     execTimedEvent = ProposeNextTransition();
00447 
00448     // deadlocked? (todo: mintime/min float number etc)
00449     if((execTimedEvent.Event==0) && (execTimedEvent.Time==0)) break;
00450     if(IsDeadlocked()) break;
00451 
00452     // execute (time and/or event)
00453     ExecuteTransition(execTimedEvent);
00454  
00455     // done if there was an event
00456     if(execTimedEvent.Event!=0) break;
00457 
00458     // record time
00459     currentTime+=execTimedEvent.Time;
00460 
00461   }
00462 
00463   // success  
00464   if(execTimedEvent.Event!=0) {
00465      execTimedEvent.Time=currentTime;
00466      return execTimedEvent;
00467   }
00468 
00469   // failure
00470   execTimedEvent.Time=tpTime::UnDef;
00471   execTimedEvent.Event=0;
00472   return execTimedEvent;
00473 }
00474 
00475 
00476 
00477 //Schedule() by attribute
00478 tpTime::Type ProposingExecutor::Schedule(Idx event, SimEventAttribute* pattr) {
00479   FD_DS("ProposingExecutor::Schedule(" << EStr(event) << ")");
00480   // insist in stochastic attribute
00481   if(!pattr->IsStochastic()) {
00482     FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): no stoxchastic attribute found");
00483     pattr->mScheduledFor=tpTime::UnDef;
00484     return tpTime::UnDef;
00485   }
00486   // only reschedule when expired
00487   if(pattr->mExpiresAt>0) {
00488     FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): event not expired");
00489     return pattr->mScheduledFor;
00490   }
00491   // invalidate event state;
00492   tpTime::Type recentschedule=pattr->mScheduledFor;
00493   pattr->mScheduledFor=tpTime::UnDef;
00494   pattr->mExpiresAt=tpTime::UnDef;
00495   pattr->mDelayFor=tpTime::UnDef;
00496   pattr->mReferenceInterval.SetEmpty();
00497   // target interval for sample, defaults to positive axis
00498   TimeInterval atarget;
00499   atarget.SetPositive();
00500   // trigger type events have restricted target
00501   if(pattr->Stochastic().mType == SimStochasticEventAttribute::Trigger) {
00502     atarget.Intersect(EnabledGuardTime(event));
00503     atarget.Canonical();
00504   }
00505   // cannot have empty target
00506   if(atarget.Empty()) {
00507      FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): empty target");
00508      return tpTime::UnDef;
00509   }   
00510   // report timed automaton target
00511   FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): for timed automaton target " << atarget.Str());
00512   // get pdf parameters to figure restricted support 
00513   std::vector<double> pdfparavec=pattr->Stochastic().mParameter;
00514   TimeInterval starget;
00515   starget.LB(static_cast<tpTime::Type>(pdfparavec[0]));
00516   starget.UB(static_cast<tpTime::Type>(pdfparavec[1]));
00517   starget.LBincl(true);
00518   starget.UBincl(false);  
00519   atarget.Intersect(starget);
00520   FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): for restricted target " << atarget.Str());
00521   if(atarget.Empty()) {
00522     FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): empty target");
00523     return tpTime::UnDef;
00524   }
00525   // do the sample
00526   double occtime=-1; 
00527   switch(pattr->Stochastic().mPdf){
00528   // exponential
00529   case SimStochasticEventAttribute::Exponential:
00530     occtime=ran_exponential(pdfparavec[2],atarget.LB(),atarget.UB());
00531     break;
00532   // gauss
00533   case SimStochasticEventAttribute::Gauss:
00534     occtime=ran_gauss(pdfparavec[2],pdfparavec[3],atarget.LB(),atarget.UB());
00535     break;
00536   //Uniform
00537   case SimStochasticEventAttribute::Uniform: 
00538     occtime=ran_uniform(atarget.LB(),atarget.UB());
00539     break;
00540   //Undefined 
00541   case SimStochasticEventAttribute::Vector:
00542     FD_DS("ProposingExecutor::Schedule(" << EStr(event) << ") internal error: no valid stochastic defs");
00543     return tpTime::UnDef;
00544     break;
00545   }
00546   // report failure
00547   if(occtime < 0)  {
00548     FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): sampling failed: A");
00549     return tpTime::UnDef;
00550   }
00551   // discretize tpTime::Type 
00552   long int round= static_cast<unsigned long>(occtime/tpTime::Step + 0.5);     
00553   tpTime::Type schedule = static_cast<tpTime::Type>(round*tpTime::Step);
00554   FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): random sample " << schedule 
00555     << "(" << occtime << ")");
00556   // interpret sample
00557   switch(pattr->Stochastic().mType){
00558   // interpret sample: trigger type
00559   case SimStochasticEventAttribute::Trigger:
00560     // paranoid ... fix rounding issues
00561     if(!atarget.In(schedule)) schedule+=tpTime::Step;
00562     if(!atarget.In(schedule)) schedule-=2*tpTime::Step;
00563     if(!atarget.In(schedule)) schedule= tpTime::UnDef;
00564     // paranoid ... report failure
00565     if(!atarget.In(schedule))  {
00566       FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): sampling failed: B");
00567       return tpTime::UnDef;
00568     }
00569     // set schedule
00570     pattr->mScheduledFor=schedule;
00571     pattr->mExpiresAt=atarget.UB();
00572     pattr->mDelayFor=tpTime::UnDef;
00573     pattr->mReferenceInterval=atarget;
00574     break;   
00575   // interpret sample: extern type // issue: re-sampling can hang
00576   case SimStochasticEventAttribute::Extern:
00577     pattr->mScheduledFor=schedule;
00578     if(recentschedule!=tpTime::UnDef) 
00579       pattr->mScheduledFor+=recentschedule;
00580     pattr->mExpiresAt=pattr->mScheduledFor+1;
00581     pattr->mDelayFor=tpTime::UnDef;
00582     pattr->mReferenceInterval.SetEmpty();
00583     if(pattr->mScheduledFor<0) {   
00584       FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): re-sampling");
00585       return Schedule(event,pattr);
00586     }
00587     break;
00588   // interpret sample: delay type
00589   case SimStochasticEventAttribute::Delay:
00590     TimeInterval etime=EnabledEventTime(event);
00591     etime.Canonical();
00592     FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): delay type: etime " 
00593           << etime.Str() << " delayfor " << schedule);
00594     pattr->mDelayFor=schedule;
00595     pattr->mReferenceInterval=etime;
00596     pattr->mScheduledFor=tpTime::UnDef;
00597     pattr->mExpiresAt=tpTime::Max;
00598     schedule+=etime.LB();
00599     if(etime.In(schedule)) {
00600       pattr->mScheduledFor=schedule;
00601       pattr->mExpiresAt=pattr->mScheduledFor+1;
00602     }
00603     return pattr->mScheduledFor;
00604   }
00605   // done
00606   return pattr->mScheduledFor;
00607 }
00608    
00609 
00610 
00611 //DoWrite(rTr,rLabel)
00612 void ProposingExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00613   (void) pContext;
00614   std::string label=rLabel;
00615   if(label=="") label = "Executor";
00616   rTw.WriteBegin(label);
00617   ParallelExecutor::DoWriteGenerators(rTw);
00618   Conditions().Write(rTw,"Conditions",this);
00619   mSimEvents.Write(rTw,"SimEvents");
00620   rTw.WriteEnd(label);
00621 }
00622 
00623 //DoRead(rTr,rLabel)
00624 void ProposingExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00625   (void) pContext;
00626   FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<")");
00627   std::string label=rLabel;
00628   if(label=="") label = "Executor";
00629   rTr.ReadBegin(label);
00630 
00631   while(!rTr.Eos(label)) {
00632     FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<"): loop");
00633     // peek token
00634     Token token;
00635     rTr.Peek(token);
00636     // case 1: generators
00637     if(token.Type()==Token::Begin)
00638     if(token.StringValue()=="Generators") {
00639       ParallelExecutor::DoReadGenerators(rTr);
00640       continue;
00641     }
00642     // case 2: conditions
00643     if(token.Type()==Token::Begin)
00644     if(token.StringValue()=="Conditions") {
00645       SimConditionSet conditions;
00646       conditions.Read(rTr,"Conditions",this);
00647       Conditions(conditions);
00648       continue;
00649     }
00650     // case 3: event attributes
00651     if(token.Type()==Token::Begin)
00652     if(token.StringValue()=="SimEvents") {
00653       mSimEvents.Read(rTr,"SimEvents");
00654       continue;
00655     }
00656     // case 3: event attributes (compatibility mode)
00657     if(token.Type()==Token::Begin)
00658     if(token.StringValue()=="SimEventAttributes") {
00659       mSimEvents.Read(rTr,"SimEventAttributes");
00660       continue;
00661     }
00662     // else report error
00663     std::stringstream errstr;
00664     errstr << "Invalid token, generators, conditions or simeventattribute section expected, " << rTr.FileLine();
00665     throw Exception("ProposingExecutor::DoRead", errstr.str(), 502);
00666   }
00667   rTr.ReadEnd(label);
00668   FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<"): done");
00669   Reset();
00670 }
00671 
00672 
00673 // revert executors state to past step from buffer
00674 bool ProposingExecutor::RevertToStep(Idx step) {
00675   FD_DX("ProposingExecutor(" << this << ")::RevertToStep("<< step << ")");
00676   // call base
00677   bool res=LoggingExecutor::RevertToStep(step);
00678   // bail out
00679   if(!res) return false;
00680   // reset my dynamic data
00681   ResetProposer();
00682   // done
00683   return true;
00684 }
00685 
00686 } // end namespace
00687 
00688 
00689 
00690 
00691 
00692 /*
00693       Scratch: how to record relevant clocks in Schedule()
00694       This might be interesting to sense resets that invalidate delay type events
00695 
00696       // record relevant clocks
00697       pattr->mRelevantClocks.Clear();
00698       for(Iterator git=Begin(); git!=End(); git++){ 
00699         pattr->mRelevantClocks.InsertSet(git->Generator().Invariant(git->CurrentState()).ActiveClocks());
00700         TransSet::Iterator tit = git->Generator().TransRelBegin(git->CurrentState(),*eit);
00701         pattr->mRelevantClocks.InsertSet(git->Generator().Guard(*tit).ActiveClocks());
00702       }
00703       FD_DS("ProposingExecutor::ExecuteEvent(): relevant clocks " << pattr->mRelevantClocks.ToString());
00704 
00705 */
00706 
00707 
00708 
00709 
00710 /*
00711       Scratch: how to figure whether relevant clocks, guards, or invariants changed
00712       This was required for the old internal type events. Depreciated.
00713 
00714 
00715 //EventValidity(Idx, Idx, T_state_vec, T_state_vec) 
00716 bool ProposingExecutor::EventValidity(Idx ev, Idx executedEvent, 
00717       const ParallelState& oldStateVec, const ParallelState& newStateVec) {
00718   unsigned int i=0;
00719   Iterator xit;
00720   TransSet::Iterator tit;
00721   TimeConstraint::Iterator oldcit,newcit;
00722   ClockSet::Iterator clit;
00723   ClockSet* pclocks = &mSimEvents.Attributep(ev)->mRelevantClocks;
00724 
00725   //Check if event was indeed active and is is still active
00726   if(!Active(ev, oldStateVec)){ 
00727     FD_DS("ProposingExecutor::EventValidity(): Event "<<Alphabet().SymbolicName(ev)
00728          << " has not been active in last parallel state");
00729     return false;
00730   }
00731   if(!Active(ev, newStateVec)){ 
00732     FD_DS("ProposingExecutor::EventValidity(): Event "<<Alphabet().SymbolicName(ev)
00733              <<" is not active in current parallel state");
00734     return false;
00735   }
00736 
00737 
00738   //Check if relevant clocks are affected
00739   FD_DS("ProposingExecutor::EventValidity(): test clocks for " << Alphabet().Str(ev));
00740 
00741   for(xit=Begin(); xit!=End(); ++xit, i++){
00742     // If this excutor did not execute anything, nothing changed at all
00743     if(!xit->Generator().ExistsEvent(executedEvent)) continue;  
00744     // If this excutor does not share the event, no guards/invs/resets affects its enabled status
00745     if(!xit->Generator().ExistsEvent(ev)) continue; 
00746     //Check if a reset of a relevant clock was executed
00747     tit=xit->Generator().TransRelBegin(oldStateVec[i],executedEvent); 
00748     FD_DS("ProposingExecutor::EventValidity(): test resets of " << Generator().TStr(*tit));
00749     const ClockSet resetClocks=xit->Generator().Resets(*tit);
00750     if(!(resetClocks * (*pclocks)).Empty()) {
00751       FD_DS("ProposingExecutor::EventValidity(): relevant clock reset in " << xit->Name());
00752       return false;
00753     }
00754     // If the state didnt change, neither did guards/invariants
00755     if(oldStateVec[i]==newStateVec[i]) continue;  
00756     //Check if guards have changed wrt relevant clocks
00757     tit=xit->Generator().TransRelBegin(oldStateVec[i],ev);
00758     FD_DS("ProposingExecutor::EventValidity(): compare old guard of " << Generator().TStr(*tit));
00759     TimeConstraint oldGuard=xit->Generator().Guard(*tit);
00760     tit=xit->Generator().TransRelBegin(newStateVec[i],ev);
00761     FD_DS("ProposingExecutor::EventValidity(): ... with guard of " << Generator().TStr(*tit));
00762     TimeConstraint newGuard=xit->Generator().Guard(*tit);
00763     for(ClockSet::Iterator cit=pclocks->Begin(); cit!=pclocks->End(); cit++) {
00764       if(oldGuard.Interval(*cit)!=newGuard.Interval(*cit)) { 
00765         FD_DS("ProposingExecutor::EventValidity(): invalidate for change in guard wrt clock " << 
00766           pclocks->SymbolicName(*cit));
00767         FD_DS("ProposingExecutor::EventValidity(): old guard " << oldGuard.ToString());
00768         FD_DS("ProposingExecutor::EventValidity(): new guard " << newGuard.ToString());
00769         return false;
00770       }
00771     }
00772     //Check if invariants have changed
00773     TimeConstraint oldInv=xit->Generator().Invariant(oldStateVec[i]);
00774     TimeConstraint newInv=xit->Generator().Invariant(newStateVec[i]);
00775     for(ClockSet::Iterator cit=pclocks->Begin(); cit!=pclocks->End(); cit++) {
00776       if( oldInv.Interval(*cit)!=newInv.Interval(*cit)) { 
00777         FD_DS("ProposingExecutor::EventValidity(): invalidate for change in invariant wrt clock " << 
00778           pclocks->SymbolicName(*cit));
00779         FD_DS("ProposingExecutor::EventValidity(): old inv " << oldInv.ToString());
00780         FD_DS("ProposingExecutor::EventValidity(): new inv " << newInv.ToString());
00781         return false;
00782       }
00783     }
00784   } // loop all generators
00785   FD_DS("ProposingExecutor::EventValidity(): Event " << Alphabet().SymbolicName(ev)<< " is still valid"); 
00786   return true;
00787 }
00788 
00789 */
00790 
00791 
00792 
00793 
00794 
00795 
00796 

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen