sp_plpexecutor.cpp
Go to the documentation of this file.
1 /** @file sp_plpexecutor.cpp Executor that proposes transitions to execute */
2 
3 /*
4  FAU Discrete Event System Simulator
5 
6  Copyright (C) 2007 Christoph Doerr
7  Copyright (C) 2008 Thomas Moor
8  Exclusive copyright is granted to Thomas Moor
9 
10 */
11 
12 #include "sp_plpexecutor.h"
13 #include <cmath>
14 
15 namespace faudes {
16 
17 // std faudes type
18 FAUDES_TYPE_IMPLEMENTATION(ProposingExecutor, ProposingExecutor, ParallelExecutor)
19 
20 // constructor
22  mPValid=false;
23 }
24 
25 // copy constructor
27 {
28  mPValid=false;
29  Assign(rOther);
30 }
31 
32 // clear static data
35  mSimEvents.Clear();
36  mPValid=false;
37 }
38 
39 // DoAssign(other)
41  FD_DX("ProposingExecutor(" << this << ")::DoAssign(other)");
42  // my members
44  // base
46 }
47 
48 // lookup event attribute
50  return mSimEvents.Attribute(index);
51 }
52 
53 // set simulation event attribute
55  mSimEvents.Attribute(index,rAttr);
56 }
57 
58 // set execution properties from attributed event set
59 void ProposingExecutor::Alphabet(const sEventSet& rAlphabet) {
60  // set ...
61  mSimEvents=rAlphabet;
62  // ... and ensure to cover all relevant alphabet
64 }
65 
66 // clear dynamic data (reset state)
68  FD_DS("ProposingExecutor::ResetProposer()");
69  //Initialize random number generator with computer system time as seed
70  if(seed == 0) {
71  faudes_systime_t now;
72  faudes_gettimeofday(&now);
73  seed=now.tv_sec;
74  }
75  ran_init(seed);
76  // schedule all events
77  EventSet::Iterator eit;
78  for(eit=Alphabet().Begin(); eit!=Alphabet().End(); ++eit){
80  pattr->mScheduledFor=Time::UnDef();
81  pattr->mDelayFor=Time::UnDef();
82  pattr->mExpiresAt=0;
83  if(pattr->IsPriority()) continue;
84  if(!pattr->IsStochastic()) continue;
85  Schedule(*eit,pattr);
86  }
87  // invalidate proposal
88  mPValid=false;
89  FD_DS("ProposingExecutor::ResetProposer(): done");
90 
91 
92 }
93 
94 // clear dynamic data (reset state)
95 void ProposingExecutor::Reset(long int seed){
96  FD_DS("ProposingExecutor::Reset()");
99  ResetProposer(seed);
100  FD_DS("ProposingExecutor::Reset(): done");
101 }
102 
103 
104 //EventStatesToString
106  std::stringstream retstr;
107  EventSet::Iterator eit;
108  for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit){
109  const SimEventAttribute& attr= mSimEvents.Attribute(*eit);
110  retstr<< "% simulation state: "<< ExpandString(mSimEvents.Str(*eit),FD_NAMELEN) << ": ";
111  retstr<< "enabled: " << ExpandString(EnabledEventTime(*eit).Str(),FD_NAMELEN) << ": ";
112  retstr<< attr.Str();
113  if( eit!= --mSimEvents.End()) {
114  retstr << std::endl;
115  }
116  }
117  return retstr.str();
118 }
119 
120 
121 
122 //ExecuteTime: todo: may hang + performance issue
124  FD_DS("ProposingExecutor::ExecuteTime(): LoggingExecutor to execute time "<< duration);
125  if(!LoggingExecutor::ExecuteTime(duration)) return false;
126  // update stochastic event state
127  EventSet::Iterator eit;
128  for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit) {
130  // stochastic only
131  if(!pattr->IsStochastic()) continue;
132  // shift relative time: schedule/expiring time
133  if(pattr->mScheduledFor!=Time::UnDef())
134  if(pattr->mScheduledFor!=Time::Max())
135  pattr->mScheduledFor -= duration;
136  if(pattr->mExpiresAt!=Time::UnDef())
137  if(pattr->mExpiresAt!=Time::Max())
138  pattr->mExpiresAt -= duration;
139  // shift reference interval for type trigger
141  pattr->mReferenceInterval.PositiveLeftShift(duration);
142  }
143  // shift reference interval for type delay
144  if(pattr->Stochastic().mType==SimStochasticEventAttribute::Delay) {
145  if(!pattr->mReferenceInterval.Empty()) {
146  Time::Type delay = duration - pattr->mReferenceInterval.LB();
147  if(delay>0) pattr->mDelayFor-=delay;
148  pattr->mReferenceInterval.PositiveLeftShift(duration);
149  }
150  }
151  // re-schedule (required for type extern and delay)
152  if(pattr->mExpiresAt<=0) Schedule(*eit,pattr);
153  }
154  FD_DS("ProposingExecutor::ExecuteTime(): LoggingExecutor to execute time: done ");
155  // case a: no valid proposal anyway
156  if(!mPValid) return true;
157  // case b: proposal remains valid
158  if(mProposal.mTime==Time::Max()) return true;
159  // case c: proposal becomes invalid
160  if(mProposal.mTime < duration) { mPValid=false; return true;}
161  // case d: adjust proposal
162  mProposal.mTime-=duration;
163  mPValid= (mProposal.mTime>0) || (mProposal.mEvent!=0);
164  return true;
165 }
166 
167 //ExecuteEvent
169  FD_DS("ProposingExecutor::ExecuteEvent(): ProposingExecutor to execute event "<< mSimEvents.Str(event));
170 
171  // (try to) execute
172  if(!LoggingExecutor::ExecuteEvent(event)) return false;
173  FD_DS("ProposingExecutor::ExecuteEvent(): executed "<< EventName(event));
174 
175  // record enabled events
176  const EventSet newActiveEvents=ActiveEventSet(CurrentParallelState());
177  FD_DS("ProposingExecutor::ExecuteEvent(): new active events "<< newActiveEvents.ToString());
178 
179 
180  // invalidate/re-schedule event states
181  EventSet::Iterator eit;
182  for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit) {
184  // stochastic only
185  if(!pattr->IsStochastic()) continue;
186  // invalidate schedule: type trigger
188  TimeInterval gtime=EnabledGuardTime(*eit);
189  gtime.Canonical();
190  if(gtime!=pattr->mReferenceInterval) {
191  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating trigger type event "<< EStr(*eit));
192  pattr->mExpiresAt = 0;
193  }
194  }
195  // update state: type delay (only if not expired)
197  if(pattr->mExpiresAt > 0) {
198  TimeInterval etime=EnabledEventTime(*eit);
199  etime.Canonical();
200  pattr->mReferenceInterval=etime;
201  pattr->mScheduledFor=Time::UnDef();
202  pattr->mExpiresAt=Time::Max();
203  Time::Type schedule= etime.LB()+ pattr->mDelayFor;
204  if(etime.In(schedule)) {
205  pattr->mScheduledFor=schedule;
206  pattr->mExpiresAt=pattr->mScheduledFor+1;
207  FD_DS("ProposingExecutor::ExecuteEvent(): delay event " << EStr(*eit) << ": etime "
208  << etime.Str() << " scheduled " << schedule);
209  }
210  }
211  // invalidate schedule: event executed
212  if(*eit==event) {
213  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for executed event "<< EStr(*eit));
214  pattr->mExpiresAt = 0;
215  }
216  /*
217  // invalidate schedule: type all reset
218  if(pattr->Stochastic().mType==SimStochasticEventAttribute::State) {
219  pattr->mExpiresAt = 0;
220  pattr->mScheduledFor = 0;
221  pattr->mDelayFor = Time::UnDef();
222  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for state-type " << EStr(*eit));
223  }
224  */
225  /*
226  // invalidate schedule: type intern
227  if(pattr->Stochastic().mType==SimStochasticEventAttribute::Intern) {
228  if(!EventValidity(*eit, event, oldActiveStateVec,newActiveStateVec)){
229  pattr->mExpiresAt = 0;
230  pattr->mScheduledFor = 0;
231  pattr->mDelayFor = Time::UnDef();
232  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for intern-type " << EStr(*eit));
233  }
234  }
235  */
236  // re-schedule
237  if(newActiveEvents.Exists(*eit))
238  if(pattr->mExpiresAt<=0) Schedule(*eit,pattr);
239  } // loop all events
240 
241  // invalidate proposal
242  mPValid=false;
243  // done
244  FD_DS("ProposingExecutor::ExecuteEvent(): done");
245  return true;
246 }
247 
248 
249 //ExecuteTransition (rel time!) (event 0 for time only)
251 
252  if(!ExecuteTime(executeEvent.mTime)) return false;
253  if(executeEvent.mEvent==0) return true;
254  if(!ExecuteEvent(executeEvent.mEvent)) return false;
255 
256  return true;
257 }
258 
259 
260 
261 //ProposeNextTransition (event 0 for time only)
262 // todo: combine loops for performance
264 
265  FD_DS("ProposingExecutor::ProposeNextTransition()");
266 
267  // return valid proposal
268  if(mPValid) return mProposal;
269 
270  // compute valid proposal now
271  mPValid=true;
272 
273  // vars
274  EventSet::Iterator eit;
275  TimeInterval enabledInterval=EnabledInterval();
276  TimeInterval enabledTime=EnabledTime();
277  const EventSet enabledEvents = EnabledEvents();
278 
279  // report
280  FD_DS("\n" << EventStatesToString());
281  FD_DS("ProposingExecutor::ProposeNextTransition(): current time: " <<
282  CurrentTime());
283  FD_DS("ProposingExecutor::ProposeNextTransition(): timed state: " <<
285  FD_DS("ProposingExecutor::ProposeNextTransition(): active events: " <<
287  FD_DS("ProposingExecutor::ProposeNextTransition(): enabled interval: " <<
288  enabledInterval.Str());
289  FD_DS("ProposingExecutor::ProposeNextTransition(): enabled time: " <<
290  enabledTime.Str());
291  FD_DS("ProposingExecutor::ProposeNextTransition(): enabled events: " << std::endl <<
292  EnabledEvents().ToString());
293 
294  // find candidate to execute
295  Idx candidate=0;
296  std::vector<faudes::Idx> candidates;
297  Time::Type passtime=0;
298 
299  //check if a priority event occurs in analyzed interval
300  long int prio = -1;
301  for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit) {
303  if(!pattr->IsPriority()) continue;
304  // priority wins
305  if(pattr->Priority().mPriority >prio) {
306  prio= pattr->Priority().mPriority;
307  candidate=*eit;
308  candidates.clear();
309  candidates.push_back(candidate);
310  }
311  // indicate non determinism
312  if((pattr->Priority().mPriority ==prio) && (prio>=0))
313  candidates.push_back(*eit);
314  }
315 
316  // choose arbitrarily
317  if(candidates.size()>1) {
318  candidate=candidates[ran_uniform_int(0,candidates.size())];
319  }
320 
321  // propose priority candidate now
322  if(candidate>0) {
323  FD_DS("ProposingExecutor::ProposeNextTransition(): propose by priority: " << mSimEvents.Str(candidate));
324  mProposal.mEvent=candidate;
325  mProposal.mTime=0;
326  return mProposal;
327  }
328 
329  //check if stochastic events are enabled
330  Time::Type occurence = -1;
331  for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit){
333  if(!pattr->IsStochastic()) continue;
334  if(pattr->mScheduledFor == Time::UnDef()) continue; // dont need this anyway
335  if(enabledInterval.In(pattr->mScheduledFor)) {
336  // occurence wins
337  if(pattr->mScheduledFor < occurence || occurence < 0) {
338  occurence= pattr->mScheduledFor;
339  candidate=*eit;
340  candidates.clear();
341  candidates.push_back(candidate);
342  }
343  // indicate non determinism
344  if(pattr->mScheduledFor == occurence)
345  candidates.push_back(*eit);
346  }
347  }
348 
349  // choose arbitrarily
350  if(candidates.size()>1) {
351  candidate=candidates[ran_uniform_int(0,candidates.size())];
352  }
353 
354  // propose stochastic candidate now
355  if(candidate>0) {
356  FD_DS("ProposingExecutor::ProposeNextTransition(): propose by stochastic: " << mSimEvents.Str(candidate) << " for " << Time::Str(occurence));
357  mProposal.mEvent=candidate;
358  mProposal.mTime=occurence;
359  return mProposal;
360  }
361 
362  // check if we can pass time
363  if(!enabledTime.Empty()) {
364  // pass enabled interval
365  passtime=enabledInterval.UB();
366  if(enabledInterval.Empty()) passtime=0;
367  // be sure to be beyond enabled interval but within enabled time
368  if(enabledInterval.UBincl()) passtime+=Time::Step();
369  // be sure to be within enabled time
370  if(!enabledTime.In(passtime)) passtime-=Time::Step();
371  // fix infty
372  if(enabledTime.UBinf() && enabledInterval.UBinf()) passtime=Time::Max();
373  // if we can go for ever, step with minstep
374  // if(passtime==Time::Max()) passtime=Time::Step();
375  // only execute relevant steps -- otherwise max execute priority event
376  if(passtime!=0) {
377  FD_DS("ProposingExecutor::ProposeNextTransition(): propose to pass time: "<< Time::Str(passtime));
378  mProposal.mEvent=0;
379  mProposal.mTime=passtime;
380  return mProposal;
381  }
382  }
383 
384  //check if prevent priority event occurs in analyzed interval
385  prio =0;
386  for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit){
388  if(!pattr->IsPriority()) continue;
389  // priority wins
390  if(pattr->Priority().mPriority >prio || prio==0) {
391  prio= pattr->Priority().mPriority;
392  candidate=*eit;
393  candidates.clear();
394  candidates.push_back(candidate);
395  }
396  // alphabetical
397  if((pattr->Priority().mPriority ==prio) && (prio <0))
398  candidates.push_back(*eit);
399  }
400 
401  // choose arbitrarily
402  if(candidates.size()>1) {
403  candidate=candidates[ran_uniform_int(0,candidates.size())];
404  }
405 
406  // propose prevent priority candidate now
407  if(candidate>0) {
408  FD_DS("ProposingExecutor::ProposeNextTransition(): propose by priority: " << mSimEvents.Str(candidate));
409  mProposal.mEvent=candidate;
410  mProposal.mTime=passtime;
411  return mProposal;
412  }
413 
414  //Deadlock request
415  if(IsDeadlocked()){
416  FD_DS("ProposingExecutor::ProposeNextTransition(): Deadlocked");
417  mProposal.mEvent=0;
419  return mProposal;
420  }
421 
422  // nothing to propose but time
423  FD_DS("ProposingExecutor::ProposeNextTransition(): Lifelock");
424  mProposal.mEvent=0;
426  return mProposal;
427 }
428 
429 
430 //ExecuteNextTransition
432  FD_DS("ProposingExecutor::ExecuteNextTransition() *********************************************************** ");
433 
434  Time::Type currentTime=0;
435  TimedEvent execTimedEvent;
436 
437  //********************************************
438  //Execution loop
439  //********************************************
440  while(true){
441 
442  // get proposal
443  execTimedEvent = ProposeNextTransition();
444 
445  // deadlocked? (todo: mintime/min float number etc)
446  if((execTimedEvent.mEvent==0) && (execTimedEvent.mTime==0)) break;
447  if(IsDeadlocked()) break;
448 
449  // execute (time and/or event)
450  ExecuteTransition(execTimedEvent);
451 
452  // done if there was an event
453  if(execTimedEvent.mEvent!=0) break;
454 
455  // record time
456  currentTime+=execTimedEvent.mTime;
457 
458  }
459 
460  // success
461  if(execTimedEvent.mEvent!=0) {
462  execTimedEvent.mTime=currentTime;
463  return execTimedEvent;
464  }
465 
466  // failure
467  execTimedEvent.mTime=Time::UnDef();
468  execTimedEvent.mEvent=0;
469  return execTimedEvent;
470 }
471 
472 
473 
474 //Schedule() by attribute
476  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << ")");
477  // insist in stochastic attribute
478  if(!pattr->IsStochastic()) {
479  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): no stoxchastic attribute found");
480  pattr->mScheduledFor=Time::UnDef();
481  return Time::UnDef();
482  }
483  // only reschedule when expired
484  if(pattr->mExpiresAt>0) {
485  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): event not expired");
486  return pattr->mScheduledFor;
487  }
488  // invalidate event state;
489  Time::Type recentschedule=pattr->mScheduledFor;
490  pattr->mScheduledFor=Time::UnDef();
491  pattr->mExpiresAt=Time::UnDef();
492  pattr->mDelayFor=Time::UnDef();
493  pattr->mReferenceInterval.SetEmpty();
494  // target interval for sample, defaults to positive axis
495  TimeInterval atarget;
496  atarget.SetPositive();
497  // trigger type events have restricted target
498  if(pattr->Stochastic().mType == SimStochasticEventAttribute::Trigger) {
499  atarget.Intersect(EnabledGuardTime(event));
500  atarget.Canonical();
501  }
502  // cannot have empty target
503  if(atarget.Empty()) {
504  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): empty target");
505  return Time::UnDef();
506  }
507  // report timed automaton target
508  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): for timed automaton target " << atarget.Str());
509  // get pdf parameters to figure restricted support
510  std::vector<Float> pdfparavec=pattr->Stochastic().mParameter;
511  TimeInterval starget;
512  starget.LB(Time::FromFloat(pdfparavec[0]));
513  starget.UB(Time::FromFloat(pdfparavec[1]));
514  starget.LBincl(true);
515  starget.UBincl(false);
516  atarget.Intersect(starget);
517  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): for restricted target " << atarget.Str());
518  if(atarget.Empty()) {
519  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): empty target");
520  return Time::UnDef();
521  }
522  // do the sample
523  double occtime=-1;
524  switch(pattr->Stochastic().mPdf){
525  // exponential
527  occtime=ran_exponential(pdfparavec[2],atarget.LB(),atarget.UB());
528  break;
529  // gauss
531  occtime=ran_gauss(pdfparavec[2],pdfparavec[3],atarget.LB(),atarget.UB());
532  break;
533  //Uniform
535  occtime=ran_uniform(atarget.LB(),atarget.UB());
536  break;
537  //Undefined
539  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << ") internal error: no valid stochastic defs");
540  return Time::UnDef();
541  break;
542  }
543  // report failure
544  if(occtime < 0) {
545  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): sampling failed: A");
546  return Time::UnDef();
547  }
548  // discretize Time::Type
549  Time::Type schedule = Time::Quantize(occtime);
550  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): random sample " << schedule
551  << "(" << occtime << ")");
552  // interpret sample
553  switch(pattr->Stochastic().mType){
554  // interpret sample: trigger type
556  // paranoid ... fix rounding issues
557  if(!atarget.In(schedule)) schedule+=Time::Step();
558  if(!atarget.In(schedule)) schedule-=2*Time::Step();
559  if(!atarget.In(schedule)) schedule= Time::UnDef();
560  // paranoid ... report failure
561  if(!atarget.In(schedule)) {
562  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): sampling failed: B");
563  return Time::UnDef();
564  }
565  // set schedule
566  pattr->mScheduledFor=schedule;
567  pattr->mExpiresAt=atarget.UB();
568  pattr->mDelayFor=Time::UnDef();
569  pattr->mReferenceInterval=atarget;
570  break;
571  // interpret sample: extern type // issue: re-sampling can hang
573  pattr->mScheduledFor=schedule;
574  if(recentschedule!=Time::UnDef())
575  pattr->mScheduledFor+=recentschedule;
576  pattr->mExpiresAt=pattr->mScheduledFor+1;
577  pattr->mDelayFor=Time::UnDef();
578  pattr->mReferenceInterval.SetEmpty();
579  if(pattr->mScheduledFor<0) {
580  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): re-sampling");
581  return Schedule(event,pattr);
582  }
583  break;
584  // interpret sample: delay type
586  TimeInterval etime=EnabledEventTime(event);
587  etime.Canonical();
588  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): delay type: etime "
589  << etime.Str() << " delay for " << schedule);
590  pattr->mDelayFor=schedule;
591  pattr->mReferenceInterval=etime;
592  pattr->mScheduledFor=Time::UnDef();
593  pattr->mExpiresAt=Time::Max();
594  schedule+=etime.LB();
595  if(etime.In(schedule)) {
596  pattr->mScheduledFor=schedule;
597  pattr->mExpiresAt=pattr->mScheduledFor+1;
598  }
599  return pattr->mScheduledFor;
600  }
601  // done
602  return pattr->mScheduledFor;
603 }
604 
605 
606 
607 //DoWrite(rTr,rLabel)
608 void ProposingExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
609  (void) pContext;
610  std::string label=rLabel;
611  if(label=="") label = "Executor";
612  rTw.WriteBegin(label);
614  Conditions().Write(rTw,"Conditions",this);
615  mSimEvents.Write(rTw,"SimEvents");
616  rTw.WriteEnd(label);
617 }
618 
619 //DoRead(rTr,rLabel)
620 void ProposingExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
621  (void) pContext;
622  FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<")");
623  std::string label=rLabel;
624  if(label=="") label = "Executor";
625  rTr.ReadBegin(label);
626 
627  while(!rTr.Eos(label)) {
628  FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<"): loop");
629  // peek token
630  Token token;
631  rTr.Peek(token);
632  // case 1: generators
633  if(token.Type()==Token::Begin)
634  if(token.StringValue()=="Generators") {
636  continue;
637  }
638  // case 2: conditions
639  if(token.Type()==Token::Begin)
640  if(token.StringValue()=="Conditions") {
641  SimConditionSet conditions;
642  conditions.Read(rTr,"Conditions",this);
643  Conditions(conditions);
644  continue;
645  }
646  // case 3: event attributes
647  if(token.Type()==Token::Begin)
648  if(token.StringValue()=="SimEvents") {
649  mSimEvents.Read(rTr,"SimEvents");
650  continue;
651  }
652  // case 3: event attributes (compatibility mode)
653  if(token.Type()==Token::Begin)
654  if(token.StringValue()=="SimEventAttributes") {
655  mSimEvents.Read(rTr,"SimEventAttributes");
656  continue;
657  }
658  // else report error
659  std::stringstream errstr;
660  errstr << "Invalid token, generators, conditions or simeventattribute section expected, " << rTr.FileLine();
661  throw Exception("ProposingExecutor::DoRead", errstr.str(), 502);
662  }
663  rTr.ReadEnd(label);
664  FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<"): done");
665  Reset();
666 }
667 
668 
669 // revert executors state to past step from buffer
671  FD_DX("ProposingExecutor(" << this << ")::RevertToStep("<< step << ")");
672  // call base
673  bool res=LoggingExecutor::RevertToStep(step);
674  // bail out
675  if(!res) return false;
676  // reset my dynamic data
677  ResetProposer();
678  // done
679  return true;
680 }
681 
682 } // end namespace
683 
684 
685 
686 
687 
688 /*
689  Scratch: how to record relevant clocks in Schedule()
690  This might be interesting to sense resets that invalidate delay type events
691 
692  // record relevant clocks
693  pattr->mRelevantClocks.Clear();
694  for(Iterator git=Begin(); git!=End(); git++){
695  pattr->mRelevantClocks.InsertSet(git->Generator().Invariant(git->CurrentState()).ActiveClocks());
696  TransSet::Iterator tit = git->Generator().TransRelBegin(git->CurrentState(),*eit);
697  pattr->mRelevantClocks.InsertSet(git->Generator().Guard(*tit).ActiveClocks());
698  }
699  FD_DS("ProposingExecutor::ExecuteEvent(): relevant clocks " << pattr->mRelevantClocks.ToString());
700 
701 */
702 
703 
704 
705 
706 /*
707  Scratch: how to figure whether relevant clocks, guards, or invariants changed
708  This was required for the old internal type events. Depreciated.
709 
710 
711 //EventValidity(Idx, Idx, T_state_vec, T_state_vec)
712 bool ProposingExecutor::EventValidity(Idx ev, Idx executedEvent,
713  const ParallelState& oldStateVec, const ParallelState& newStateVec) {
714  unsigned int i=0;
715  Iterator xit;
716  TransSet::Iterator tit;
717  TimeConstraint::Iterator oldcit,newcit;
718  ClockSet::Iterator clit;
719  ClockSet* pclocks = &mSimEvents.Attributep(ev)->mRelevantClocks;
720 
721  //Check if event was indeed active and is is still active
722  if(!Active(ev, oldStateVec)){
723  FD_DS("ProposingExecutor::EventValidity(): Event "<<Alphabet().SymbolicName(ev)
724  << " has not been active in last parallel state");
725  return false;
726  }
727  if(!Active(ev, newStateVec)){
728  FD_DS("ProposingExecutor::EventValidity(): Event "<<Alphabet().SymbolicName(ev)
729  <<" is not active in current parallel state");
730  return false;
731  }
732 
733 
734  //Check if relevant clocks are affected
735  FD_DS("ProposingExecutor::EventValidity(): test clocks for " << Alphabet().Str(ev));
736 
737  for(xit=Begin(); xit!=End(); ++xit, i++){
738  // If this excutor did not execute anything, nothing changed at all
739  if(!xit->Generator().ExistsEvent(executedEvent)) continue;
740  // If this excutor does not share the event, no guards/invs/resets affects its enabled status
741  if(!xit->Generator().ExistsEvent(ev)) continue;
742  //Check if a reset of a relevant clock was executed
743  tit=xit->Generator().TransRelBegin(oldStateVec[i],executedEvent);
744  FD_DS("ProposingExecutor::EventValidity(): test resets of " << Generator().TStr(*tit));
745  const ClockSet resetClocks=xit->Generator().Resets(*tit);
746  if(!(resetClocks * (*pclocks)).Empty()) {
747  FD_DS("ProposingExecutor::EventValidity(): relevant clock reset in " << xit->Name());
748  return false;
749  }
750  // If the state didnt change, neither did guards/invariants
751  if(oldStateVec[i]==newStateVec[i]) continue;
752  //Check if guards have changed wrt relevant clocks
753  tit=xit->Generator().TransRelBegin(oldStateVec[i],ev);
754  FD_DS("ProposingExecutor::EventValidity(): compare old guard of " << Generator().TStr(*tit));
755  TimeConstraint oldGuard=xit->Generator().Guard(*tit);
756  tit=xit->Generator().TransRelBegin(newStateVec[i],ev);
757  FD_DS("ProposingExecutor::EventValidity(): ... with guard of " << Generator().TStr(*tit));
758  TimeConstraint newGuard=xit->Generator().Guard(*tit);
759  for(ClockSet::Iterator cit=pclocks->Begin(); cit!=pclocks->End(); cit++) {
760  if(oldGuard.Interval(*cit)!=newGuard.Interval(*cit)) {
761  FD_DS("ProposingExecutor::EventValidity(): invalidate for change in guard wrt clock " <<
762  pclocks->SymbolicName(*cit));
763  FD_DS("ProposingExecutor::EventValidity(): old guard " << oldGuard.ToString());
764  FD_DS("ProposingExecutor::EventValidity(): new guard " << newGuard.ToString());
765  return false;
766  }
767  }
768  //Check if invariants have changed
769  TimeConstraint oldInv=xit->Generator().Invariant(oldStateVec[i]);
770  TimeConstraint newInv=xit->Generator().Invariant(newStateVec[i]);
771  for(ClockSet::Iterator cit=pclocks->Begin(); cit!=pclocks->End(); cit++) {
772  if( oldInv.Interval(*cit)!=newInv.Interval(*cit)) {
773  FD_DS("ProposingExecutor::EventValidity(): invalidate for change in invariant wrt clock " <<
774  pclocks->SymbolicName(*cit));
775  FD_DS("ProposingExecutor::EventValidity(): old inv " << oldInv.ToString());
776  FD_DS("ProposingExecutor::EventValidity(): new inv " << newInv.ToString());
777  return false;
778  }
779  }
780  } // loop all generators
781  FD_DS("ProposingExecutor::EventValidity(): Event " << Alphabet().SymbolicName(ev)<< " is still valid");
782  return true;
783 }
784 
785 */
786 
787 
788 
789 
790 
791 
792 
#define FD_DC(message)
Debug: optional report on container operations.
#define FD_NAMELEN
Length of strings for text fields in token output.
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
faudes type implementation macros, overall
Definition: cfl_types.h:946
Faudes exception class.
Executor with logging facilities.
Definition: sp_lpexecutor.h:85
virtual bool RevertToStep(Idx step)
Revert executors state to past step from buffer.
void DoAssign(const LoggingExecutor &rSrc)
Assignment method.
virtual void Clear(void)
Clear all data.
virtual bool ExecuteTime(Time::Type duration)
Let time pass without executing a transition.
const SimConditionSet & Conditions(void) const
Read-only access to simulation conditions.
virtual bool ExecuteEvent(Idx event)
Execute transition.
Time::Type CurrentTime(void) const
Get clock time.
virtual void Reset(void)
Goto initial state.
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
bool Exists(const Idx &rIndex) const
Test existence of index.
const EventSet & EnabledEvents() const
Get events that are enabled at current (timed) state.
const ParallelState & CurrentParallelState(void) const
Get current discrete state vector of the ParallelExecutor.
EventSet ActiveEventSet(const ParallelState &stateVec) const
Get events that are active in all TimedGenerators.
bool IsDeadlocked() const
Test for deadlocked.
const TimeInterval & EnabledInterval() const
Get an interval on which the set of enabled events is constant.
Iterator Begin(void) const
Definition: sp_pexecutor.h:181
std::string CurrentParallelTimedStateStr(void) const
Pretty printable string of current state.
virtual void DoWriteGenerators(TokenWriter &rTw) const
Write generator files section to TokenWriter.
const TimeInterval & EnabledTime() const
Get maximal duration that can pass without executing an event.
TimeInterval EnabledGuardTime(Idx event) const
Get interval on which the respective guard is satisfied.
std::string EStr(Idx event) const
Pretty printable string of event.
virtual void DoReadGenerators(TokenReader &rTr)
Reads generator files section from TokenReader.
const EventSet & Alphabet(void) const
Overall alphabet.
std::string EventName(Idx index) const
Event name lookup.
Definition: sp_pexecutor.h:210
TimeInterval EnabledEventTime(Idx event) const
Get interval on which the specified event is enabled.
Executer that proposes which transition to execute.
bool ExecuteEvent(Idx event)
Execute event.
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Reads proposing executor from TokenReader, see also public wrappers Type::Read.
virtual void Reset(void)
Reset the ProposingExecutor.
void ResetProposer(long int seed=0)
Reset stochastic state of events.
TimedEvent mProposal
Available proposal.
bool ExecuteTime(Time::Type duration)
Execute time duration.
ProposingExecutor()
Creates an emtpy ProposingExecutor.
bool RevertToStep(Idx step)
Revert executor to past step.
TimedEvent ExecuteNextTransition()
Execute next transition.
std::string EventStatesToString(void) const
Inspect stochastic event states (debugging)
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Write to TokenWriter, see also public wrappers Type::Write.
const SimEventAttribute & EventAttribute(Idx index) const
Simulation event attribute lookup.
Time::Type Schedule(Idx event, SimEventAttribute *pattr)
Evaluate random variable to schedule event.
virtual void Clear(void)
Clear all data (generators, simulation attributes etc)
void DoAssign(const ProposingExecutor &rSrc)
Assignment method.
const TimedEvent & ProposeNextTransition()
Propose next transition.
bool mPValid
Valid proposal available.
const sEventSet & Alphabet(void) const
Access alphabet (incl simulation event attributes)
bool ExecuteTransition(const TimedEvent &tevent)
Execute event by transition.
sEventSet mSimEvents
Simulation event attributes, incl stochastic and priority data.
Set of simulation named conditions.
Attribute for an event in the context of simulation.
Time::Type mExpiresAt
Time at which the recent schedule expires.
Time::Type mScheduledFor
Next scheduled occurence of this event relative to current time.
void Priority(const SimPriorityEventAttribute &rPriorityAttribute)
Set priority behaviour.
TimeInterval mReferenceInterval
Time domain on which the recent schedule was computed.
std::string Str(void) const
Debug string, incl state.
bool IsPriority(void) const
Test for priority property.
bool IsStochastic(void) const
Test for stochastic property.
void Stochastic(const SimStochasticEventAttribute &rStochasticAttribute)
Set stochastic behaviour.
Time::Type mDelayFor
Amount of time to defer the event.
std::string Str(const Idx &rIndex) const
Return pretty printable symbolic name for index.
Definition: cfl_nameset.h:1190
Attr * Attributep(const Idx &rElem)
Definition: cfl_nameset.h:848
virtual void InsertSet(const NameSet &rOtherSet)
Inserts elements of rOtherSet.
Definition: cfl_nameset.h:1038
const Attr & Attribute(const Idx &rElem) const
Definition: cfl_nameset.h:849
virtual TaNameSet & Assign(const TBaseSet< Idx > &rSrc)
Relaxed assignment method (uses base class to maintain attributes)
Definition: cfl_nameset.h:973
Model of a time interval.
void LB(Time::Type time)
Set the lower bound to a given value.
void SetPositive(void)
Set to positive [0, inf)
void PositiveLeftShift(Time::Type time)
Transform by left shift and intersection with [0, inf)
void Canonical(void)
Convert to canonical representation.
bool UBinf(void) const
Test for upper bound infinity.
bool In(Time::Type time) const
Test whether a point satisfies interval.
std::string Str(void) const
Pretty printable string.
void UBincl(bool incl)
Configures the upper bound to be inclusive.
void LBincl(bool incl)
Configures the lower bound to be inclusive.
void UB(Time::Type time)
Set the upper bound to a given value.
void SetEmpty(void)
Set to empty (1, -1)
bool Empty(void) const
Test interval for empty set.
void Intersect(const TimeInterval &rOtherInterval)
Intersect this interval with other interval.
static Type UnDef(void)
Undefined time value.
Int Type
Datatype for point on time axis.
static Type Quantize(Float x)
Discretize (when using cosmetic float time: "step*(round(t/step))".
static std::string Str(Type time)
convert to string
static Type Step(void)
Smallest representable time step.
static Type Max(void)
Maximum time, associated with infinitiy.
static Float FromFloat(Float x)
Convert From float (for convenient token-reading only)
Global Tyoedefs.
Definition: sp_executor.h:53
Time::Type mTime
Definition: sp_executor.h:56
A TokenReader reads sequential tokens from a file or string.
std::string FileLine(void) const
Return "filename:line".
bool Eos(const std::string &rLabel)
Peek a token and check whether it ends the specified section.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
bool Peek(Token &token)
Peek next token.
A TokenWriter writes sequential tokens to a file, a string or stdout.
void WriteEnd(const std::string &rLabel)
Write end label.
void WriteBegin(const std::string &rLabel)
Write begin label.
Tokens model atomic data for stream IO.
Definition: cfl_token.h:54
const std::string & StringValue(void) const
Get string value of a name token.
Definition: cfl_token.cpp:178
@ Begin
<label> (begin of section)
Definition: cfl_token.h:84
TokenType Type(void) const
Get token Type.
Definition: cfl_token.cpp:199
Base class of all libFAUDES objects that participate in the run-time interface.
Definition: cfl_types.h:239
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Read configuration data from file with label specified.
Definition: cfl_types.cpp:261
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
Definition: cfl_types.cpp:169
virtual Type & Assign(const Type &rSrc)
Assign configuration data from other object.
Definition: cfl_types.cpp:77
void Write(const Type *pContext=0) const
Write configuration data to console.
Definition: cfl_types.cpp:139
virtual void Clear(void)
Clear all set.
Definition: cfl_baseset.h:1911
Iterator End(void) const
Iterator to the end of set.
Definition: cfl_baseset.h:1905
Iterator Begin(void) const
Iterator to the begin of set.
Definition: cfl_baseset.h:1900
double ran_gauss(double mu, double sigma, Time::Type tossLB, Time::Type tossUB)
Sample a random variable gaussian distributed on a restricted interval Distribution: f(t) = 1 / sqrt(...
Definition: sp_random.cpp:132
long ran_uniform_int(long a, long b)
Sample a discrete random variable uniformly on interval [a;b) Distribution: p(n) = 1/(b-a-1)
Definition: sp_random.cpp:98
double ran_exponential(double mu)
Sample a random variable exponentially Distribution: f(t) dt = 1/mu exp(-t/mu) dt for t>=0.
Definition: sp_random.cpp:107
void ran_init(long seed)
Initialize random generator.
Definition: sp_random.cpp:67
double ran_uniform(double a, double b)
Sample a random variable uniformly on interval [a;b) Distribution: f(t) dt= {1/(b-a)} dt for t,...
Definition: sp_random.cpp:91
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
std::string ExpandString(const std::string &rString, unsigned int len)
Fill string with spaces up to a given length if length of the string is smaller than given length par...
Definition: cfl_utils.cpp:80
#define FD_DS(message)
Definition: sp_executor.h:34
#define FD_DX(message)
Definition: sp_executor.h:27
Executor that proposes transitions to execute.

libFAUDES 2.32f --- 2024.12.22 --- c++ api documentaion by doxygen