sp_executor.cpp
Go to the documentation of this file.
1 /** @file sp_executor.cpp Execute transitions in a timed generator */
2 
3 /*
4  FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2007 Ruediger Berndt
7  Copyright (C) 2007, 2010, 2024 Thomas Moor
8  Exclusive copyright is granted to Klaus Schmidt
9 
10 */
11 
12 
13 #include "sp_executor.h"
14 
15 namespace faudes {
16 
17 // std faudes type
19 
20 
21 // Executor(void)
23  FD_DX("Executor(" << this << ")::Executor()");
24  InsInitState("init");
25  Compile();
26 }
27 
28 // Exector(rGen)
30  FD_DX("Executor(" << this << ")::Executor(rGen)");
31  Assign(rGen);
32 }
33 
34 // Exector(filename)
35 Executor::Executor(const std::string& rFileName) : TimedGenerator() {
36  FD_DX("Executor(" << this << ")::Executor("<< rFileName <<")");
37  Read(rFileName);
38 }
39 
40 // Generator()
42  return *this;
43 }
44 
45 // Generator(rGen)
47  FD_DX("Executor::Generator(" << &rGen << ")");
48  Assign(*this);
49 }
50 
51 
52 // Compile()
53 void Executor::Compile(void) {
54  FD_DX("Executor(" << this << ")::Compile()");
55  // throw exception on non deterministic generator
56  if(!IsDeterministic() || InitState()==0) {
57  std::stringstream errstr;
58  errstr << "nondeterministic generator in simulation" << std::endl;
59  throw Exception("Executor::Compile", errstr.str(), 501);
60  }
61  // compile guards
63  for(tit=TransRelBegin(); tit!= TransRelEnd(); tit++) {
64  FD_DX("Executor(" << this << ")::Compile(): trans " << TStr(*tit));
65  TimeConstraint guard=Guard(*tit);
66  std::map<Idx,TimeInterval> guardtime;
67  ClockSet aclocks=guard.ActiveClocks();
68  ClockSet::Iterator cit;
69  for(cit=aclocks.Begin(); cit!= aclocks.End(); cit++)
70  guardtime[*cit]=guard.Interval(*cit);
71  mTransClockIntervalMap[*tit]=guardtime;
72  }
73  // compile invariants
74  StateSet::Iterator sit;
75  for(sit=StatesBegin(); sit!= StatesEnd(); sit++) {
76  FD_DX("Executor(" << this << ")::Compile(): state " << SStr(*sit));
77  TimeConstraint invariant=Invariant(*sit);
78  std::map<Idx,TimeInterval> invtime;
79  ClockSet aclocks=invariant.ActiveClocks();
80  ClockSet::Iterator cit;
81  for(cit=aclocks.Begin(); cit!= aclocks.End(); cit++)
82  invtime[*cit]=invariant.Interval(*cit);
83  mStateClockIntervalMap[*sit]=invtime;
84  }
85  // get ready
86  Reset();
87  FD_DX("Executor(" << this << ")::Compile(): done");
88 }
89 
90 // Clear()
91 void Executor::Clear(void) {
92  FD_DX("Executor(" << this << ")::Clear(): invalid executor");
96  mCurrentTime=0;
97  mCurrentStep=0;
98  mEValid=false;
99 }
100 
101 // Reset()
102 void Executor::Reset(void) {
105  ClockSet::Iterator cit;
106  for(cit=GlobalAttribute().mClocks.Begin(); cit!=GlobalAttribute().mClocks.End(); cit++)
108  mCurrentTime=0;
109  mCurrentStep=0;
110  mEValid=false;
111 }
112 
113 
114 // DoRead(rTr)
115 void Executor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
116  FD_DX("Executor(" << this << ")::DoRead(rTr)");
117  TimedGenerator::DoRead(rTr,rLabel,pContext);
118  Compile();
119 }
120 
121 // DoWrite(rTr)
122 void Executor::DoWrite(TokenWriter& rTw,const std::string& rLabel, const Type* pContext) const {
123  FD_DX("Executor(" << this << ")::DoWrite(rTw)");
124  TimedGenerator::DoWrite(rTw,rLabel,pContext);
125 }
126 
127 // DoAssign
128 void Executor::DoAssign(const Executor& rSrc) {
129  // call base
131  // fox my data
132  Compile();
133 }
134 
135 
136 
137 // ComputeEnabled() fake const
138 void Executor::ComputeEnabled(void) const {
139  Executor* fakeconst = const_cast<Executor*>(this);
140  fakeconst->ComputeEnabledNonConst();
141 }
142 
143 // ComputeEnabledNoneConst()
145  FD_DX("Executor(" << this << ")::ComputeEnabled()");
146  // time is up: clear all
147  if(mCurrentTime>=Time::Max()) {
148  mAEvents.Clear();
149  mATrans.Clear();
150  mETime.SetEmpty();
152  mEEvents.Clear();
153  mDEvents=Alphabet();
154  mEGuardInterval.clear();
155  mEValid=true;
156  FD_DX("Executor(" << this << ")::ComputeEnabled(): time is up");
157  return;
158  }
159  // set active events/transitions
162  // hypothesis: all time can pass [0,inf)
165  // hypothesis: no events can occur
166  mEEvents.Clear();
167  mDEvents=Alphabet();
168  mEGuardInterval.clear();
169  // inspect invariant to restrict enabled time
170  std::map<Idx,TimeInterval> clockintervalmap=mStateClockIntervalMap[mCurrentTimedState.State];
171  std::map<Idx,TimeInterval>::const_iterator cit;
172  for(cit=clockintervalmap.begin(); cit!=clockintervalmap.end(); cit++) {
173  Idx clock = cit-> first;
174  Time::Type clockvalue = mCurrentTimedState.ClockValue[clock];
175  TimeInterval interval = cit->second;
176  // if a clock violates an invariant constraint return deadlock
177  if(! interval.In( clockvalue ) ) {
178  FD_DX("Executor(" << this << ")::ComputeEnabled(): clock " << CStr(cit->first)
179  << " at " << clockvalue << " violates invariant condition " << interval.Str() );
180  mETime.SetEmpty();
181  mEValid=true;
182  return;
183  }
184  // left shift interval by clock value to obtain an interval relative to current time
185  interval.PositiveLeftShift(clockvalue);
186  // intersect with enabled time
187  mETime.Intersect(interval);
188  }
189  FD_DX("Executor(" << this << ")::ComputeEnabled(): invariant is satisfied for "
190  << mETime.Str() );
191  // no events for all time that can pass to begin with ...
192  mEEvents.Clear();
193  mEEvents.Name("EnabledEvents");
194  mDEvents=Alphabet();
195  mDEvents.Name("DisabledEvents");
197  // iterate over all transitions and check guards
198  TransSet::Iterator tit;
199  for(tit=mATrans.Begin(); tit!= mATrans.End(); tit++) {
200  // hypothesis: transition is enabled for all time
201  bool enabled=true;
202  TimeInterval enabledtime;
203  enabledtime.SetPositive();
204  // check all clocks
205  std::map<Idx,TimeInterval> clockintervalmap=mTransClockIntervalMap[*tit];
206  std::map<Idx,TimeInterval>::const_iterator cit;
207  for(cit=clockintervalmap.begin(); cit!=clockintervalmap.end(); cit++) {
208  Idx clock = cit->first;
209  Time::Type clockvalue = mCurrentTimedState.ClockValue[clock];
210  TimeInterval interval = cit->second;
211  // reject transition if a clock violates a guard constraint
212  if(! interval.In(clockvalue) ) enabled=false;
213  // left shift interval by clock value to obtain an interval relative to current time
214  interval.PositiveLeftShift(clockvalue);
215  // intersect with enabled interval
216  enabledtime.Intersect(interval);
217  }
218  // record guard interval
219  mEGuardInterval[tit->Ev]=enabledtime;
220  // intersect with invariant
221  enabledtime.Intersect(mETime);
222  // intersect with time hypothesis
223  if(enabled) {
224  // easy: intersect enabledtime with mEInterval
225  FD_DX("Executor(" << this << ")::ComputeEnabled(): event " << EStr(tit->Ev)
226  << " is enabled for " << enabledtime.Str());
227  mEEvents.Insert(tit->Ev);
228  mDEvents.Erase(tit->Ev);
229  mEInterval.Intersect(enabledtime);
230  } else {
231  // first compute disabledtime, then intersect
232  TimeInterval disabledtime;
233  disabledtime.SetPositive();
234  if(!enabledtime.Empty()) {
235  disabledtime.UB(enabledtime.LB());
236  disabledtime.UBincl(!enabledtime.LBincl());
237  }
238  FD_DX("Executor(" << this << ")::ComputeEnabled(): event " << EStr(tit->Ev)
239  << " is disabled for " << disabledtime.Str() << " and enabled for " << enabledtime.Str());
240  mEInterval.Intersect(disabledtime);
241  }
242  } // loop transitions
243  FD_DX("Executor(" << this << ")::ComputeEnabled(): e/d status constant on "
244  << mEInterval.Str() );
245  mEValid=true;
246 }
247 
248 // EnabledTime(void)
250  if(!mEValid) ComputeEnabled();
251  return mETime;
252 }
253 
254 // EnabledEvents(void)
255 const EventSet& Executor::EnabledEvents(void) const {
256  if(!mEValid) ComputeEnabled();
257  return mEEvents;
258 }
259 
260 // DisabledEvents(void)
261 const EventSet& Executor::DisabledEvents(void) const {
262  if(!mEValid) ComputeEnabled();
263  return mDEvents;
264 }
265 
266 // EnabledInterval(void)
268  if(!mEValid) ComputeEnabled();
269  return mEInterval;
270 }
271 
272 // ActiveEventSet(void)
273 const EventSet& Executor::ActiveEventSet(void) const {
274  if(!mEValid) ComputeEnabled();
275  return mAEvents;
276 }
277 
278 // ActiveTransSet(void)
279 const TransSet& Executor::ActiveTransSet(void) const {
280  if(!mEValid) ComputeEnabled();
281  return mATrans;
282 }
283 
284 // EnabledEventInterval(event)
286  if(!mEValid) ComputeEnabled();
287  TimeInterval res;
288  std::map<Idx,TimeInterval>::const_iterator eit;
289  eit=mEGuardInterval.find(event);
290  if(eit!= mEGuardInterval.end()) {
291  res = eit->second;
292  res.Intersect(mETime);
293  return res;
294  }
295  if(Alphabet().Exists(event)) {
296  res.SetEmpty();
297  return res;
298  }
299  res.SetPositive();
300  return res;
301 }
302 
303 // EnabledGuardInterval(event)
305  if(!mEValid) ComputeEnabled();
306  std::map<Idx,TimeInterval>::const_iterator eit;
307  eit=mEGuardInterval.find(event);
308  if(eit!= mEGuardInterval.end()) return eit->second;
309  TimeInterval res;
310  res.SetEmpty();
311  if(Alphabet().Exists(event)) return res;
312  res.SetPositive();
313  return res;
314 }
315 
316 // ExecuteTime(time)
318  if(mCurrentTime>=Time::Max()) return false;
319  if(!mEValid) ComputeEnabled();
320  if(!mETime.In(time) && !((time==Time::Max()) && mETime.UBinf()) ) {
321  FD_DX("Executor(" << this << ")::ExecuteTime: execution of " << time
322  << " conflicts with enabled status " );
323  return false;
324  }
325  FD_DX("Executor(" << this << ")::ExecuteTime(" << time << ")");
326  // progress current time
327  mCurrentTime += time;
328  // progres clocks
329  ClockSet::Iterator cit;
330  for(cit=ClocksBegin(); cit!=ClocksEnd(); cit++)
332  // fix infinity
333  if(time==Time::Max()) {
335  for(cit=ClocksBegin(); cit!=ClocksEnd(); cit++)
337  mEValid=false;
338  }
339  // progress enabled interval or invalidate enabled status
340  if(mEInterval.In(time) && mEValid) {
343  std::map<Idx,TimeInterval>::iterator iit;
344  for(iit=mEGuardInterval.begin();iit != mEGuardInterval.end(); iit++) {
345  iit->second.PositiveLeftShift(time);
346  }
347  } else {
348  mEValid=false;
349  }
350  return true;
351 }
352 
353 // ExecuteEvent(event)
355  if(mCurrentTime>=Time::Max()) return false;
356  if(!mEValid) ComputeEnabled();
357  if(!mEEvents.Exists(event)) {
358  FD_DX("Executor(" << this << ")::ExecuteEvent: execution of event " << EStr(event)
359  << " conflicts with enabled status " );
360  return false;
361  }
362  FD_DX("Executor(" << this << ")::ExecuteEvent(" << EStr(event) << ")");
363  // pick transition
365  // TODO: invalid iterator error
366  // execute resets
367  ClockSet resets=Resets(*tit);
368  ClockSet::Iterator cit;
369  for(cit = resets.Begin(); cit!=resets.End(); cit++)
371  // progress state
372  mCurrentTimedState.State=tit->X2;
373  // progress current time
374  mCurrentStep += 1;
375  // invalidate
376  mEValid=false;
377  return true;
378 }
379 
380 
381 // CurrentTimedState(tstate)
383  // test consitency
384  if(!ExistsState(tstate.State)) return false;
385  if(tstate.ClockValue.size()!=ClocksSize()) return false;
386  std::map<Idx,Time::Type>::const_iterator cvit;
387  for(cvit=tstate.ClockValue.begin(); cvit!=tstate.ClockValue.end(); cvit++)
388  if(!ExistsClock(cvit->first)) return false;
389  // set state
390  mCurrentTimedState=tstate;
391  mEValid=false;
392  return true;
393 }
394 
395 // CurrentTimedState()
397  return mCurrentTimedState;
398 }
399 
400 // CurrentState(idx)
402  if(!ExistsState(index)) return false;
404  mEValid=false;
405  return true;
406 }
407 
408 // CurrentState()
410  return mCurrentTimedState.State;
411 }
412 
413 // CurrentClockValue(idx,time)
415  if(!ExistsClock(index)) return false;
416  mCurrentTimedState.ClockValue[index]=time;
417  mEValid=false;
418  return true;
419 }
420 
421 // CurrentClockValue(idx)
423  std::map<Idx,Time::Type>::const_iterator cvit;
424  cvit=mCurrentTimedState.ClockValue.find(index);
425  if(cvit==mCurrentTimedState.ClockValue.end()) {}; // todo: error
426  return cvit->second;
427 }
428 
429 // CurrentTime(time)
431  mCurrentTime=time;
432  mEValid=false;
433 }
434 
435 // CurrentTime()
437  return mCurrentTime;
438 }
439 
440 // CurrentStep(time)
441 void Executor::CurrentStep(int step) {
442  mCurrentStep=step;
443  mEValid=false;
444 }
445 
446 // CurrentStep()
447 int Executor::CurrentStep(void) const {
448  return mCurrentStep;
449 }
450 
451 // IsDeadlocked()
452 bool Executor::IsDeadlocked(void) const {
453  if(!mEValid) ComputeEnabled();
454  if(!mEEvents.Empty()) return false;
455  if(!(mETime.UB()<=0)) return false;
456  return true;
457 }
458 
459 // TSStr(tstate)
460 std::string Executor::TSStr(const TimedState& tstate) const {
461  std::stringstream res;
462  res << "(state " << SStr(tstate.State);
463  if(Generator().ExistsMarkedState(tstate.State)) res << " [marked]";
464  res << ") (clocks";
465  ClockSet::Iterator cit;
466  for(cit=ClocksBegin();cit!=ClocksEnd();cit++){
467  res << " " << CStr(*cit) << "=";
468  std::map<Idx,Time::Type>::const_iterator cvit=tstate.ClockValue.find(*cit);
469  if(cvit!=tstate.ClockValue.end())
470  res << cvit->second;
471  else
472  res << "undef";
473  }
474  res << ")";
475  return res.str();
476 }
477 
478 // CurrentTimedStateStr()
479 std::string Executor::CurrentTimedStateStr(void) const {
480  return TSStr(mCurrentTimedState);
481 }
482 
483 // TEStr(tevent)
484 std::string Executor::TEStr(const TimedEvent& tevent) const {
485  std::stringstream res;
486  res << "(" << EStr(tevent.mEvent) << " at " << tevent.mTime << ")";
487  return res.str();
488 }
489 
490 // EStr(event)
491 std::string Executor::EStr(Idx event) const {
492  return TimedGenerator::EStr(event);
493 }
494 
495 // CStr(clock)
496 std::string Executor::CStr(Idx clock) const {
497  return TimedGenerator::CStr(clock);
498 }
499 
500 // SStr(clock)
501 std::string Executor::SStr(Idx state) const {
502  return TimedGenerator::SStr(state);
503 }
504 
505 
506 } // namespace faudes
507 
508 
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition: cfl_types.h:951
const TimeInterval & EnabledTime() const
std::string EStr(Idx idx) const
EventSet mDEvents
Definition: sp_executor.h:508
const TimedGenerator & Generator(void) const
Definition: sp_executor.cpp:41
bool ExecuteTime(Time::Type time)
const EventSet & EnabledEvents() const
void Compile(void)
Definition: sp_executor.cpp:53
std::map< Idx, TimeInterval > mEGuardInterval
Definition: sp_executor.h:505
Time::Type CurrentTime(void) const
Idx CurrentState(void) const
std::string SStr(Idx idx) const
const EventSet & ActiveEventSet(void) const
Time::Type mCurrentTime
Definition: sp_executor.h:481
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
EventSet mAEvents
Definition: sp_executor.h:511
std::map< Transition, std::map< Idx, TimeInterval > > mTransClockIntervalMap
Definition: sp_executor.h:520
bool ExecuteEvent(Idx event)
void Clear(void)
Definition: sp_executor.cpp:91
void ComputeEnabled(void) const
std::map< Idx, std::map< Idx, TimeInterval > > mStateClockIntervalMap
Definition: sp_executor.h:523
TimeInterval EnabledEventTime(Idx event) const
std::string TSStr(const TimedState &tstate) const
std::string CStr(Idx idx) const
const TransSet & ActiveTransSet(void) const
const TimeInterval & EnabledInterval() const
const EventSet & DisabledEvents() const
bool CurrentClockValue(Idx clock, Time::Type time)
TimeInterval mETime
Definition: sp_executor.h:496
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
std::string TEStr(const TimedEvent &tevent) const
TimeInterval mEInterval
Definition: sp_executor.h:502
const TimedState & CurrentTimedState(void) const
bool IsDeadlocked() const
TimedState mCurrentTimedState
Definition: sp_executor.h:478
TimeInterval EnabledGuardTime(Idx event) const
void DoAssign(const Executor &rSrc)
int CurrentStep(void) const
std::string CurrentTimedStateStr(void) const
EventSet mEEvents
Definition: sp_executor.h:499
void ComputeEnabledNonConst(void)
TransSet mATrans
Definition: sp_executor.h:514
bool Exists(const Idx &rIndex) const
bool Insert(const Idx &rIndex)
virtual bool Erase(const Idx &rIndex)
Iterator Begin(void) const
Iterator End(void) const
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Definition: cfl_transset.h:273
const GlobalAttr & GlobalAttribute(void) const
virtual void Clear(void)
const TaEventSet< EventAttr > & Alphabet(void) const
void DoAssign(const TaGenerator &rGen)
virtual TcGenerator & Assign(const Type &rSource)
TimeInterval Interval(Idx clockindex) const
ClockSet ActiveClocks(void) const
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 Max(void)
Time::Type mTime
Definition: sp_executor.h:56
Idx ClocksSize(void) const
const TimeConstraint & Invariant(Idx idx) const
bool ExistsClock(Idx index) const
ClockSet::Iterator ClocksEnd(void) const
ClockSet::Iterator ClocksBegin(void) const
void Resets(const Transition &rTrans, const ClockSet &rResets)
void Guard(const Transition &rTrans, const TimeConstraint &rGuard)
std::string CStr(Idx index) const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Definition: cfl_types.cpp:262
StateSet::Iterator StatesBegin(void) const
StateSet::Iterator InitStatesBegin(void) const
EventSet ActiveEventSet(Idx x1) const
TransSet::Iterator TransRelBegin(void) const
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
TransSet ActiveTransSet(Idx x1) const
bool ExistsState(Idx index) const
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
std::string TStr(const Transition &rTrans) const
StateSet::Iterator StatesEnd(void) const
TransSet::Iterator TransRelEnd(void) const
bool IsDeterministic(void) const
std::string EStr(Idx index) const
Idx InitState(void) const
std::string SStr(Idx index) const
bool ExistsMarkedState(Idx index) const
bool Empty(void) const
Definition: cfl_baseset.h:1841
virtual void Clear(void)
Definition: cfl_baseset.h:1919
Iterator End(void) const
Definition: cfl_baseset.h:1913
Iterator Begin(void) const
Definition: cfl_baseset.h:1908
const std::string & Name(void) const
Definition: cfl_baseset.h:1772
uint32_t Idx
TtGenerator< AttributeTimedGlobal, AttributeTimedState, AttributeCFlags, AttributeTimedTrans > TimedGenerator
#define FD_DX(message)
Definition: sp_executor.h:27
std::map< Idx, Time::Type > ClockValue
Definition: sp_executor.h:103

libFAUDES 2.33b --- 2025.05.07 --- c++ api documentaion by doxygen