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