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
15namespace faudes {
16
17// std faudes type
18FAUDES_TYPE_IMPLEMENTATION(ProposingExecutor, ProposingExecutor, ParallelExecutor)
19
20// constructor
22 mPValid=false;
23}
24
25// copy constructor
31
32// clear static data
38
39// DoAssign(other)
41 FD_DX("ProposingExecutor(" << this << ")::DoAssign(other)");
42 // my members
44 // base
46}
47
48// lookup event attribute
52
53// set simulation event attribute
55 mSimEvents.Attribute(index,rAttr);
56}
57
58// set execution properties from attributed event set
59void 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){
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)
95void 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
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;
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 <<
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;
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));
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");
419 return mProposal;
420 }
421
422 // nothing to propose but time
423 FD_DS("ProposingExecutor::ProposeNextTransition(): Lifelock");
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();
494 // target interval for sample, defaults to positive axis
495 TimeInterval atarget;
496 atarget.SetPositive();
497 // trigger type events have restricted target
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();
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)
608void 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)
620void 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
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)
712bool 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)
#define FD_NAMELEN
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition cfl_types.h:958
virtual bool RevertToStep(Idx step)
void DoAssign(const LoggingExecutor &rSrc)
virtual void Clear(void)
virtual bool ExecuteTime(Time::Type duration)
const SimConditionSet & Conditions(void) const
virtual bool ExecuteEvent(Idx event)
Time::Type CurrentTime(void) const
virtual void Reset(void)
bool Exists(const Idx &rIndex) const
const EventSet & EnabledEvents() const
const ParallelState & CurrentParallelState(void) const
EventSet ActiveEventSet(const ParallelState &stateVec) const
const TimeInterval & EnabledInterval() const
Iterator Begin(void) const
std::string CurrentParallelTimedStateStr(void) const
virtual void DoWriteGenerators(TokenWriter &rTw) const
const TimeInterval & EnabledTime() const
TimeInterval EnabledGuardTime(Idx event) const
std::string EStr(Idx event) const
virtual void DoReadGenerators(TokenReader &rTr)
const EventSet & Alphabet(void) const
std::string EventName(Idx index) const
TimeInterval EnabledEventTime(Idx event) const
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
virtual void Reset(void)
void ResetProposer(long int seed=0)
bool ExecuteTime(Time::Type duration)
const sEventSet & Alphabet(void) const
std::string EventStatesToString(void) const
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
const SimEventAttribute & EventAttribute(Idx index) const
Time::Type Schedule(Idx event, SimEventAttribute *pattr)
void DoAssign(const ProposingExecutor &rSrc)
const TimedEvent & ProposeNextTransition()
bool ExecuteTransition(const TimedEvent &tevent)
void Priority(const SimPriorityEventAttribute &rPriorityAttribute)
std::string Str(void) const
bool IsPriority(void) const
bool IsStochastic(void) const
void Stochastic(const SimStochasticEventAttribute &rStochasticAttribute)
Attr * Attributep(const Idx &rElem)
virtual std::string Str(const Idx &rIndex) const
const Attr & Attribute(const Idx &rElem) const
virtual void InsertSet(const NameSet &rOtherSet)
virtual TaNameSet & Assign(const TBaseSet< Idx > &rSrc)
void LB(Time::Type time)
void PositiveLeftShift(Time::Type time)
bool UBinf(void) const
bool In(Time::Type time) const
std::string Str(void) const
void UBincl(bool incl)
void LBincl(bool incl)
void UB(Time::Type time)
bool Empty(void) const
void Intersect(const TimeInterval &rOtherInterval)
static Type UnDef(void)
static Type Quantize(Float x)
static std::string Str(Type time)
static Type Step(void)
static Type Max(void)
static Float FromFloat(Float x)
std::string FileLine(void) const
bool Eos(const std::string &rLabel)
void ReadEnd(const std::string &rLabel)
void ReadBegin(const std::string &rLabel)
bool Peek(Token &token)
void WriteEnd(const std::string &rLabel)
void WriteBegin(const std::string &rLabel)
const std::string & StringValue(void) const
@ Begin
<label> (begin of section)
Definition cfl_token.h:84
TokenType Type(void) const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
virtual Type & Assign(const Type &rSrc)
Definition cfl_types.cpp:82
void Write(const Type *pContext=0) const
virtual void Clear(void)
Iterator End(void) const
Iterator Begin(void) const
double ran_gauss(double mu, double sigma, Time::Type tossLB, Time::Type tossUB)
long ran_uniform_int(long a, long b)
Definition sp_random.cpp:98
double ran_exponential(double mu)
void ran_init(long seed)
Definition sp_random.cpp:67
double ran_uniform(double a, double b)
Definition sp_random.cpp:91
uint32_t Idx
std::string ExpandString(const std::string &rString, unsigned int len)
Definition cfl_utils.cpp:80
#define FD_DS(message)
Definition sp_executor.h:34
#define FD_DX(message)
Definition sp_executor.h:27

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen