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 #include <ctime>
15 
16 namespace faudes {
17 
18 // std faudes type
19 FAUDES_TYPE_IMPLEMENTATION(ProposingExecutor, ProposingExecutor, ParallelExecutor)
20 
21 // constructor
23  mPValid=false;
24 }
25 
26 // copy constructor
28 {
29  mPValid=false;
30  Assign(rOther);
31 }
32 
33 // clear static data
36  mSimEvents.Clear();
37  mPValid=false;
38 }
39 
40 // DoAssign(other)
42  FD_DX("ProposingExecutor(" << this << ")::DoAssign(other)");
43  // my members
45  // base
47 }
48 
49 // lookup event attribute
51  return mSimEvents.Attribute(index);
52 }
53 
54 // set simulation event attribute
56  mSimEvents.Attribute(index,rAttr);
57 }
58 
59 // set execution properties from attributed event set
60 void ProposingExecutor::Alphabet(const sEventSet& rAlphabet) {
61  // set ...
62  mSimEvents=rAlphabet;
63  // ... and ensure to cover all relevant alphabet
65 }
66 
67 // clear dynamic data (reset state)
69  FD_DS("ProposingExecutor::ResetProposer()");
70  //Initialize random number generator with computer system time as seed
71  if(seed == 0) seed = static_cast<long>(time(NULL));
72  ran_init(seed);
73  // schedule all events
74  EventSet::Iterator eit;
75  for(eit=Alphabet().Begin(); eit!=Alphabet().End(); ++eit){
78  pattr->mDelayFor=tpTime::UnDef;
79  pattr->mExpiresAt=0;
80  if(pattr->IsPriority()) continue;
81  if(!pattr->IsStochastic()) continue;
82  Schedule(*eit,pattr);
83  }
84  // invalidate proposal
85  mPValid=false;
86  FD_DS("ProposingExecutor::ResetProposer(): done");
87 
88 
89 }
90 
91 // clear dynamic data (reset state)
92 void ProposingExecutor::Reset(long int seed){
93  FD_DS("ProposingExecutor::Reset()");
96  ResetProposer(seed);
97  FD_DS("ProposingExecutor::Reset(): done");
98 }
99 
100 
101 //EventStatesToString
103  std::stringstream retstr;
104  EventSet::Iterator eit;
105  for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit){
106  const SimEventAttribute& attr= mSimEvents.Attribute(*eit);
107  retstr<< "% simulation state: "<< ExpandString(mSimEvents.Str(*eit),FD_NAMELEN) << ": ";
108  retstr<< "enabled: " << ExpandString(EnabledEventTime(*eit).Str(),FD_NAMELEN) << ": ";
109  retstr<< attr.Str();
110  if( eit!= --mSimEvents.End()) {
111  retstr << std::endl;
112  }
113  }
114  return retstr.str();
115 }
116 
117 
118 
119 //ExecuteTime: todo: may hang + performance issue
121  FD_DS("ProposingExecutor::ExecuteTime(): LoggingExecutor to execute time "<< duration);
122  if(!LoggingExecutor::ExecuteTime(duration)) return false;
123  // update stochastic event state
124  EventSet::Iterator eit;
125  for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit) {
127  // stochastic only
128  if(!pattr->IsStochastic()) continue;
129  // shift relative time: schedule/expiring time
130  if(pattr->mScheduledFor!=tpTime::UnDef)
131  if(pattr->mScheduledFor!=tpTime::Max)
132  pattr->mScheduledFor -= duration;
133  if(pattr->mExpiresAt!=tpTime::UnDef)
134  if(pattr->mExpiresAt!=tpTime::Max)
135  pattr->mExpiresAt -= duration;
136  // shift reference interval for type trigger
138  pattr->mReferenceInterval.PositiveLeftShift(duration);
139  }
140  // shift reference interval for type delay
141  if(pattr->Stochastic().mType==SimStochasticEventAttribute::Delay) {
142  if(!pattr->mReferenceInterval.Empty()) {
143  tpTime::Type delay = duration - pattr->mReferenceInterval.LB();
144  if(delay>0) pattr->mDelayFor-=delay;
145  pattr->mReferenceInterval.PositiveLeftShift(duration);
146  }
147  }
148  // re-schedule (required for type extern and delay)
149  if(pattr->mExpiresAt<=0) Schedule(*eit,pattr);
150  }
151  FD_DS("ProposingExecutor::ExecuteTime(): LoggingExecutor to execute time: done ");
152  // case a: no valid proposal anyway
153  if(!mPValid) return true;
154  // case b: proposal remains valid
155  if(mProposal.Time==tpTime::Max) return true;
156  // case c: proposal becomes invalid
157  if(mProposal.Time < duration) { mPValid=false; return true;}
158  // case d: adjust proposal
159  mProposal.Time-=duration;
160  mPValid= (mProposal.Time>0) || (mProposal.Event!=0);
161  return true;
162 }
163 
164 //ExecuteEvent
166  FD_DS("ProposingExecutor::ExecuteEvent(): ProposingExecutor to execute event "<< mSimEvents.Str(event));
167 
168  // (try to) execute
169  if(!LoggingExecutor::ExecuteEvent(event)) return false;
170  FD_DS("ProposingExecutor::ExecuteEvent(): executed "<< EventName(event));
171 
172  // record enabled events
173  const EventSet newActiveEvents=ActiveEventSet(CurrentParallelState());
174  FD_DS("ProposingExecutor::ExecuteEvent(): new active events "<< newActiveEvents.ToString());
175 
176 
177  // invalidate/re-schedule event states
178  EventSet::Iterator eit;
179  for(eit=mSimEvents.Begin(); eit!=mSimEvents.End(); ++eit) {
181  // stochastic only
182  if(!pattr->IsStochastic()) continue;
183  // invalidate schedule: type trigger
185  TimeInterval gtime=EnabledGuardTime(*eit);
186  gtime.Canonical();
187  if(gtime!=pattr->mReferenceInterval) {
188  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating trigger type event "<< EStr(*eit));
189  pattr->mExpiresAt = 0;
190  }
191  }
192  // update state: type delay (only if not expired)
194  if(pattr->mExpiresAt > 0) {
195  TimeInterval etime=EnabledEventTime(*eit);
196  etime.Canonical();
197  pattr->mReferenceInterval=etime;
199  pattr->mExpiresAt=tpTime::Max;
200  tpTime::Type schedule= etime.LB()+ pattr->mDelayFor;
201  if(etime.In(schedule)) {
202  pattr->mScheduledFor=schedule;
203  pattr->mExpiresAt=pattr->mScheduledFor+1;
204  FD_DS("ProposingExecutor::ExecuteEvent(): delay event " << EStr(*eit) << ": etime "
205  << etime.Str() << " scheduled " << schedule);
206  }
207  }
208  // invalidate schedule: event executed
209  if(*eit==event) {
210  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for executed event "<< EStr(*eit));
211  pattr->mExpiresAt = 0;
212  }
213  /*
214  // invalidate schedule: type all reset
215  if(pattr->Stochastic().mType==SimStochasticEventAttribute::State) {
216  pattr->mExpiresAt = 0;
217  pattr->mScheduledFor = 0;
218  pattr->mDelayFor = tpTime::UnDef;
219  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for state-type " << EStr(*eit));
220  }
221  */
222  /*
223  // invalidate schedule: type intern
224  if(pattr->Stochastic().mType==SimStochasticEventAttribute::Intern) {
225  if(!EventValidity(*eit, event, oldActiveStateVec,newActiveStateVec)){
226  pattr->mExpiresAt = 0;
227  pattr->mScheduledFor = 0;
228  pattr->mDelayFor = tpTime::UnDef;
229  FD_DS("ProposingExecutor::ExecuteEvent(): invalidating state for intern-type " << EStr(*eit));
230  }
231  }
232  */
233  // re-schedule
234  if(newActiveEvents.Exists(*eit))
235  if(pattr->mExpiresAt<=0) Schedule(*eit,pattr);
236  } // loop all events
237 
238  // invalidate proposal
239  mPValid=false;
240  // done
241  FD_DS("ProposingExecutor::ExecuteEvent(): done");
242  return true;
243 }
244 
245 
246 //ExecuteTransition (rel time!) (event 0 for time only)
248 
249  if(!ExecuteTime(executeEvent.Time)) return false;
250  if(executeEvent.Event==0) return true;
251  if(!ExecuteEvent(executeEvent.Event)) return false;
252 
253  return true;
254 }
255 
256 
257 
258 //ProposeNextTransition (event 0 for time only)
259 // todo: combine loops for performance
261 
262  FD_DS("ProposingExecutor::ProposeNextTransition()");
263 
264  // return valid proposal
265  if(mPValid) return mProposal;
266 
267  // compute valid proposal now
268  mPValid=true;
269 
270  // vars
271  EventSet::Iterator eit;
272  TimeInterval enabledInterval=EnabledInterval();
273  TimeInterval enabledTime=EnabledTime();
274  const EventSet enabledEvents = EnabledEvents();
275 
276  // report
277  FD_DS("\n" << EventStatesToString());
278  FD_DS("ProposingExecutor::ProposeNextTransition(): current time: " <<
279  CurrentTime());
280  FD_DS("ProposingExecutor::ProposeNextTransition(): timed state: " <<
282  FD_DS("ProposingExecutor::ProposeNextTransition(): active events: " <<
284  FD_DS("ProposingExecutor::ProposeNextTransition(): enabled interval: " <<
285  enabledInterval.Str());
286  FD_DS("ProposingExecutor::ProposeNextTransition(): enabled time: " <<
287  enabledTime.Str());
288  FD_DS("ProposingExecutor::ProposeNextTransition(): enabled events: " << std::endl <<
289  EnabledEvents().ToString());
290 
291  // find candidate to execute
292  Idx candidate=0;
293  std::vector<faudes::Idx> candidates;
294  tpTime::Type passtime=0;
295 
296  //check if a priority event occurs in analyzed interval
297  long int prio = -1;
298  for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit) {
300  if(!pattr->IsPriority()) continue;
301  // priority wins
302  if(pattr->Priority().mPriority >prio) {
303  prio= pattr->Priority().mPriority;
304  candidate=*eit;
305  candidates.clear();
306  candidates.push_back(candidate);
307  }
308  // indicate non determinism
309  if((pattr->Priority().mPriority ==prio) && (prio>=0))
310  candidates.push_back(*eit);
311  }
312 
313  // choose arbitrarily
314  if(candidates.size()>1) {
315  candidate=candidates[ran_uniform_int(0,candidates.size())];
316  }
317 
318  // propose priority candidate now
319  if(candidate>0) {
320  FD_DS("ProposingExecutor::ProposeNextTransition(): propose by priority: " << mSimEvents.Str(candidate));
321  mProposal.Event=candidate;
322  mProposal.Time=0;
323  return mProposal;
324  }
325 
326  //check if stochastic events are enabled
327  tpTime::Type occurence = -1;
328  for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit){
330  if(!pattr->IsStochastic()) continue;
331  if(pattr->mScheduledFor == tpTime::UnDef) continue; // dont need this anyway
332  if(enabledInterval.In(pattr->mScheduledFor)) {
333  // occurence wins
334  if(pattr->mScheduledFor < occurence || occurence < 0) {
335  occurence= pattr->mScheduledFor;
336  candidate=*eit;
337  candidates.clear();
338  candidates.push_back(candidate);
339  }
340  // indicate non determinism
341  if(pattr->mScheduledFor == occurence)
342  candidates.push_back(*eit);
343  }
344  }
345 
346  // choose arbitrarily
347  if(candidates.size()>1) {
348  candidate=candidates[ran_uniform_int(0,candidates.size())];
349  }
350 
351  // propose stochastic candidate now
352  if(candidate>0) {
353  FD_DS("ProposingExecutor::ProposeNextTransition(): propose by stochastic: " << mSimEvents.Str(candidate) << " for " << tpTime::Str(occurence));
354  mProposal.Event=candidate;
355  mProposal.Time=occurence;
356  return mProposal;
357  }
358 
359  // check if we can pass time
360  if(!enabledTime.Empty()) {
361  // pass enabled interval
362  passtime=enabledInterval.UB();
363  if(enabledInterval.Empty()) passtime=0;
364  // be sure to be beyond enabled interval but within enabled time
365  if(enabledInterval.UBincl()) passtime+=tpTime::Step;
366  // be sure to be within enabled time
367  if(!enabledTime.In(passtime)) passtime-=tpTime::Step;
368  // fix infty
369  if(enabledTime.UBinf() && enabledInterval.UBinf()) passtime=tpTime::Max;
370  // if we can go for ever, step with minstep
371  // if(passtime==tpTime::Max) passtime=tpTime::Step;
372  // only execute relevant steps -- otherwise max execute priority event
373  if(passtime!=0) {
374  FD_DS("ProposingExecutor::ProposeNextTransition(): propose to pass time: "<< tpTime::Str(passtime));
375  mProposal.Event=0;
376  mProposal.Time=passtime;
377  return mProposal;
378  }
379  }
380 
381  //check if prevent priority event occurs in analyzed interval
382  prio =0;
383  for(eit=enabledEvents.Begin(); eit!=enabledEvents.End(); ++eit){
385  if(!pattr->IsPriority()) continue;
386  // priority wins
387  if(pattr->Priority().mPriority >prio || prio==0) {
388  prio= pattr->Priority().mPriority;
389  candidate=*eit;
390  candidates.clear();
391  candidates.push_back(candidate);
392  }
393  // alphabetical
394  if((pattr->Priority().mPriority ==prio) && (prio <0))
395  candidates.push_back(*eit);
396  }
397 
398  // choose arbitrarily
399  if(candidates.size()>1) {
400  candidate=candidates[ran_uniform_int(0,candidates.size())];
401  }
402 
403  // propose prevent priority candidate now
404  if(candidate>0) {
405  FD_DS("ProposingExecutor::ProposeNextTransition(): propose by priority: " << mSimEvents.Str(candidate));
406  mProposal.Event=candidate;
407  mProposal.Time=passtime;
408  return mProposal;
409  }
410 
411  //Deadlock request
412  if(IsDeadlocked()){
413  FD_DS("ProposingExecutor::ProposeNextTransition(): Deadlocked");
414  mProposal.Event=0;
416  return mProposal;
417  }
418 
419  // nothing to propose but time
420  FD_DS("ProposingExecutor::ProposeNextTransition(): Lifelock");
421  mProposal.Event=0;
423  return mProposal;
424 }
425 
426 
427 //ExecuteNextTransition
429  FD_DS("ProposingExecutor::ExecuteNextTransition() *********************************************************** ");
430 
431  tpTime::Type currentTime=0;
432  TimedEvent execTimedEvent;
433 
434  //********************************************
435  //Execution loop
436  //********************************************
437  while(true){
438 
439  // get proposal
440  execTimedEvent = ProposeNextTransition();
441 
442  // deadlocked? (todo: mintime/min float number etc)
443  if((execTimedEvent.Event==0) && (execTimedEvent.Time==0)) break;
444  if(IsDeadlocked()) break;
445 
446  // execute (time and/or event)
447  ExecuteTransition(execTimedEvent);
448 
449  // done if there was an event
450  if(execTimedEvent.Event!=0) break;
451 
452  // record time
453  currentTime+=execTimedEvent.Time;
454 
455  }
456 
457  // success
458  if(execTimedEvent.Event!=0) {
459  execTimedEvent.Time=currentTime;
460  return execTimedEvent;
461  }
462 
463  // failure
464  execTimedEvent.Time=tpTime::UnDef;
465  execTimedEvent.Event=0;
466  return execTimedEvent;
467 }
468 
469 
470 
471 //Schedule() by attribute
473  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << ")");
474  // insist in stochastic attribute
475  if(!pattr->IsStochastic()) {
476  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): no stoxchastic attribute found");
478  return tpTime::UnDef;
479  }
480  // only reschedule when expired
481  if(pattr->mExpiresAt>0) {
482  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): event not expired");
483  return pattr->mScheduledFor;
484  }
485  // invalidate event state;
486  tpTime::Type recentschedule=pattr->mScheduledFor;
488  pattr->mExpiresAt=tpTime::UnDef;
489  pattr->mDelayFor=tpTime::UnDef;
490  pattr->mReferenceInterval.SetEmpty();
491  // target interval for sample, defaults to positive axis
492  TimeInterval atarget;
493  atarget.SetPositive();
494  // trigger type events have restricted target
495  if(pattr->Stochastic().mType == SimStochasticEventAttribute::Trigger) {
496  atarget.Intersect(EnabledGuardTime(event));
497  atarget.Canonical();
498  }
499  // cannot have empty target
500  if(atarget.Empty()) {
501  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): empty target");
502  return tpTime::UnDef;
503  }
504  // report timed automaton target
505  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): for timed automaton target " << atarget.Str());
506  // get pdf parameters to figure restricted support
507  std::vector<double> pdfparavec=pattr->Stochastic().mParameter;
508  TimeInterval starget;
509  starget.LB(static_cast<tpTime::Type>(pdfparavec[0]));
510  starget.UB(static_cast<tpTime::Type>(pdfparavec[1]));
511  starget.LBincl(true);
512  starget.UBincl(false);
513  atarget.Intersect(starget);
514  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): for restricted target " << atarget.Str());
515  if(atarget.Empty()) {
516  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): empty target");
517  return tpTime::UnDef;
518  }
519  // do the sample
520  double occtime=-1;
521  switch(pattr->Stochastic().mPdf){
522  // exponential
524  occtime=ran_exponential(pdfparavec[2],atarget.LB(),atarget.UB());
525  break;
526  // gauss
528  occtime=ran_gauss(pdfparavec[2],pdfparavec[3],atarget.LB(),atarget.UB());
529  break;
530  //Uniform
532  occtime=ran_uniform(atarget.LB(),atarget.UB());
533  break;
534  //Undefined
536  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << ") internal error: no valid stochastic defs");
537  return tpTime::UnDef;
538  break;
539  }
540  // report failure
541  if(occtime < 0) {
542  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): sampling failed: A");
543  return tpTime::UnDef;
544  }
545  // discretize tpTime::Type
546  long int round= static_cast<unsigned long>(occtime/tpTime::Step + 0.5);
547  tpTime::Type schedule = static_cast<tpTime::Type>(round*tpTime::Step);
548  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): random sample " << schedule
549  << "(" << occtime << ")");
550  // interpret sample
551  switch(pattr->Stochastic().mType){
552  // interpret sample: trigger type
554  // paranoid ... fix rounding issues
555  if(!atarget.In(schedule)) schedule+=tpTime::Step;
556  if(!atarget.In(schedule)) schedule-=2*tpTime::Step;
557  if(!atarget.In(schedule)) schedule= tpTime::UnDef;
558  // paranoid ... report failure
559  if(!atarget.In(schedule)) {
560  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): sampling failed: B");
561  return tpTime::UnDef;
562  }
563  // set schedule
564  pattr->mScheduledFor=schedule;
565  pattr->mExpiresAt=atarget.UB();
566  pattr->mDelayFor=tpTime::UnDef;
567  pattr->mReferenceInterval=atarget;
568  break;
569  // interpret sample: extern type // issue: re-sampling can hang
571  pattr->mScheduledFor=schedule;
572  if(recentschedule!=tpTime::UnDef)
573  pattr->mScheduledFor+=recentschedule;
574  pattr->mExpiresAt=pattr->mScheduledFor+1;
575  pattr->mDelayFor=tpTime::UnDef;
576  pattr->mReferenceInterval.SetEmpty();
577  if(pattr->mScheduledFor<0) {
578  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): re-sampling");
579  return Schedule(event,pattr);
580  }
581  break;
582  // interpret sample: delay type
584  TimeInterval etime=EnabledEventTime(event);
585  etime.Canonical();
586  FD_DS("ProposingExecutor::Schedule(" << EStr(event) << "): delay type: etime "
587  << etime.Str() << " delay for " << schedule);
588  pattr->mDelayFor=schedule;
589  pattr->mReferenceInterval=etime;
591  pattr->mExpiresAt=tpTime::Max;
592  schedule+=etime.LB();
593  if(etime.In(schedule)) {
594  pattr->mScheduledFor=schedule;
595  pattr->mExpiresAt=pattr->mScheduledFor+1;
596  }
597  return pattr->mScheduledFor;
598  }
599  // done
600  return pattr->mScheduledFor;
601 }
602 
603 
604 
605 //DoWrite(rTr,rLabel)
606 void ProposingExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
607  (void) pContext;
608  std::string label=rLabel;
609  if(label=="") label = "Executor";
610  rTw.WriteBegin(label);
612  Conditions().Write(rTw,"Conditions",this);
613  mSimEvents.Write(rTw,"SimEvents");
614  rTw.WriteEnd(label);
615 }
616 
617 //DoRead(rTr,rLabel)
618 void ProposingExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
619  (void) pContext;
620  FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<")");
621  std::string label=rLabel;
622  if(label=="") label = "Executor";
623  rTr.ReadBegin(label);
624 
625  while(!rTr.Eos(label)) {
626  FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<"): loop");
627  // peek token
628  Token token;
629  rTr.Peek(token);
630  // case 1: generators
631  if(token.Type()==Token::Begin)
632  if(token.StringValue()=="Generators") {
634  continue;
635  }
636  // case 2: conditions
637  if(token.Type()==Token::Begin)
638  if(token.StringValue()=="Conditions") {
639  SimConditionSet conditions;
640  conditions.Read(rTr,"Conditions",this);
641  Conditions(conditions);
642  continue;
643  }
644  // case 3: event attributes
645  if(token.Type()==Token::Begin)
646  if(token.StringValue()=="SimEvents") {
647  mSimEvents.Read(rTr,"SimEvents");
648  continue;
649  }
650  // case 3: event attributes (compatibility mode)
651  if(token.Type()==Token::Begin)
652  if(token.StringValue()=="SimEventAttributes") {
653  mSimEvents.Read(rTr,"SimEventAttributes");
654  continue;
655  }
656  // else report error
657  std::stringstream errstr;
658  errstr << "Invalid token, generators, conditions or simeventattribute section expected, " << rTr.FileLine();
659  throw Exception("ProposingExecutor::DoRead", errstr.str(), 502);
660  }
661  rTr.ReadEnd(label);
662  FD_DC("ProposingExecutor::DoRead(rTr, " << rLabel<<"): done");
663  Reset();
664 }
665 
666 
667 // revert executors state to past step from buffer
669  FD_DX("ProposingExecutor(" << this << ")::RevertToStep("<< step << ")");
670  // call base
671  bool res=LoggingExecutor::RevertToStep(step);
672  // bail out
673  if(!res) return false;
674  // reset my dynamic data
675  ResetProposer();
676  // done
677  return true;
678 }
679 
680 } // end namespace
681 
682 
683 
684 
685 
686 /*
687  Scratch: how to record relevant clocks in Schedule()
688  This might be interesting to sense resets that invalidate delay type events
689 
690  // record relevant clocks
691  pattr->mRelevantClocks.Clear();
692  for(Iterator git=Begin(); git!=End(); git++){
693  pattr->mRelevantClocks.InsertSet(git->Generator().Invariant(git->CurrentState()).ActiveClocks());
694  TransSet::Iterator tit = git->Generator().TransRelBegin(git->CurrentState(),*eit);
695  pattr->mRelevantClocks.InsertSet(git->Generator().Guard(*tit).ActiveClocks());
696  }
697  FD_DS("ProposingExecutor::ExecuteEvent(): relevant clocks " << pattr->mRelevantClocks.ToString());
698 
699 */
700 
701 
702 
703 
704 /*
705  Scratch: how to figure whether relevant clocks, guards, or invariants changed
706  This was required for the old internal type events. Depreciated.
707 
708 
709 //EventValidity(Idx, Idx, T_state_vec, T_state_vec)
710 bool ProposingExecutor::EventValidity(Idx ev, Idx executedEvent,
711  const ParallelState& oldStateVec, const ParallelState& newStateVec) {
712  unsigned int i=0;
713  Iterator xit;
714  TransSet::Iterator tit;
715  TimeConstraint::Iterator oldcit,newcit;
716  ClockSet::Iterator clit;
717  ClockSet* pclocks = &mSimEvents.Attributep(ev)->mRelevantClocks;
718 
719  //Check if event was indeed active and is is still active
720  if(!Active(ev, oldStateVec)){
721  FD_DS("ProposingExecutor::EventValidity(): Event "<<Alphabet().SymbolicName(ev)
722  << " has not been active in last parallel state");
723  return false;
724  }
725  if(!Active(ev, newStateVec)){
726  FD_DS("ProposingExecutor::EventValidity(): Event "<<Alphabet().SymbolicName(ev)
727  <<" is not active in current parallel state");
728  return false;
729  }
730 
731 
732  //Check if relevant clocks are affected
733  FD_DS("ProposingExecutor::EventValidity(): test clocks for " << Alphabet().Str(ev));
734 
735  for(xit=Begin(); xit!=End(); ++xit, i++){
736  // If this excutor did not execute anything, nothing changed at all
737  if(!xit->Generator().ExistsEvent(executedEvent)) continue;
738  // If this excutor does not share the event, no guards/invs/resets affects its enabled status
739  if(!xit->Generator().ExistsEvent(ev)) continue;
740  //Check if a reset of a relevant clock was executed
741  tit=xit->Generator().TransRelBegin(oldStateVec[i],executedEvent);
742  FD_DS("ProposingExecutor::EventValidity(): test resets of " << Generator().TStr(*tit));
743  const ClockSet resetClocks=xit->Generator().Resets(*tit);
744  if(!(resetClocks * (*pclocks)).Empty()) {
745  FD_DS("ProposingExecutor::EventValidity(): relevant clock reset in " << xit->Name());
746  return false;
747  }
748  // If the state didnt change, neither did guards/invariants
749  if(oldStateVec[i]==newStateVec[i]) continue;
750  //Check if guards have changed wrt relevant clocks
751  tit=xit->Generator().TransRelBegin(oldStateVec[i],ev);
752  FD_DS("ProposingExecutor::EventValidity(): compare old guard of " << Generator().TStr(*tit));
753  TimeConstraint oldGuard=xit->Generator().Guard(*tit);
754  tit=xit->Generator().TransRelBegin(newStateVec[i],ev);
755  FD_DS("ProposingExecutor::EventValidity(): ... with guard of " << Generator().TStr(*tit));
756  TimeConstraint newGuard=xit->Generator().Guard(*tit);
757  for(ClockSet::Iterator cit=pclocks->Begin(); cit!=pclocks->End(); cit++) {
758  if(oldGuard.Interval(*cit)!=newGuard.Interval(*cit)) {
759  FD_DS("ProposingExecutor::EventValidity(): invalidate for change in guard wrt clock " <<
760  pclocks->SymbolicName(*cit));
761  FD_DS("ProposingExecutor::EventValidity(): old guard " << oldGuard.ToString());
762  FD_DS("ProposingExecutor::EventValidity(): new guard " << newGuard.ToString());
763  return false;
764  }
765  }
766  //Check if invariants have changed
767  TimeConstraint oldInv=xit->Generator().Invariant(oldStateVec[i]);
768  TimeConstraint newInv=xit->Generator().Invariant(newStateVec[i]);
769  for(ClockSet::Iterator cit=pclocks->Begin(); cit!=pclocks->End(); cit++) {
770  if( oldInv.Interval(*cit)!=newInv.Interval(*cit)) {
771  FD_DS("ProposingExecutor::EventValidity(): invalidate for change in invariant wrt clock " <<
772  pclocks->SymbolicName(*cit));
773  FD_DS("ProposingExecutor::EventValidity(): old inv " << oldInv.ToString());
774  FD_DS("ProposingExecutor::EventValidity(): new inv " << newInv.ToString());
775  return false;
776  }
777  }
778  } // loop all generators
779  FD_DS("ProposingExecutor::EventValidity(): Event " << Alphabet().SymbolicName(ev)<< " is still valid");
780  return true;
781 }
782 
783 */
784 
785 
786 
787 
788 
789 
790 

libFAUDES 2.26g --- 2015.08.17 --- c++ api documentaion by doxygen