tp_tgenerator.h
Go to the documentation of this file.
1 /** @file tp_tgenerator.h Timed generator class TtGenerator */
2 
3 /*
4  Timeplugin for FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2007 Thomas Moor
7  Exclusive copyright is granted to Klaus Schmidt
8 
9 */
10 
11 
12 #ifndef FAUDES_TP_TGENERATOR_H
13 #define FAUDES_TP_TGENERATOR_H
14 
15 #include "corefaudes.h"
16 #include "tp_attributes.h"
17 
18 namespace faudes {
19 
20 
21 
22 /**
23  * Generator with timing extensions.
24  *
25  * \section SecTimedAlur Alur's Timed Automata
26  *
27  * The TtGenerator implements a timed automaton as
28  * introduced by Alur et al. Thus, a TtGenerator is equipped with a number of clock
29  * variables to express conditions on timing, so called time constraints. Each state has a
30  * TimeConstraint called the invariant, which must be satisfied while the generator
31  * resides in the respective state. Similarly, each transition has a timeconstraint called the
32  * guard, which must be satisfied at the moment in which the transition is executed. Transitions
33  * may also reset clock variables.
34  *
35  *
36  * \section SecTimedAlusImplement Implementation
37  *
38  * The TimedGenerator is derived from the System and requires
39  * adequate attribute parameters that implement the timing constraints. Suitable
40  * attribute classes are provided by AttributeTimedState, AttributeTimedTrans and AttributeTimedGlobal
41  * which may be used either directly or as base classes for further derivatives.
42  * For the event attribute, the TimedGenerator assumes the AttributeCFlags interface. A convenience
43  * definition faudes::TimedGenerator is used for a minimal version with the above mentioned attribute parameters.
44  *
45  *
46  * \section TimedGeneratorFileFormat File IO
47  *
48  * The TtGenerator calsses use the TaGenerator file IO, i.e. the file format is the
49  * same up to timing related requirements from the attribute parameters. The below
50  * example is from the basic version TimedGenerator and represents a simplemachine with a
51  * busy cycle of at least 5 and at most 10 time units.
52  * @code
53  * <Generator>
54  * "tc simple machine"
55  *
56  * <Alphabet>
57  * "alpha" +C+ "beta" "mue" "lambda" +C+
58  * </Alphabet>
59  *
60  * <States>
61  * "idle"
62  * "busy" <Invariant> "cBusy" "LT" 10 </Invariant>
63  * "down"
64  * </States>
65  *
66  * <TransRel>
67  *
68  * "idle" "alpha" "busy"
69  * <Timing>
70  * <Resets>
71  * "cBusy"
72  * </Resets>
73  * </Timing>
74  *
75  * "busy" "beta" "idle"
76  * <Timing>
77  * <Guard>
78  * "cBusy" "GT" 5
79  * </Guard>
80  * </Timing>
81  *
82  * "busy" "mue" "down"
83  *
84  * "down" "lambda" "idle"
85  *
86  * </TransRel>
87  *
88  * <InitStates> "idle" </InitStates>
89  * <MarkedStates> "idle" </MarkedStates>
90  *
91  * <Clocks> "cBusy" </Clocks>
92  *
93  * </Generator>
94  * @endcode
95  *
96  *
97  * @ingroup TimedPlugin
98  */
99 
100 template <class GlobalAttr, class StateAttr, class EventAttr, class TransAttr>
101 class TtGenerator : public TcGenerator<GlobalAttr, StateAttr, EventAttr, TransAttr> {
102  public:
103  /**
104  * Constructor
105  */
106  TtGenerator(void);
107 
108  /**
109  * Copy constructor
110  *
111  * @param rOtherGen
112  */
113  TtGenerator(const TtGenerator& rOtherGen);
114 
115  /**
116  * Copy constructor (no attributes)
117  *
118  * @param rOtherGen
119  */
120  TtGenerator(const vGenerator& rOtherGen);
121 
122  /**
123  * Assignment operator (uses copy)
124  * Note: you must reimplement this operator in derived
125  * classes in order to handle internal pointers correctly
126  *
127  * @param rOtherGen
128  * Other generator
129  */
130  virtual TtGenerator& operator= (const TtGenerator& rOtherGen) {this->Assign(rOtherGen); return *this;};
131 
132  /**
133  * Assignment operator (uses copy)
134  *
135  * @param rOtherGen
136  * Other generator
137  */
138  virtual TtGenerator& operator= (const vGenerator& rOtherGen) {this->Assign(rOtherGen); return *this;};
139 
140  /**
141  * Construct from file
142  *
143  * @param rFileName
144  * Name of file
145  *
146  * @exception Exception
147  * - file format errors (id 1, 50, 51, 52)
148  */
149  TtGenerator(const std::string& rFileName);
150 
151  /**
152  * Construct on heap.
153  * Constructs a TtGenerator on heap with the same attribute types and the same event- and clock-symboltable.
154  *
155  * @return
156  * new Generator
157  */
158  TtGenerator* New(void) const;
159 
160  /**
161  * Construct copy on heap.
162  * Constructs a TtGenerator on heap with the same attribute types and the same event- and clock-symboltable.
163  *
164  * @return
165  * new Generator
166  */
167  TtGenerator* Copy(void) const;
168 
169  /**
170  * Type test.
171  * Uses C++ dynamic cast to test whether the specified object
172  * casts to a TimedGenerator.
173  *
174  * @return
175  * TtGenerator reference if dynamic cast succeeds, else NULL
176  */
177  virtual const Type* Cast(const Type* pOther) const {
178  return dynamic_cast< const TtGenerator* > (pOther); };
179 
180 
181  /**
182  * Construct on stack.
183  * Constructs a TtGenerator on stack with the same attribute types and the same event- and clock-symboltable.
184  *
185  * @return
186  * new Generator
187  */
188  TtGenerator NewTGen(void) const;
189 
190 
191  /**
192  * Get Pointer to mpClockSymbolTable.
193  *
194  * @return Pointer mpClockSymbolTable
195  */
196  SymbolTable* ClockSymbolTablep(void) const;
197 
198  /**
199  * Set ClockSymbolTable.
200  *
201  * @param pClockSymTab
202  * Pointer SymbolTable
203  */
204  void ClockSymbolTablep(SymbolTable* pClockSymTab);
205 
206 
207  /**
208  * Return a NameSet with generator's ClockSymbolTable
209  *
210  * @return
211  * New empty ClockSet on stack
212  */
213  ClockSet NewClockSet(void) const;
214 
215  /**
216  * Construct a clock on heap.
217  *
218  * @return
219  * Pointer to new empty ClockSet on heap
220  */
221  ClockSet* NewClockSetp(void) const;
222 
223  /**
224  * Number of clocks in mClocks
225  *
226  * @return Number of clocks in mClocks
227  */
228  Idx ClocksSize(void) const;
229 
230  /**
231  * Get clockset as const reference
232  *
233  * @return mClocks
234  */
235  const ClockSet& Clocks(void) const;
236 
237 
238  /**
239  * Get clockset as pointer
240  *
241  * @return mClocks
242  */
243  ClockSet* Clocksp(void);
244 
245  /**
246  * Overwrites mClocks with newclocks without consistency check
247  *
248  * @param newclocks
249  * New clocks that are written to mClocks
250  */
251  void InjectClocks(const ClockSet& newclocks);
252 
253  /**
254  * Looks up clock name for given index
255  *
256  * @param index
257  * Clock index
258  *
259  * @return Clock name
260  */
261  std::string ClockName(Idx index) const;
262 
263  /**
264  * Looks up clock index for given name
265  *
266  * @param rName
267  * Clock name
268  *
269  * @return Clock index or 0 for nonexistent
270  */
271  Idx ClockIndex(const std::string& rName) const;
272 
273  /**
274  * Add an existing clock to mClcoks by index
275  *
276  * @param index
277  * Clock index
278  * @return
279  * True if clock was new to clockset
280  */
281  bool InsClock(Idx index);
282 
283  /**
284  * Add named clock to generator. An entry in the mpClockSymbolTable will
285  * be made if clock is new.
286  *
287  * @param rName
288  * Name of the clock to add
289  *
290  * @return
291  * New unique index
292  */
293  Idx InsClock(const std::string& rName);
294 
295  /**
296  * Add new named clocks to generator.
297  *
298  * @param rClockSet
299  * ClockSet
300  */
301  void InsClocks(const ClockSet& rClockSet);
302 
303  /**
304  * Delete clock from generator by index. This also removes
305  * any constraints and resets that refer to that clock.
306  *
307  * @param index
308  * Index of clock
309  * @return
310  * True if clock did exist
311  *
312  */
313  bool DelClock(Idx index);
314 
315  /**
316  * Delete clock from generator by name. mpClockSymbolTable stays untouched.
317  * Also removes constraints and resets that refer to this clock
318  *
319  * @param rName
320  * Name of clock
321  * @return
322  * True if clock did exist
323  */
324  bool DelClock(const std::string& rName);
325 
326  /**
327  * Delete a set of clocks from generator.
328  *
329  * @param rClocks
330  * ClockSet containing clocks to remove
331  */
332  void DelClocks(const ClockSet& rClocks);
333 
334  /**
335  * Test existence of clock in mClocks
336  *
337  * @param index
338  * Clock index
339  *
340  * @return
341  * true / false
342  */
343  bool ExistsClock(Idx index) const;
344 
345  /**
346  * Test existence of clock in mClock
347  *
348  * @param rName
349  * Clock name
350  *
351  * @return
352  * True if clock exists
353  */
354  bool ExistsClock(const std::string& rName) const;
355 
356  /**
357  * Returns a niterator to clock index in mClock
358  *
359  * @param index
360  * Index to find
361  *
362  * @return
363  * ClockSet::Iterator to clock index
364  */
365  ClockSet::Iterator FindClock(Idx index) const;
366 
367  /**
368  * Returns an iterator to clock index in mClock
369  *
370  * @param rName
371  * Clock name of index to find
372  *
373  * @return
374  * ClockSet::Iterator to clock index
375  */
376  ClockSet::Iterator FindClock(const std::string& rName) const;
377 
378  /**
379  * Returns all clocks used by all TimeConstraints and Resets.
380  * Should be a subset of Clocks()
381  *
382  * @return
383  * ClockSet containing all clocks
384  */
385  ClockSet ActiveClocks(void) const;
386 
387  /**
388  * Returns all clocks not used by any TimeConstraints or Reset.
389  *
390  * @return
391  * ClockSet containing all unused clocks
392  */
393  ClockSet InactiveClocks(void) const;
394 
395  /**
396  * Update Clocks to include all active clocks
397  *
398  */
399  void InsActiveClocks(void);
400 
401  /**
402  * Update Clocks not to include any inactive clocks
403  *
404  */
405  void DelInactiveClocks(void);
406 
407  /**
408  * Iterator to Begin() of mClocks
409  *
410  * @return iterator to begin of mClocks
411  */
412  ClockSet::Iterator ClocksBegin(void) const;
413 
414  /**
415  * Iterator to End() of mClocks
416  *
417  * @return iterator to end of mClocks
418  */
419  ClockSet::Iterator ClocksEnd(void) const;
420 
421  /**
422  * Throw exception if timeconstraint refers to clocks not
423  * in clockset or symboltable mismatch
424  *
425  * @exception Exception
426  * - invalid cock (id 200)
427  */
428  void ConsistentTimeConstraint(const TimeConstraint& rTimeConstr) const;
429 
430  /**
431  * Throw exception if clocksset contains clocks not
432  * in generators clockset or symboltable mismatch
433  *
434  * @exception Exception
435  * - invalid cock (id 200)
436  */
437  void ConsistentClocks(const ClockSet& rClocks) const;
438 
439 
440  /**
441  * Get invariant of state by index
442  *
443  * @param idx
444  * State index
445  * @return
446  * Const ref to invariant
447  */
448  const TimeConstraint& Invariant(Idx idx) const;
449 
450  /**
451  * Get invariant of state by index
452  *
453  * @param idx
454  * State index
455  * @return
456  * Pointer to invariant
457  */
459 
460  /**
461  * Get invariant of state by name
462  *
463  * @param name
464  * State name
465  * @return
466  * Const ref to invariant
467  */
468  const TimeConstraint& Invariant(const std::string& name) const;
469 
470 
471  /**
472  * Get invariant of state by name
473  *
474  * @param name
475  * State index
476  * @return
477  * Pointer to invariant
478  */
479  TimeConstraint* Invariantp(const std::string& name);
480 
481  /**
482  * Set invariant of state by index
483  *
484  * @param index
485  * State index
486  * @param rConstraints
487  * New constraints
488  */
489  void Invariant(Idx index, const TimeConstraint& rConstraints);
490 
491 
492  /**
493  * Set invariant of state by name
494  *
495  * @param name
496  * State name
497  * @param rConstraints
498  * New constraints
499  */
500  void Invariant(const std::string& name, const TimeConstraint& rConstraints);
501 
502 
503  /**
504  * Ins invariant of state by name
505  *
506  * @param name
507  * State name
508  * @param rConstraints
509  * New constraints
510  */
511  void InsInvariant(const std::string& name, const TimeConstraint& rConstraints);
512 
513 
514  /**
515  * Ins invariant of state by name
516  *
517  * @param index
518  * State index
519  * @param rConstraints
520  * New constraints
521  */
522  void InsInvariant(Idx index, const TimeConstraint& rConstraints);
523 
524 
525  /**
526  * Clear invariant of state by index
527  *
528  * @param idx
529  * State index
530  */
531  void ClrInvariant(Idx idx);
532 
533  /**
534  * Clear invariant of state by name
535  *
536  * @param name
537  * State name
538  */
539  void ClrInvariant(const std::string& name);
540 
541  /**
542  * Clear all invariants
543  *
544  */
545  void ClearInvariants(void);
546 
547  /**
548  * Add a transition to generator by indices. States and event
549  * must already exist!
550  *
551  * Define FAUDES_CHECKED for consistency checks.
552  *
553  * @param x1
554  * Predecessor state index
555  * @param ev
556  * Event index
557  * @param x2
558  * Successor state index
559  *
560  * @return
561  * True, if the transition was new the generator
562  *
563  * @exception Exception
564  * - state or event not in generator (id 95)
565  */
566  bool SetTransition(Idx x1, Idx ev, Idx x2);
567 
568  /**
569  * Add a transition to generator by names. Statename and eventname
570  * must already exist!
571  *
572  * @param rX1
573  * Predecessor state name
574  * @param rEv
575  * Event name
576  * @param rX2
577  * Successor state name
578  *
579  * @return
580  * True, if the transition was new the generator
581  *
582  * @exception Exception
583  * - state or event not in generator (id 95)
584  * - state name not known (id 90)
585  * - event name not known (id 66)
586  */
587  bool SetTransition(const std::string& rX1, const std::string& rEv,
588  const std::string& rX2);
589 
590  /**
591  * Add a transition with attribute to generator. States and event
592  * must already exist!
593  *
594  * Define FAUDES_CHECKED for consistency checks.
595  *
596  * @param rTransition
597  * transition
598  * @param rAttr
599  * attribute
600  *
601  * @return
602  * True, if the transition was new the generator
603  *
604  */
605  bool SetTransition(const Transition& rTransition, const TransAttr& rAttr);
606 
607  /**
608  * Inserts new TimedTransition constructed from parameters.
609  * Performs consistency checks for x1, x2, ev and all clocks in rguard and rResetClocks.
610  *
611  * @param rTrans
612  * new transition
613  * @param rGuard
614  * Guard of new TimedTransition.
615  * @param rResets
616  * Reset clocks of new TimedTransition.
617  * @return
618  * True, if the transition was new the generator
619  */
620  bool SetTransition(const Transition& rTrans,
621  const TimeConstraint& rGuard = TimeConstraint(), const ClockSet& rResets = ClockSet());
622 
623  /**
624  * Inserts new TimedTransition constructed from parameters.
625  * Performs consistency checks for x1, x2, ev and all clocks in rguard and rResetClocks.
626  *
627  * @param x1
628  * Start state of new TimedTransition.
629  * @param ev
630  * Event of new TimedTransition.
631  * @param x2
632  * Goal state of new TimedTransition.
633  * @param rguard
634  * Guard of new TimedTransition.
635  * @param rResetClocks
636  * Reset clocks of new TimedTransition.
637  */
638  bool SetTransition(Idx x1, Idx ev, Idx x2,
639  const TimeConstraint& rguard, const ClockSet& rResetClocks = ClockSet());
640 
641  /**
642  * Inserts new TimedTransition constructed from parameters.
643  * Performs consistency checks for x1, x2, ev and all clocks in rguard and rResetClocks.
644  *
645  * @param rX1
646  * Start state of new TimedTransition.
647  * @param rEv
648  * Event of new TimedTransition.
649  * @param rX2
650  * Goal state of new TimedTransition.
651  * @param rGuard
652  * Guard of new TimedTransition.
653  * @param rResets
654  * Reset clocks of new TimedTransition.
655  *
656  * @return
657  * True, if the transition was new the generator
658  */
659  bool SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2,
660  const TimeConstraint& rGuard = TimeConstraint(), const ClockSet& rResets = ClockSet());
661 
662 
663  /**
664  * Sets Guard of a transition
665  *
666  * @param rTrans
667  * transition to manupilate
668  * @param rGuard
669  * new Guard of transition.
670  */
671  void Guard(const Transition& rTrans, const TimeConstraint& rGuard);
672 
673  /**
674  * adds constraints to Guard of a transition
675  *
676  * @param rTrans
677  * transition to manupilate
678  * @param rConstraints
679  * new constraints for Guard
680  */
681  void InsGuard(const Transition& rTrans, const TimeConstraint& rConstraints);
682 
683  /**
684  * Gets Guard refernce of a transition
685  *
686  * @param rTrans
687  * transition to inspect
688  *
689  * @return
690  * Guard of transition.
691  */
692  const TimeConstraint& Guard(const Transition& rTrans) const;
693 
694  /**
695  * Gets Guard pointer of ransition
696  *
697  * @param rTrans
698  * transition to inspect
699  *
700  * @return
701  * Guard of transition.
702  */
703  TimeConstraint* Guardp(const Transition& rTrans);
704 
705 
706  /**
707  * Clears Guard of a transition
708  *
709  * @param rTrans
710  * transition to manupilate
711  */
712  void ClrGuard(const Transition& rTrans);
713 
714  /**
715  * Sets Resets of a transition
716  *
717  * @param rTrans
718  * transition to manupilate
719  * @param rResets
720  * new Resets of transition.
721  */
722  void Resets(const Transition& rTrans, const ClockSet& rResets);
723 
724  /**
725  * adds Resets of a transition
726  *
727  * @param rTrans
728  * transition to manupilate
729  * @param rMoreResets
730  * new Resets of transition.
731  */
732  void InsResets(const Transition& rTrans, const ClockSet& rMoreResets);
733 
734  /**
735  * Gets Resets refernce of a transition
736  *
737  * @param rTrans
738  * transition to inspect
739  *
740  * @return
741  * Resets of transition.
742  */
743  const ClockSet& Resets(const Transition& rTrans) const;
744 
745  /**
746  * Gets Resets pointer of ransition
747  *
748  * @param rTrans
749  * transition to inspect
750  *
751  * @return
752  * Resets of transition.
753  */
754  ClockSet* Resetsp(const Transition& rTrans);
755 
756  /**
757  * Clears Resets of a transition
758  *
759  * @param rTrans
760  * transition to manupilate
761  */
762  void ClrResets(const Transition& rTrans);
763 
764  /**
765  * Return pretty printable clock name for index.
766  * Primary meant for debugging messages
767  *
768  * @param index
769  * Event index
770  *
771  * @return
772  * std::string
773  */
774  std::string CStr(Idx index) const;
775 
776  /**
777  * Check if generator is valid
778  *
779  * @return
780  * Success
781  */
782  virtual bool Valid(void);
783 
784 
785  /**
786  * Updates internal attributes. As a demo, we set
787  * state flag 0x20000000 for blocking states.
788  * Reimplement to your needs.
789  *
790  * @return true if value changed
791  */
792  virtual bool UpdateAttributes(void);
793 
794 
795 
796 }; // end class TtGeneraator
797 
798 
799 /** Convenience typedef for std TimedGenerator */
800 typedef TtGenerator<AttributeTimedGlobal, AttributeTimedState, AttributeCFlags,AttributeTimedTrans>
802 
803 /** Compatibility: pre 2.20b used tGenerator as C++ class name*/
804 #ifdef FAUDES_COMPATIBILITY
807 #endif
808 
809 
810 
811 // convenient scope macors
812 #define THIS TtGenerator<GlobalAttr, StateAttr, EventAttr, TransAttr>
813 #define BASE TcGenerator<GlobalAttr, StateAttr, EventAttr, TransAttr>
814 #define TEMP template <class GlobalAttr, class StateAttr, class EventAttr, class TransAttr>
815 
816 
817 // TtGenerator(void)
818 TEMP THIS::TtGenerator(void) : BASE() {
819  // set basic members (cosmetic)
820  BASE::pGlobalAttribute->mClocks.Name("Clocks");
821  BASE::pGlobalAttribute->mpClockSymbolTable=ClockSet::StaticSymbolTablep();
822  FD_DG("TimedGenerator(" << this << ")::TimedGenerator() with csymtab "
823  << (BASE::pGlobalAttribute->mpClockSymbolTable ));
824 }
825 
826 // TtGenerator(rOtherGen)
827 TEMP THIS::TtGenerator(const TtGenerator& rOtherGen) : BASE(rOtherGen) {
828  FD_DG("TimedGenerator(" << this << ")::TimedGenerator(rOtherGen) with csymtab"
829  << (BASE::pGlobalAttribute->mpClockSymbolTable) );
830 }
831 
832 // TtGenerator(rOtherGen)
833 TEMP THIS::TtGenerator(const vGenerator& rOtherGen) : BASE(rOtherGen) {
834  // set basic members (cosmetic)
835  BASE::pGlobalAttribute->mClocks.Name("Clocks");
836  BASE::pGlobalAttribute->mpClockSymbolTable=ClockSet::StaticSymbolTablep();
837  FD_DG("TimedGenerator(" << this << ")::TimedGenerator(rOtherGen) with csymtab"
838  << (BASE::pGlobalAttribute->mpClockSymbolTable) );
839 }
840 
841 // TtGenerator(rFilename)
842 TEMP THIS::TtGenerator(const std::string& rFileName) : BASE(rFileName) {
843  FD_DG("TimedGenerator(" << this << ")::TimedGenerator(" << rFileName << ") with csymtab"
844  << (BASE::pGlobalAttribute->mpClockSymbolTable) );
845 }
846 
847 
848 // ClockSymbolTablep()
849 TEMP SymbolTable* THIS::ClockSymbolTablep(void) const {
850  return BASE::pGlobalAttribute->mpClockSymbolTable;
851 }
852 
853 // ClockSymbolTablep(pSymTab)
854 TEMP void THIS::ClockSymbolTablep(SymbolTable* pSymTab) {
855  BASE::Clear(); // TODO: relax this
856  BASE::pGlobalAttribute->mpClockSymbolTable=pSymTab;
857 }
858 
859 
860 // New
861 TEMP THIS* THIS::New(void) const {
862  // allocate
863  THIS* res = new THIS;
864  // fix base data
865  res->EventSymbolTablep(BASE::mpEventSymbolTable);
866  res->mStateNamesEnabled=BASE::mStateNamesEnabled;
867  res->mReindexOnWrite=BASE::mReindexOnWrite;
868  // fix my data
869  res->ClockSymbolTablep(ClockSymbolTablep());
870  return res;
871 }
872 
873 // Copy
874 TEMP THIS* THIS::Copy(void) const {
875  // allocate
876  THIS* res = new THIS(*this);
877  // done
878  return res;
879 }
880 
881 // NewTGen
882 TEMP THIS THIS::NewTGen(void) const {
883  // call base (fixes by assignment constructor)
884  THIS res= BASE::NewCGen();
885  // fix my data
886  res.ClockSymbolTablep(ClockSymbolTablep());
887  return res;
888 }
889 
890 // ClockSize() const
891 TEMP Idx THIS::ClocksSize(void) const {
892  return BASE::pGlobalAttribute->mClocks.Size();
893 }
894 
895 // Clocks()
896 TEMP const ClockSet& THIS::Clocks(void) const {
897  return BASE::pGlobalAttribute->mClocks;
898 }
899 
900 // Clocksp()
901 TEMP ClockSet* THIS::Clocksp(void) {
902  return &BASE::pGlobalAttribute->mClocks;
903 }
904 
905 // InjectClocks(set)
906 TEMP void THIS::InjectClocks(const ClockSet& clockset) {
907  BASE::pGlobalAttribute->mClocks=clockset;
908  BASE::pGlobalAttribute->mClocks.Name("Clocks");
909 }
910 
911 // InsClock(index)
912 TEMP bool THIS::InsClock(Idx clockindex) {
913  return BASE::pGlobalAttribute->mClocks.Insert(clockindex);
914 }
915 
916 // InsClock(name)
917 TEMP Idx THIS::InsClock(const std::string& clockname) {
918  return BASE::pGlobalAttribute->mClocks.Insert(clockname);
919 }
920 
921 // InsClocks(set)
922 TEMP void THIS::InsClocks(const ClockSet& clockset) {
923  BASE::pGlobalAttribute->mClocks.InsertSet(clockset);
924 }
925 
926 
927 // DelClock(index)
928 TEMP bool THIS::DelClock(Idx clockindex) {
929  FD_DG("TimedGenerator(" << this << ")::DelClock(" << clockindex << ")");
930  TransSet::Iterator tit;
931  for(tit=BASE::TransRelBegin(); tit!=BASE::TransRelEnd(); tit++) {
932  if(!BASE::pTransRel->Attribute(*tit).IsDefault()) {
933  BASE::pTransRel->Attributep(*tit)->mGuard.EraseByClock(clockindex);
934  BASE::pTransRel->Attributep(*tit)->mResets.Erase(clockindex);
935  }
936  }
937  StateSet::Iterator it;
938  for(it=BASE::StatesBegin(); it!=BASE::StatesEnd(); it++) {
939  if(!BASE::pStates->Attribute(*it).IsDefault()) {
940  BASE::pStates->Attributep(*it)->mInvariant.EraseByClock(clockindex);
941  }
942  }
943  return BASE::pGlobalAttribute->mClocks.Erase(clockindex);
944 }
945 
946 // DelClock(name)
947 TEMP bool THIS::DelClock(const std::string& clockname) {
948  Idx index=BASE::pGlobalAttribute->mClocks.Index(clockname);
949  return DelClock(index);
950 }
951 
952 // DelClocks(set)
953 TEMP void THIS::DelClocks(const ClockSet& clockset) {
954  ClockSet::Iterator it, tmpit;
955  for(it=ClocksBegin(); it!=ClocksEnd(); ) {
956  tmpit=it;
957  it++;
958  DelClock(*tmpit);
959  }
960 }
961 
962 // ExistsClock(index)
963 TEMP bool THIS::ExistsClock(Idx clockindex) const {
964  return BASE::pGlobalAttribute->mClocks.Exists(clockindex);
965 }
966 
967 // ExistsClock(name)
968 TEMP bool THIS::ExistsClock(
969  const std::string& clockname) const {
970  return BASE::pGlobalAttribute->mClocks.Exists(clockname);
971 }
972 
973 // FindClock(index)
974 TEMP ClockSet::Iterator THIS::FindClock(Idx clockindex) const {
975  return BASE::pGlobalAttribute->mClocks.Find(clockindex);
976 }
977 
978 // FindClock(name)
979 TEMP ClockSet::Iterator THIS::FindClock(const std::string& clockname) const {
980  return BASE::pGlobalAttribute->mClocks.Find(clockname);
981 }
982 
983 // ClockName(index)
984 TEMP std::string THIS::ClockName(Idx clockindex) const {
985  return BASE::pGlobalAttribute->mClocks.SymbolicName(clockindex);
986 }
987 
988 // ClockIndex(name)
989 TEMP Idx THIS::ClockIndex(const std::string& clockname) const {
990  return BASE::pGlobalAttribute->mClocks.Index(clockname);
991 }
992 
993 // ActiveClocks() const
994 TEMP ClockSet THIS::ActiveClocks(void) const {
995  FD_DG("TimedGenerator(" << this << ")::ActiveClocks() const");
996  ClockSet res;
997  TransSet::Iterator tit;
998  for(tit=BASE::TransRelBegin(); tit!=BASE::TransRelEnd(); tit++) {
999  res.InsertSet(Guard(*tit).ActiveClocks());
1000  res.InsertSet(Resets(*tit));
1001  }
1002  StateSet::Iterator it;
1003  for(it=BASE::StatesBegin(); it!=BASE::StatesEnd(); it++) {
1004  res.InsertSet(Invariant(*it).ActiveClocks());
1005  }
1006  res.Name("AcitiveClocks");
1007  return res;
1008 }
1009 
1010 // InactiveClocks() const
1011 TEMP ClockSet THIS::InactiveClocks(void) const {
1012  FD_DG("TtaGenerator(" << this << ")::InactiveClocks() const");
1013  ClockSet res = BASE::mClocks - ActiveClocks();
1014  res.Name("InactiveClocks");
1015  return res;
1016 }
1017 
1018 // InsActiveClocks()
1019 TEMP void THIS::InsActiveClocks(void) {
1020  FD_DG("TimedGenerator(" << this << ")::InsActiveClocks()");
1021  ClockSet aclocks=ActiveClocks();
1022  InsClocks(aclocks);
1023 }
1024 
1025 // DelInactiveClocks()
1026 TEMP void THIS::DelInactiveClocks(void) {
1027  FD_DG("TimedGenerator(" << this << ")::InsActiveClocks()");
1028  ClockSet iaclocks=InactiveClocks();
1029  BASE::pGlobalAttribute->mClocks.Erase(iaclocks);
1030 }
1031 
1032 // iterator ClocksBegin() const
1033 TEMP ClockSet::Iterator THIS::ClocksBegin(void) const {
1034  return BASE::pGlobalAttribute->mClocks.Begin();
1035 }
1036 
1037 // iterator ClocksEnd() const
1038 TEMP ClockSet::Iterator THIS::ClocksEnd(void) const {
1039  return BASE::pGlobalAttribute->mClocks.End();
1040 }
1041 
1042 // ConsistentTimeConstraint(constraint)
1043 TEMP void THIS::ConsistentTimeConstraint(const TimeConstraint& rTimeConstr) const {
1044  FD_DG("TimedGenerator(" << this << ")::ConsistentTimeConstraint(constr)");
1045  if( rTimeConstr.ClockSymbolTablep() != ClockSymbolTablep()) {
1046  std::stringstream errstr;
1047  errstr << "clocksymboltable mismatch" << std::endl;
1048  throw Exception("TimedGenerator::ConsistentTimeConstraint)", errstr.str(), 200);
1049  }
1050  if(!( rTimeConstr.ActiveClocks() <= Clocks() )) {
1051  std::stringstream errstr;
1052  errstr << "time constraint refers to clocks not in clockset: " <<
1053  rTimeConstr.ActiveClocks().ToString() << " versus " << Clocks().ToString() << std::endl;
1054  throw Exception("TimedGenerator::ConsistentTimeConstraint)", errstr.str(), 200);
1055  }
1056  FD_DG("TimedGenerator(" << this << ")::ConsistentTimeConstraint(constr): ok");
1057 }
1058 
1059 // ConsistentClocks(clocks)
1060 TEMP void THIS::ConsistentClocks(const ClockSet& rClocks) const {
1061  if(!( rClocks <= Clocks() )) {
1062  std::stringstream errstr;
1063  errstr << "clocksset contains clocks not in clockset" << std::endl;
1064  throw Exception("TimedGenerator::ConsistentClocks)", errstr.str(), 200);
1065  }
1066  if( rClocks.SymbolTablep() != ClockSymbolTablep()) {
1067  std::stringstream errstr;
1068  errstr << "clocksymboltable mismatch" << std::endl;
1069  throw Exception("TimedGenerator::ConsistentClocks)", errstr.str(), 200);
1070  }
1071 }
1072 
1073 
1074 // Invariant(index)
1075 TEMP const TimeConstraint& THIS::Invariant(Idx stateindex) const {
1076  if(!BASE::ExistsState(stateindex)) {
1077  std::stringstream errstr;
1078  errstr << "state index " << stateindex << " not found in StateSet" << std::endl;
1079  throw Exception("TimedGenerator::Invariant", errstr.str(), 200);
1080  }
1081  return BASE::pStates->Attribute(stateindex).mInvariant;
1082 }
1083 
1084 // Invariantp(index)
1085 TEMP TimeConstraint* THIS::Invariantp(Idx stateindex) {
1086  if(!BASE::ExistsState(stateindex)) {
1087  std::stringstream errstr;
1088  errstr << "state index " << stateindex << " not found in StateSet" << std::endl;
1089  throw Exception("TimedGenerator::Invariant", errstr.str(), 200);
1090  }
1091  return &BASE::pStates->Attributep(stateindex)->mInvariant;
1092 }
1093 
1094 // Invariant(name)
1095 TEMP const TimeConstraint& THIS::Invariant(const std::string& statename) const {
1096  Idx idx=BASE::StateIndex(statename);
1097  return Invariant(idx);
1098 }
1099 
1100 // Invariantp(name)
1101 TEMP TimeConstraint* THIS::Invariantp(const std::string& statename) {
1102  Idx idx=BASE::StateIndex(statename);
1103  return Invariantp(idx);
1104 }
1105 
1106 // Invariant(index,invariant)
1107 TEMP void THIS::Invariant(Idx stateindex, const TimeConstraint& rInv) {
1108  FD_DG("TimedGenerator(" << this << ")::Invariant("<<stateindex<<",inv)");
1109 #ifdef FAUDES_CHECKED
1110  ConsistentTimeConstraint(rInv);
1111  if(!BASE::ExistsState(stateindex)) {
1112  std::stringstream errstr;
1113  errstr << "state index " << stateindex << " not found in StateSet" << std::endl;
1114  throw Exception("TimedGenerator::Invariant", errstr.str(), 200);
1115  }
1116 #endif
1117  BASE::pStates->Attributep(stateindex)->mInvariant=rInv;
1118  BASE::pStates->Attributep(stateindex)->mInvariant.Name("Invariant");
1119 }
1120 
1121 // Invariant(name,invariant)
1122 TEMP void THIS::Invariant(const std::string& statename, const TimeConstraint& rInv) {
1123  FD_DG("TimedGenerator(" << this << ")::Invariant("<<statename<<",inv)");
1124  Idx idx=BASE::StateIndex(statename);
1125  Invariant(idx,rInv);
1126 }
1127 
1128 // InsInvariant(index,invariant)
1129 TEMP void THIS::InsInvariant(Idx stateindex, const TimeConstraint& rInv) {
1130  FD_DG("TimedGenerator(" << this << ")::InsInvariant("<<stateindex<<",inv)");
1131 #ifdef FAUDES_CHECKED
1132  ConsistentTimeConstraint(rInv);
1133  if(!BASE::ExistsState(stateindex)) {
1134  std::stringstream errstr;
1135  errstr << "state index " << stateindex << " not found in StateSet" << std::endl;
1136  throw Exception("TimedGenerator::InsInvariant", errstr.str(), 200);
1137  }
1138 #endif
1139  if(!rInv.Empty()) {
1140  BASE::pStates->Attributep(stateindex)->mInvariant.Insert(rInv);
1141  }
1142 }
1143 
1144 // InsInvariant(name,invariant)
1145 TEMP void THIS::InsInvariant(const std::string& statename, const TimeConstraint& rInv) {
1146  FD_DG("TimedGenerator(" << this << ")::InsInvariant("<<statename<<",inv)");
1147  Idx idx=BASE::StateIndex(statename);
1148  InsInvariant(idx,rInv);
1149 }
1150 
1151 // ClrInvariant(index)
1152 TEMP void THIS::ClrInvariant(Idx stateindex) {
1153  if(!BASE::pStates->Attribute(stateindex).IsDefault())
1154  BASE::pStates->Attributep(stateindex)->mInvariant.Clear();
1155 }
1156 
1157 // ClrInvariant(name)
1158 TEMP void THIS::ClrInvariant(const std::string& statename) {
1159  Idx idx=BASE::StateIndex(statename);
1160  ClrInvariant(idx);
1161 }
1162 
1163 // ClearInvariants()
1164 TEMP void THIS::ClearInvariants(void) {
1165  // FIXME: should iterate, there could be other attributes
1166  BASE::pStates->ClearAttributes();
1167 }
1168 
1169 
1170 // SetTransition(rX1, rEv, rX2)
1171 TEMP bool THIS::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2) {
1172  return BASE::SetTransition(rX1,rEv,rX2);
1173 }
1174 
1175 
1176 // SetTransition(x1, ev, x2)
1177 TEMP bool THIS::SetTransition(Idx x1, Idx ev, Idx x2) {
1178  return BASE::SetTransition(Transition(x1,ev,x2));
1179 }
1180 
1181 // SetTransition(rTransition, rAttr)
1182 TEMP bool THIS::SetTransition(const Transition& rTransition, const TransAttr& rAttr) {
1183  return BASE::SetTransition(rTransition,rAttr);
1184 }
1185 
1186 // SetTransition(trans,....)
1187 TEMP bool THIS::SetTransition(const Transition& rTrans,
1188  const TimeConstraint& rGuard, const ClockSet& rResets) {
1189  FD_DG("TimedGenerator(" << this << ")::SetTransition(" << (BASE::TStr(rTrans)) <<", " <<
1190  rGuard.ToString() << ", " << rResets.ToString() << ") const");
1191  if(rResets.Empty() && rGuard.Empty()) {
1192  return BASE::SetTransition(rTrans);
1193  }
1194  TransAttr attr;
1195  attr.mGuard=rGuard;
1196  attr.mResets=rResets;
1197  attr.mGuard.Name("Guard");
1198  attr.mResets.Name("Resets");
1199 #ifdef FAUDES_CHECKED
1200  ConsistentTimeConstraint(rGuard);
1201  ConsistentClocks(rResets);
1202 #endif
1203  return BASE::SetTransition(rTrans,attr);
1204 }
1205 
1206 // SetTransition(x1,ev,x2, ...)
1207 TEMP bool THIS::SetTransition(Idx x1, Idx ev, Idx x2,
1208  const TimeConstraint& rGuard, const ClockSet& rResets) {
1209  return SetTransition(Transition(x1,ev,x2),rGuard,rResets);
1210 }
1211 
1212 // SetTransition(X1,Ev,X2, ...)
1213 TEMP bool THIS::SetTransition(
1214  const std::string& rX1, const std::string& rEv, const std::string& rX2,
1215  const TimeConstraint& rGuard, const ClockSet& rResets) {
1216  FD_DG("TimedGenerator(" << this << ")::SetTransition(" << rX1 << " " << rEv <<" " << rX2 <<
1217  rGuard.ToString() << ", " << rResets.ToString() << ") const");
1218  bool res=BASE::SetTransition(rX1,rEv,rX2);
1219  if(rResets.Empty() && rGuard.Empty()) {
1220  return res;
1221  }
1222  TransAttr attr;
1223  attr.mResets=rResets;
1224  attr.mGuard=rGuard;
1225  attr.mGuard.Name("Guard");
1226  attr.mResets.Name("Resets");
1227 #ifdef FAUDES_CHECKED
1228  ConsistentTimeConstraint(rGuard);
1229  ConsistentClocks(rResets);
1230 #endif
1231  BASE::TransAttribute(Transition(rX1,rEv,rX2),attr);
1232  return res;
1233 }
1234 
1235 // Guard(trans)
1236 TEMP const TimeConstraint& THIS::Guard(const Transition& rTrans) const {
1237 #ifdef FAUDES_CHECKED
1238  if(!BASE::ExistsTransition(rTrans)) {
1239  std::stringstream errstr;
1240  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1241  throw Exception("TimedGenerator::Guard(trans)", errstr.str(), 200);
1242  }
1243 #endif
1244  return BASE::pTransRel->Attribute(rTrans).mGuard;
1245 }
1246 
1247 
1248 // Guardp(trans)
1249 TEMP TimeConstraint* THIS::Guardp(const Transition& rTrans) {
1250 #ifdef FAUDES_CHECKED
1251  if(!BASE::ExistsTransition(rTrans)) {
1252  std::stringstream errstr;
1253  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1254  throw Exception("TimedGenerator::Guardp(trans)", errstr.str(), 200);
1255  }
1256 #endif
1257  return &BASE::pTransRel->Attributep(rTrans)->mGuard;
1258 }
1259 
1260 
1261 // Guard(trans,guard)
1262 TEMP void THIS::Guard(const Transition& rTrans, const TimeConstraint& rGuard) {
1263 #ifdef FAUDES_CHECKED
1264  ConsistentTimeConstraint(rGuard);
1265  if(!BASE::ExistsTransition(rTrans)) {
1266  std::stringstream errstr;
1267  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1268  throw Exception("TimedGenerator::Guard(trans,guard)", errstr.str(), 200);
1269  }
1270 #endif
1271  BASE::pTransRel->Attributep(rTrans)->mGuard=rGuard;
1272  BASE::pTransRel->Attributep(rTrans)->mGuard.Name("Guard");
1273 }
1274 
1275 // InsGuard(trans,guard)
1276 TEMP void THIS::InsGuard(const Transition& rTrans, const TimeConstraint& rGuard) {
1277 #ifdef FAUDES_CHECKED
1278  ConsistentTimeConstraint(rGuard);
1279  if(!BASE::ExistsTransition(rTrans)) {
1280  std::stringstream errstr;
1281  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1282  throw Exception("TimedGenerator::InsGuard(trans,guard)", errstr.str(), 200);
1283  }
1284 #endif
1285  if(!rGuard.Empty()) {
1286  BASE::pTransRel->Attributep(rTrans)->mGuard.Insert(rGuard);
1287  }
1288 }
1289 
1290 // ClrGuard(trans)
1291 TEMP void THIS::ClrGuard(const Transition& rTrans) {
1292 #ifdef FAUDES_CHECKED
1293  if(!BASE::ExistsTransition(rTrans)) {
1294  std::stringstream errstr;
1295  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1296  throw Exception("TimedGenerator::ClrGuard(trans)", errstr.str(), 200);
1297  }
1298 #endif
1299  if(!BASE::pTransRel->Attribute(rTrans).IsDefault())
1300  BASE::pTransRel->Attributep(rTrans)->mGuard.Clear;
1301 }
1302 
1303 
1304 // Resets(trans)
1305 TEMP const ClockSet& THIS::Resets(const Transition& rTrans) const {
1306 #ifdef FAUDES_CHECKED
1307  if(!BASE::ExistsTransition(rTrans)) {
1308  std::stringstream errstr;
1309  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1310  throw Exception("TimedGenerator::Resets(trans)", errstr.str(), 200);
1311  }
1312 #endif
1313  return BASE::pTransRel->Attribute(rTrans).mResets;
1314 }
1315 
1316 
1317 // Resetsp(trans)
1318 TEMP ClockSet* THIS::Resetsp(const Transition& rTrans) {
1319 #ifdef FAUDES_CHECKED
1320  if(!BASE::ExistsTransition(rTrans)) {
1321  std::stringstream errstr;
1322  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1323  throw Exception("TimedGenerator::Resetsp(trans)", errstr.str(), 200);
1324  }
1325 #endif
1326  return &BASE::pTransRel->Attributep(rTrans)->mResets;
1327 }
1328 
1329 
1330 // Resets(trans,guard)
1331 TEMP void THIS::Resets(const Transition& rTrans, const ClockSet& rResets) {
1332 #ifdef FAUDES_CHECKED
1333  ConsistentClocks(rResets);
1334  if(!BASE::ExistsTransition(rTrans)) {
1335  std::stringstream errstr;
1336  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1337  throw Exception("TimedGenerator::Resets(trans,guard)", errstr.str(), 200);
1338  }
1339 #endif
1340  BASE::pTransRel->Attributep(rTrans)->mResets=rResets;
1341  BASE::pTransRel->Attributep(rTrans)->mResets.Name("Resets");
1342 }
1343 
1344 // InsResets(trans,guard)
1345 TEMP void THIS::InsResets(const Transition& rTrans, const ClockSet& rResets) {
1346 #ifdef FAUDES_CHECKED
1347  ConsistentClocks(rResets);
1348  if(!BASE::ExistsTransition(rTrans)) {
1349  std::stringstream errstr;
1350  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1351  throw Exception("TimedGenerator::InsResets(trans,guard)", errstr.str(), 200);
1352  }
1353 #endif
1354  if(!rResets.Empty()) {
1355  BASE::pTransRel->Attributep(rTrans)->mResets.InsertSet(rResets);
1356  }
1357 }
1358 
1359 
1360 // ClrResets(trans)
1361 TEMP void THIS::ClrResets(const Transition& rTrans) {
1362 #ifdef FAUDES_CHECKED
1363  if(!BASE::ExistsTransition(rTrans)) {
1364  std::stringstream errstr;
1365  errstr << "transition " << BASE::TStr(rTrans) << " not found " << std::endl;
1366  throw Exception("TimedGenerator::ClrResets(trans)", errstr.str(), 200);
1367  }
1368 #endif
1369  if(!BASE::pTransRel->Attribute(rTrans).IsDefault())
1370  BASE::pTransRel->Attributep(rTrans)->mGuard.Clear;
1371 }
1372 
1373 
1374 // Valid()
1375 TEMP bool THIS::Valid(void) {
1376  FD_DV("TimedGenerator(" << this << ")::Valid()");
1377  //call base
1378  if(!BASE::Valid()) return false;
1379  // check my names
1380  TransSet::Iterator tit;
1381  StateSet::Iterator sit;
1382  for(sit = BASE::StatesBegin(); sit!= BASE::StatesEnd(); ++sit) {
1383  if(Invariant(*sit).Name()!="Invariant") return false;
1384  }
1385  for(tit = BASE::TransRelBegin(); tit!= BASE::TransRelEnd(); ++tit) {
1386  if(Guard(*tit).Name()!="Guard") return false;
1387  if(Resets(*tit).Name()!="Resets") return false;
1388  }
1389  if(Clocks().Name()!="Clocks") return false;
1390  // check my clockset
1391  ClockSet aclocks=ActiveClocks();
1392  if(!(aclocks <= Clocks())) return false;
1393  // check all clocksymboltables
1394  for(sit = BASE::StatesBegin(); sit!= BASE::StatesEnd(); ++sit) {
1395  if(Invariant(*sit).ClockSymbolTablep()!=ClockSymbolTablep()) return false;
1396  }
1397  for(tit = BASE::TransRelBegin(); tit!= BASE::TransRelEnd(); ++tit) {
1398  if(Guard(*tit).ClockSymbolTablep()!=ClockSymbolTablep()) return false;
1399  if(Resets(*tit).SymbolTablep()!=ClockSymbolTablep()) return false;
1400  }
1401  if(Clocks().SymbolTablep()!=ClockSymbolTablep()) return false;
1402 
1403  return true;
1404 }
1405 
1406 
1407 // UpdateAttributes()
1408 TEMP bool THIS::UpdateAttributes(void) {
1409  FD_DG("TimedGenerator(" << this << ")::UpdateAttributes()");
1410 
1411  // debugging example: flag blocking states
1412  // btw: need efficient methods to set/clr flags by sets
1413  StateSet blockstates=BASE::BlockingStates();
1414  StateSet::Iterator sit;
1415  for(sit=BASE::StatesBegin(); sit!= BASE::StatesEnd(); sit++) {
1416  StateAttr attr=BASE::StateAttribute(*sit);
1417  if(blockstates.Exists(*sit)) {
1418  attr.Set(0x20000000);
1419  } else {
1420  attr.Clr(0x20000000);
1421  }
1422  BASE::StateAttribute(*sit,attr);
1423  };
1424 
1425  return true;
1426 }
1427 
1428 
1429 
1430 // CStr(index)
1431 TEMP std::string THIS::CStr(Idx index) const {
1432  return BASE::pGlobalAttribute->mClocks.Str(index);
1433 }
1434 
1435 
1436 
1437 #undef BASE
1438 #undef THIS
1439 #undef TEMP
1440 
1441 
1442 
1443 } // namespace faudes
1444 
1445 
1446 #endif
1447 

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen