sp_plpexecutor.cpp

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

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