pd_pdgenerator.h
Go to the documentation of this file.
1 /** @file pd_pdgenerator.h pushdown generator class TpdGenerator */
2 
3 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2013/14 Stefan Jacobi, Ramon Barakat, Sven Schneider, Anne-Kathrin Hess
6 
7 */
8 
9 #ifndef FAUDES_PD_PDGENERATOR_H
10 #define FAUDES_PD_PDGENERATOR_H
11 //#define FAUDES_DEBUG_GENERATOR
12 //#define FAUDES_DEBUG_CONTAINER
13 
14 #include "corefaudes.h"
15 #include "pd_attributes.h"
16 #include "pd_grammar.h"
17 
18 
19 namespace faudes {
20 
21 
22 
23 /**
24  * Generator with push down extensions.
25  *
26  *
27  * @ingroup PushdownPlugin
28  *
29  * @section Overview
30  * tratarterteartawrtrae
31  *
32  * @section Contents
33  * fvdgdthrthorthtiop
34  */
35 
36 template <class GlobalAttr, class StateAttr, class EventAttr, class TransAttr>
37 class FAUDES_API TpdGenerator : public TcGenerator<GlobalAttr, StateAttr, EventAttr, TransAttr> {
38 
39 public:
40 
41 
42  /**
43  * Constructor
44  */
45  TpdGenerator(void);
46 
47  /**
48  * Copy constructor
49  *
50  * @param rOtherGen
51  */
52  TpdGenerator(const TpdGenerator& rOtherGen);
53 
54  /**
55  * Copy constructor (no attributes)
56  *
57  * @param rOtherGen
58  */
59  TpdGenerator(const vGenerator& rOtherGen);
60 
61  /**
62  * Assignment operator (uses Assign)
63  * Note: you must reimplement this operator in derived
64  * classes in order to handle internal pointers correctly
65  *
66  * @param rOtherGen
67  * Other generator
68  */
69  virtual TpdGenerator& operator= (const TpdGenerator& rOtherGen) {return this->Assign(rOtherGen);};
70 
71  /* Assignment method
72  *
73  * Note: you must reimplement this method in derived
74  * classes in order to handle internal pointers correctly
75  *
76  * @param rOtherGen
77  * Other generator
78  */
79  virtual TpdGenerator& Assign(const Type& rSource);
80 
81  /**
82  * Construct from file
83  *
84  * @param rFileName
85  * Name of file
86  *
87  * @exception Exception
88  * - file format errors (id 1, 50, 51, 52)
89  */
90  TpdGenerator(const std::string& rFileName);
91 
92  /**
93  * Construct on heap.
94  * Constructs a TpdGenerator on heap.
95  *
96  * @return
97  * new Generator
98  */
99  TpdGenerator* New(void) const;
100 
101  /**
102  * Construct copy on heap.
103  * Constructs a TpdGenerator on heap.
104  *
105  * @return
106  * new Generator
107  */
108  TpdGenerator* Copy(void) const;
109 
110  /**
111  * Type test.
112  * Uses C++ dynamic cast to test whether the specified object
113  * casts to a PushdownGenerator.
114  *
115  * @return
116  * TpdGenerator reference if dynamic cast succeeds, else NULL
117  */
118  virtual const Type* Cast(const Type* pOther) const {
119  return dynamic_cast< const TpdGenerator* > (pOther);
120  };
121 
122 
123  /**
124  * Construct on stack.
125  * Constructs a TpdGenerator on stack.
126  *
127  * @return
128  * new Generator
129  */
130  TpdGenerator NewPdGen(void) const;
131 
132  /**
133  * Get Pointer to global StackSymbolTable. This is
134  * a static member of SymbolTable and used as default
135  * for all derived generator classes and instantiated objects.
136  *
137  * @return
138  * Pointer to global StackSymbolTable
139  */
140  static SymbolTable* GlobalStackSymbolTablep(void);
141 
142  /**
143  * XXX: NEW !
144  * Return pretty printable state name (eg for debugging)
145  *
146  * @param idx
147  * index
148  *
149  * @return State name or Idx:<idx> for nonexistent name
150  */
151  std::string StateStr(Idx idx) const;
152 
153  /**
154  * XXX: NEW !
155  * Return pretty printable event name (eg for debugging)
156  *
157  * @param idx
158  * index
159  *
160  * @return Event name or Idx:<idx> for nonexistent name
161  */
162  std::string EventStr(Idx idx) const;
163 
164  /**
165  * Get Pointer to mpStackSymbolTable.
166  *
167  * @return Pointer mpStackSymbolTable
168  */
169  SymbolTable* StackSymbolTablep(void) const;
170 
171  /**
172  * Set StackSymbolTable.
173  *
174  * @param pStackSymTab
175  * Pointer SymbolTable
176  */
177  void StackSymbolTablep(SymbolTable* pStackSymTab);
178 
179  /**
180  * Return a NameSet with generator's StackSymbolTable
181  *
182  * @return
183  * New empty StackSymbolSet on stack
184  */
185  StackSymbolSet NewStackSymbolSet(void) const;
186 
187  /**
188  * Construct a stack symbol on heap.
189  *
190  * @return
191  * Pointer to new empty StackSymbolSet on heap
192  */
193  StackSymbolSet* NewStackSymbolSetp(void) const;
194 
195  /**
196  * Number of stacks symbols in mStackSymbols
197  *
198  * @return Number of stack symbols in mStackSymbols
199  */
200  Idx StackSymbolsSize(void) const;
201 
202  /**
203  * Get stack symbol set as const reference
204  *
205  * @return mStackSymbols
206  */
207  const StackSymbolSet& StackSymbols(void) const;
208 
209 
210  /**
211  * Get stack symbol set as pointer
212  *
213  * @return mStackSymbols
214  */
215  StackSymbolSet* StackSymbolsp(void);
216 
217  /**
218  * Overwrites mStackSymbols with new stack symbols without consistency check
219  *
220  * @param newstacksymbols
221  * New stack symbols that are written to mStackSymbols
222  */
223  void InjectStackSymbols(const StackSymbolSet& newstacksymbols);
224 
225  /**
226  * Looks up stack symbol name for given index
227  *
228  * @param index
229  * Stack symbol index
230  *
231  * @return Stack symbol name
232  */
233  std::string StackSymbolName(Idx index) const;
234 
235 
236  /** XXX:NEW
237  * Set new stack symbol name for existing index.
238  * FAUDES_CHECKED checks if index exists in NameSet.
239  *
240  * @param index
241  * Index to edit
242  * @param rName
243  * New name
244  *
245  * @exception Exception
246  * - index not in this set (id 60)
247  * - index not found in SymbolTable (id 42)
248  * - name already associated with another index (id 44)
249  */
250  void StackSymbolName(Idx index, const std::string& rName) const;
251 
252  /**
253  * Returns stack symbol for given index
254  *
255  * @param index
256  * Stack symbol index
257  *
258  * @return Stack symbol object
259  */
260  StackSymbol StackSymbolObj(Idx index) const;
261 
262  /**
263  * Looks up stack symbol index for given name
264  *
265  * @param rName
266  * Stack symbol name
267  *
268  * @return Stack symbol index or 0 for nonexistent
269  */
270  Idx StackSymbolIndex(const std::string& rName) const;
271 
272  /**
273  * XXX:NEW !
274  * Get string of stack symbol for given index
275  *
276  * @param rName
277  * Stack symbol name
278  *
279  * @return Stack symbol name or Idx:<idx> for nonexistent name
280  */
281  std::string StackSymbolStr(Idx idx) const;
282 
283  /**
284  * Add named stack symbol to generator. An entry in the mpStackSymbolTable will
285  * be made if stack symbol is new.
286  *
287  * @param rName
288  * Name of the stack symbol to add
289  *
290  * @return
291  * New unique index
292  */
293  Idx InsStackSymbol(const std::string& rName);
294 
295  /**
296  * Add stack symbol to generator. An entry in the mpStackSymbolTable will
297  * be made if stack symbol is new.
298  *
299  * @param rSymbol
300  * The stack symbol to add
301  *
302  * @return
303  * New unique index
304  */
305  Idx InsStackSymbol(const StackSymbol& rSymbol);
306 
307  /**
308  * Add named stack bottom to generator. An entry in the mpStackSymbolTable will
309  * be made if stack symbol is new. This will replace any old stack bottom symbol.
310  *
311  * @param rName
312  * Name of the stack bottom symbol to add
313  *
314  * @return
315  * Stack bottom symbol index
316  */
317  Idx SetStackBottom(const std::string& rName);
318 
319  /**
320  * Add stack bottom to generator. An entry in the mpStackSymbolTable will
321  * be made if stack symbol is new. This will replace any old stack bottom symbol.
322  *
323  * @param rSymbol
324  * The stack bottom symbol to add
325  *
326  * @return
327  * Stack bottom symbol index
328  */
329  Idx SetStackBottom(const StackSymbol& rSymbol);
330 
331  /**
332  * Add stack bottom to generator. An entry in the mpStackSymbolTable will
333  * be made if stack symbol is new. This will replace any old stack bottom symbol.
334  *
335  * @param idx
336  * The index of the stack bottom symbol to add
337  *
338  * @return
339  * Stack bottom symbol index
340  */
341  Idx SetStackBottom(const Idx idx);
342 
343  /**
344  * Get the index of the stack bottom symbol
345  *
346  * @return
347  * index of the stack bottom symbol
348  */
349  Idx StackBottom() const;
350 
351  /**
352  * Add new named stack symbols to generator.
353  *
354  * @param rStackSymbolSet
355  * StackSymbolSet
356  */
357  void InsStackSymbols(const StackSymbolSet& rStackSymbolSet);
358 
359  /**
360  * Delete stack symbol from generator by index.
361  *
362  * @param index
363  * Index of stack symbol
364  * @return
365  * True if stack symbol did exist
366  *
367  */
368  bool DelStackSymbol(Idx index);
369 
370  /**
371  * Delete stack symbol from generator by name. mpStackSymbolTable stays untouched.
372  *
373  * @param rName
374  * Name of stack symbol
375  * @return
376  * True if stack symbol did exist
377  */
378  bool DelStackSymbol(const std::string& rName);
379 
380  /**
381  * Delete a set of stack symbols from generator.
382  *
383  * @param rStackSymbols
384  * StackSymbolSet containing stack symbols to remove
385  */
386  void DelStackSymbols(const StackSymbolSet& rStackSymbols);
387 
388  /**
389  * Test existence of stack symbol in mStackSymbols
390  *
391  * @param index
392  * Stack symbol index
393  *
394  * @return
395  * true / false
396  */
397  bool ExistsStackSymbol(Idx index) const;
398 
399  /**
400  * Test existence of stack symbol in mStackSymbols
401  *
402  * @param rName
403  * Stack symbol name
404  *
405  * @return
406  * True if stack symbol exists
407  */
408  bool ExistsStackSymbol(const std::string& rName) const;
409 
410  /**
411  * Returns an iterator to stack symbol index in mStackSymbols
412  *
413  * @param index
414  * Index to find
415  *
416  * @return
417  * StackSymbolSet::Iterator to stack symbol index
418  */
419  StackSymbolSet::Iterator FindStackSymbol(Idx index) const;
420 
421  /**
422  * Returns an iterator to stack symbol index in mStackSymbols
423  *
424  * @param rName
425  * Stack symbol name of index to find
426  *
427  * @return
428  * StackSymbolSet::Iterator to stack symbol index
429  */
430  StackSymbolSet::Iterator FindStackSymbol(const std::string& rName) const;
431 
432  /**
433  * XXX NEW
434  * Get unique stack symbole name
435  *
436  * @param rName
437  * The name prefix
438  * @return string
439  * The unique name
440  */
441  std::string UniqueStackSymbolName(const std::string& rName) const;
442 
443  /**
444  * Iterator to Begin() of mStackSymbols
445  *
446  * @return iterator to begin of mStackSymbols
447  */
448  StackSymbolSet::Iterator StackSymbolsBegin(void) const;
449 
450  /**
451  * Iterator to End() of mStackSymbols
452  *
453  * @return iterator to end of mStackSymbols
454  */
455  StackSymbolSet::Iterator StackSymbolsEnd(void) const;
456 
457  /**
458  * Converts a vector of stack symbols to a vector of Idx
459  *
460  * @param symbols
461  * the vector of stack symbols
462  * @return
463  * vector of Idx
464  */
465  std::vector<Idx> StackSymbolsToIndices(const std::vector<StackSymbol> symbols) const;
466 
467  /** XXX:NEW
468  * Converts a vector of stack symbol names to a vector of Idx
469  *
470  * @param symbols
471  * the vector of stack symbol names
472  * @return
473  * vector of Idx
474  */
475  std::vector<Idx> StackSymbolNamesToIndices(const std::vector<std::string> symbolnames) const;
476 
477  /**
478  * Check if the pushdown generator is deterministic.
479  *
480  * A pushdown generator is deterministic iff distinct steps from a reachable configuration
481  * append elements of the Alphabet to the history variable.
482  * Note that this implies that the existence of an outgoing transition, which event is lambda,
483  * in state q requiring stack-top A prevents other outgoing transitions in q requiring stack-top A.
484  *
485  * @ return
486  * true, if the generator is deterministic
487  */
488  bool IsDeterministic() const;
489 
490  /**
491  * Get number of transitions including pop-push-pairs
492  *
493  * @return
494  * number of transitions
495  */
496  Idx TransRelSize() const;
497 
498  /**
499  * Add a transition to generator by indices. States and event
500  * must already exist!
501  *
502  * Define FAUDES_CHECKED for consistency checks.
503  *
504  * @param x1
505  * Predecessor state index
506  * @param ev
507  * Event index
508  * @param x2
509  * Successor state index
510  *
511  * @return
512  * True, if the transition was new the generator
513  *
514  * @exception Exception
515  * - state or event not in generator (id 95)
516  */
517  bool SetTransition(Idx x1, Idx ev, Idx x2);
518 
519  /**
520  * Add a transition to generator by names. Statename and eventname
521  * must already exist!
522  *
523  * @param rX1
524  * Predecessor state name
525  * @param rEv
526  * Event name
527  * @param rX2
528  * Successor state name
529  *
530  * @return
531  * True, if the transition was new the generator
532  *
533  * @exception Exception
534  * - state or event not in generator (id 95)
535  * - state name not known (id 90)
536  * - event name not known (id 66)
537  */
538  bool SetTransition(const std::string& rX1, const std::string& rEv,
539  const std::string& rX2);
540 
541  /**
542  * Add a transition with attribute to generator. States and event
543  * must already exist!
544  *
545  * Define FAUDES_CHECKED for consistency checks.
546  *
547  * @param rTransition
548  * transition
549  * @param rAttr
550  * attribute
551  *
552  * @return
553  * True, if the transition was new the generator
554  *
555  */
556  bool SetTransition(const Transition& rTransition, const TransAttr& rAttr);
557 
558  /**
559  * Inserts new PushdownTransition constructed from parameters.
560  * Performs consistency checks for x1, x2, ev and all stack symbols in rPop and rPush.
561  *
562  * @param rTrans
563  * new transition
564  * @param rPop
565  * Stack symbol vector to be popped when transitioning
566  * @param rPush
567  * Stack symbol vector to be pushed when transitioning
568  * @return
569  * True, if the transition was new to the generator
570  */
571  bool SetTransition(const Transition& rTrans, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush);
572 
573  /** XXX:NEW
574  * Inserts new PushdownTransition constructed from parameters.
575  * Performs consistency checks for x1, x2, ev and all stack symbols in rPop and rPush.
576  *
577  * @param rTrans
578  * new transition
579  * @param rPop
580  * Stack symbol vector to be popped when transitioning
581  * @param rPush
582  * Stack symbol vector to be pushed when transitioning
583  * @return
584  * True, if the transition was new to the generator
585  */
586  bool SetTransition(const Transition& trans, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush);
587 
588  /**
589  * Inserts new PushdownTransition constructed from parameters.
590  * Performs consistency checks for x1, x2, ev and all stack symbols in rPop and rPush.
591  *
592  * @param rTrans
593  * new transition
594  * @param rPop
595  * Stack symbol vector to be popped when transitioning
596  * @param rPush
597  * Stack symbol vector to be pushed when transitioning
598  * @return
599  * True, if the transition was new to the generator
600  */
601  bool SetTransition(const Transition& rTrans, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush);
602 
603 
604  /**
605  * Inserts new PushdownTransition constructed from parameters.
606  * Performs consistency checks for x1, x2, ev and stack symbols in rPop and rPush.
607  *
608  * @param x1
609  * Start state of new PushdownTransition.
610  * @param ev
611  * Event of new PushdownTransition.
612  * @param x2
613  * End state of new PushdownTransition.
614  * @param rPop
615  * Stack symbol vector to be popped when transitioning
616  * @param rPush
617  * Stack symbol vector to be pushed when transitioning
618  * @return
619  * True, if the transition was new to the generator
620  */
621  bool SetTransition(Idx x1, Idx ev, Idx x2,
622  const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush);
623 
624  /**
625  * Inserts new PushdownTransition constructed from parameters.
626  * Performs consistency checks for x1, x2, ev and stack symbols in rPop and rPush.
627  *
628  * @param x1
629  * Start state of new PushdownTransition.
630  * @param ev
631  * Event of new PushdownTransition.
632  * @param x2
633  * End state of new PushdownTransition.
634  * @param rPop
635  * Stack symbol vector to be popped when transitioning
636  * @param rPush
637  * Stack symbol vector to be pushed when transitioning
638  * @return
639  * True, if the transition was new to the generator
640  */
641  bool SetTransition(Idx x1, Idx ev, Idx x2,
642  const std::vector<Idx>& rPop, const std::vector<Idx>& rPush);
643 
644  /**
645  * Inserts new PushdownTransition constructed from parameters.
646  * Performs consistency checks for x1, x2, ev and stack symbols in rPop and rPush.
647  *
648  * @param rX1
649  * Start state of new PushdownTransition.
650  * @param rEv
651  * Event of new PushdownTransition.
652  * @param rX2
653  * End state of new PushdownTransition.
654  * @param rPop
655  * Stack symbol vector to be popped when transitioning
656  * @param rPush
657  * Stack symbol vector to be pushed when transitioning
658  * @return
659  * True, if the transition was new to the generator
660  */
661  bool SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush);
662 
663  /**
664  * XXX NEW !
665  * Inserts new PushdownTransition constructed from parameters.
666  * Performs consistency checks for x1, x2, ev and stack symbols in rPop and rPush.
667  * (Note: necessary for parsing .dot files)
668  *
669  * @param rX1
670  * Start state of new PushdownTransition.
671  * @param rEv
672  * Event of new PushdownTransition.
673  * @param rX2
674  * End state of new PushdownTransition.
675  * @param rPop
676  * Vector of Stack symbol names to be popped when transitioning
677  * @param rPush
678  * Vector of Stack symbol names to be pushed when transitioning
679  * @return
680  * True, if the transition was new to the generator
681  */
682  bool SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush);
683 
684  /**
685  * XXX NEW !
686  * Inserts new PushdownTransition constructed from parameters.
687  * Performs consistency checks for x1, x2, ev and stack symbols in rPop and rPush.
688  * (Note: necessary for parsing .dot files)
689  *
690  * @param rX1
691  * Start state of new PushdownTransition.
692  * @param rEv
693  * Event of new PushdownTransition.
694  * @param rX2
695  * End state of new PushdownTransition.
696  * @param rPop
697  * Vector of Stack symbol names to be popped when transitioning
698  * @param rPush
699  * Vector of Stack symbol names to be pushed when transitioning
700  * @return
701  * True, if the transition was new to the generator
702  */
703  bool SetTransition(Idx x1, Idx ev, Idx x2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush);
704 
705  /**
706  * Inserts new PushdownTransition constructed from parameters.
707  * Performs consistency checks for x1, x2, ev and stack symbols in rPop and rPush.
708  *
709  * @param rX1
710  * Start state of new PushdownTransition.
711  * @param rEv
712  * Event of new PushdownTransition.
713  * @param rX2
714  * End state of new PushdownTransition.
715  * @param rPop
716  * Stack symbol vector to be popped when transitioning
717  * @param rPush
718  * Stack symbol vector to be pushed when transitioning
719  * @return
720  * True, if the transition was new to the generator
721  */
722  bool SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush);
723 
724 
725  /**
726  * XXX: NEW
727  * Inserts new PushdownTransition constructed from parameters.
728  * Performs consistency checks for x1, x2, ev and stack symbols in pop and push.
729  * Pop and Push vector are given as strings where stack symbol names
730  * written in squared brackets separated by comma
731  *
732  * (Function specially to access from LuaFAUDES)
733  *
734  * @param rX1
735  * Start state of new PushdownTransition.
736  * @param rEv
737  * Event of new PushdownTransition.
738  * @param rPop
739  * String of to be popped stack symbols when transitioning
740  * @param rPush
741  * String of to be pushed stack symbols when transitioning
742  * @param rX2
743  * End state of new PushdownTransition.
744  *
745  * @return
746  * True, if the transition was new to the generator
747  */
748  bool SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rPop,
749  const std::string& rPush, const std::string& rX2);
750 
751  /**
752  * XXX: NEW
753  * Delete an existing PushdownTransition constructed with the provided parameters.
754  * Pop and Push vector are given as strings where stack symbol names
755  * written in squared brackets separated by comma
756  *
757  * (Function specially to access from LuaFAUDES)
758  *
759  * @param rX1
760  * Start state of new PushdownTransition.
761  * @param rEv
762  * Event of new PushdownTransition.
763  * @param rPop
764  * String of to be popped stack symbols when transitioning
765  * @param rPush
766  * String of to be pushed stack symbols when transitioning
767  * @param rX2
768  * End state of new PushdownTransition.
769  *
770  * @return
771  * True, if the transition was deleted from the generator
772  */
773  bool ClrTransition(const std::string& rX1, const std::string& rEv, const std::string& rPop,
774  const std::string& rPush, const std::string& rX2);
775 
776  /**
777  * Delete an exisiting PushdownTransition with the provided parameters.
778  *
779  * @param x1
780  * Start state of the PushdownTransition.
781  * @param ev
782  * Event of the PushdownTransition.
783  * @param x2
784  * End state of the PushdownTransition.
785  * @param rPop
786  * Stack symbol vector to be popped when transitioning
787  * @param rPush
788  * Stack symbol vector to be pushed when transitioning
789  * @return
790  * True, if the transition was deleted from the generator
791  */
792  bool ClrTransition(Idx x1, Idx ev, Idx x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush);
793 
794  /**
795  * Delete an exisiting PushdownTransition with the provided parameters.
796  *
797  * @param x1
798  * Start state of the PushdownTransition.
799  * @param ev
800  * Event of the PushdownTransition.
801  * @param x2
802  * End state of the PushdownTransition.
803  * @param rPop
804  * Stack symbol vector to be popped when transitioning
805  * @param rPush
806  * Stack symbol vector to be pushed when transitioning
807  * @return
808  * True, if the transition was deleted from the generator
809  */
810  bool ClrTransition(Idx x1, Idx ev, Idx x2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush);
811 
812  /**XXX:NEW
813  * Delete an exisiting PushdownTransition with the provided parameters.
814  *
815  * @param x1
816  * Start state of the PushdownTransition.
817  * @param ev
818  * Event of the PushdownTransition.
819  * @param x2
820  * End state of the PushdownTransition.
821  * @param rPop
822  * Stack symbol vector to be popped when transitioning
823  * @param rPush
824  * Stack symbol vector to be pushed when transitioning
825  * @return
826  * True, if the transition was deleted from the generator
827  */
828  bool ClrTransition(Idx x1, Idx ev, Idx x2,const std::vector<std::string>& rPop, const std::vector<std::string>& rPush);
829 
830  /**XXX:NEW
831  * Delete an exisiting PushdownTransition with the provided parameters.
832  *
833  * @param x1
834  * Start state of the PushdownTransition.
835  * @param ev
836  * Event of the PushdownTransition.
837  * @param x2
838  * End state of the PushdownTransition.
839  * @param rPop
840  * Stack symbol vector to be popped when transitioning
841  * @param rPush
842  * Stack symbol vector to be pushed when transitioning
843  * @return
844  * True, if the transition was deleted from the generator
845  */
846  bool ClrTransition(std::string x1, std::string ev, std::string x2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush);
847 
848  /**XXX:NEW
849  * Delete an exisiting PushdownTransition with the provided parameters.
850  *
851  * @param x1
852  * Start state of the PushdownTransition.
853  * @param ev
854  * Event of the PushdownTransition.
855  * @param x2
856  * End state of the PushdownTransition.
857  * @param rPop
858  * Stack symbol vector to be popped when transitioning
859  * @param rPush
860  * Stack symbol vector to be pushed when transitioning
861  * @return
862  * True, if the transition was deleted from the generator
863  */
864  bool ClrTransition(std::string x1, std::string ev, std::string x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush);
865 
866  /**XXX:NEW
867  * Delete an exisiting PushdownTransition with the provided parameters.
868  *
869  * @param x1
870  * Start state of the PushdownTransition.
871  * @param ev
872  * Event of the PushdownTransition.
873  * @param x2
874  * End state of the PushdownTransition.
875  * @param rPop
876  * Stack symbol vector to be popped when transitioning
877  * @param rPush
878  * Stack symbol vector to be pushed when transitioning
879  * @return
880  * True, if the transition was deleted from the generator
881  */
882  bool ClrTransition(std::string x1, std::string ev, std::string x2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush);
883 
884  /**
885  * Delete an exisiting PushdownTransition with the provided parameters.
886  *
887  * @param rTrans
888  * the transition
889  * @param rPop
890  * Stack symbol vector to be popped when transitioning
891  * @param rPush
892  * Stack symbol vector to be pushed when transitioning
893  * @return
894  * True, if the transition was deleted from the generator
895  */
896  bool ClrTransition(const Transition& rTrans, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush);
897 
898  /** XXX:NEW
899  * Delete an exisiting PushdownTransition with the provided parameters.
900  *
901  * @param rTrans
902  * the transition
903  * @param rPop
904  * Stack symbol name vector to be popped when transitioning
905  * @param rPush
906  * Stack symbol name vector to be pushed when transitioning
907  * @return
908  * True, if the transition was deleted from the generator
909  */
910  bool ClrTransition(const Transition& rTrans, const std::vector<std::string>& rPop,const std::vector<std::string>& rPush);
911 
912  /**
913  * Delete an exisiting PushdownTransition with the provided parameters.
914  *
915  * @param rTrans
916  * the transition
917  * @param rPop
918  * Stack symbol vector to be popped when transitioning
919  * @param rPush
920  * Stack symbol vector to be pushed when transitioning
921  * @return
922  * True, if the transition was deleted from the generator
923  */
924  bool ClrTransition(const Transition& rTrans, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush);
925 
926 
927  /**
928  * Test for transition given by x1, ev, x2
929  *
930  *
931  * @param rX1
932  * name of Predecessor state
933  * @param rEv
934  * name of Event
935  * @param rX2
936  * name of Successor state
937  *
938  * @return
939  * true / false
940  */
941  bool ExistsTransition(
942  const std::string& rX1, const std::string& rEv, const std::string& rX2) const;
943 
944  /**
945  * Test for transition given by x1, ev, x2
946  *
947  * @param x1
948  * Predecessor state
949  * @param ev
950  * Event
951  * @param x2
952  * Successor state
953  *
954  * @return
955  * true / false
956  */
957  bool ExistsTransition(Idx x1, Idx ev, Idx x2) const;
958 
959  /**
960  * Test for transition
961  *
962  *
963  * @param rTrans
964  * transition
965  *
966  * @return
967  * true / false
968  */
969  bool ExistsTransition(const Transition& rTrans) const;
970 
971  /**
972  * Test for transition given by x1, ev
973  *
974  * @param x1
975  * Predecessor state
976  * @param ev
977  * Event
978  *
979  * @return
980  * true / false
981  */
982  bool ExistsTransition(Idx x1, Idx ev) const;
983 
984  /**
985  * Test for transition given by x1
986  *
987  * @param x1
988  * Predecessor state
989  *
990  * @return
991  * true / false
992  */
993  bool ExistsTransition(Idx x1) const;
994 
995  /**
996  * XXX NEW !
997  * Test for transition given by x1, ev, x2, pop, push
998  *
999  * @param x1
1000  * Predecessor state
1001  * @param ev
1002  * Event
1003  * @param x2
1004  * Successor state
1005  * @param rPop
1006  * Vector of stacksym indices to be popped
1007  * @param rPush
1008  * Vector of stacksym indices to be pushed
1009  *
1010  * @return
1011  * true / false
1012  */
1013  bool ExistsTransition(Idx x1, Idx ev, Idx x2, const std::vector<Idx>& pop, const std::vector<Idx>& push) const;
1014 
1015  /**
1016  * XXX NEW !
1017  * Test for transition given by x1, ev, x2, pop, push
1018  *
1019  * @param x1
1020  * Predecessor state
1021  * @param ev
1022  * Event
1023  * @param x2
1024  * Successor state
1025  * @param rPop
1026  * Vector of stacksym names to be popped
1027  * @param rPush
1028  * Vector of stacksym names to be pushed
1029  *
1030  * @return
1031  * true / false
1032  */
1033  bool ExistsTransition(Idx x1, Idx ev, Idx x2, const std::vector<std::string>& pop, const std::vector<std::string>& push) const;
1034 
1035  /**
1036  * XXX NEW !
1037  * Test for transition given by x1, ev, x2, pop, push
1038  *
1039  * @param x1
1040  * Predecessor state
1041  * @param ev
1042  * Event
1043  * @param x2
1044  * Successor state
1045  * @param rPop
1046  * Stack symbol vector to be popped
1047  * @param rPush
1048  * Stack symbol vector to be pushed
1049  *
1050  * @return
1051  * true / false
1052  */
1053  bool ExistsTransition(Idx x1, Idx ev, Idx x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush)const;
1054 
1055  /**
1056  * XXX NEW !
1057  * Test for transition given by x1, ev, x2, pop, push
1058  *
1059  * @param x1
1060  * Name of predecessor state
1061  * @param ev
1062  * Name of event
1063  * @param x2
1064  * Name of successor state
1065  * @param rPop
1066  * Stack symbol vector to be popped
1067  * @param rPush
1068  * Stack symbol vector to be pushed
1069  *
1070  * @return
1071  * true / false
1072  */
1073  bool ExistsTransition(const std::string& x1, const std::string& ev, const std::string& x2, const std::vector<StackSymbol>& pop, const std::vector<StackSymbol>& push) const;
1074 
1075  /**
1076  * XXX NEW !
1077  * Test for transition given by x1, ev, x2, pop, push
1078  *
1079  * @param x1
1080  * Name of predecessor state
1081  * @param ev
1082  * Name of event
1083  * @param x2
1084  * Name of successor state
1085  * @param rPop
1086  * Vector of stacksym names to be popped
1087  * @param rPush
1088  * Vector of stacksym names to be pushed
1089  *
1090  * @return
1091  * true / false
1092  */
1093  bool ExistsTransition(const std::string& x1, const std::string& ev, const std::string& x2, const std::vector<std::string>& pop, const std::vector<std::string>& push) const;
1094 
1095  /**
1096  * XXX NEW !
1097  * Test for transition given by x1, ev, x2, pop, push
1098  *
1099  * @param x1
1100  * Name of predecessor state
1101  * @param ev
1102  * Name of event
1103  * @param x2
1104  * Name of successor state
1105  * @param rPop
1106  * Vector of stacksym indices to be popped
1107  * @param rPush
1108  * Vector of stacksym indices to be pushed
1109  *
1110  * @return
1111  * true / false
1112  */
1113  bool ExistsTransition(const std::string& x1, const std::string& ev, const std::string& x2, const std::vector<Idx>& pop, const std::vector<Idx>& push) const;
1114 
1115  /**
1116  * XXX NEW !
1117  * Test for transition given by transition, pop, push
1118  *
1119  * @param rTrans
1120  * Transition
1121  * @param rPop
1122  * Vector of stacksymbols to be popped
1123  * @param rPush
1124  * Vector of stacksymbols to be pushed
1125  *
1126  * @return
1127  * true / false
1128  */
1129  bool ExistsTransition(const Transition& rTrans, const std::vector<StackSymbol>& rPop,const std::vector<StackSymbol>& rPush)const;
1130 
1131  /**
1132  * XXX NEW !
1133  * Test for transition given by transition, pop, push
1134  *
1135  * @param rTrans
1136  * Transition
1137  * @param rPop
1138  * Vector of stacksym names to be popped
1139  * @param rPush
1140  * Vector of stacksym names to be pushed
1141  *
1142  * @return
1143  * true / false
1144  */
1145  bool ExistsTransition(const Transition& rTrans, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush) const;
1146 
1147  /**
1148  * XXX: NEW !
1149  * Test for transition given trans, pop, push
1150  *
1151  * @param rTrans
1152  * The transition
1153  * @param rPop
1154  * Stack symbol vector to be popped
1155  * @param rPush
1156  * Stack symbol vector to be pushed
1157  *
1158  * @return
1159  * true / false
1160  */
1161  bool ExistsTransition(const Transition& rTrans, const std::vector<Idx>& pop, const std::vector<Idx>& push) const;
1162 
1163  /**
1164  * XXX: NEW
1165  * Test for transition given with the provided parameters.
1166  * Pop and Push vector are given as strings where stack symbol names
1167  * written in squared brackets separated by comma
1168  *
1169  * (Function specially to access from LuaFAUDES)
1170  *
1171  * @param rX1
1172  * Start state of new PushdownTransition.
1173  * @param rEv
1174  * Event of new PushdownTransition.
1175  * @param rPop
1176  * String of to be popped stack symbols when transitioning
1177  * @param rPush
1178  * String of to be pushed stack symbols when transitioning
1179  * @param rX2
1180  * End state of new PushdownTransition.
1181  *
1182  * @return
1183  * True, if the transition was deleted from the generator
1184  */
1185  bool ExistsTransition(const std::string& x1, const std::string& ev, const std::string& pop,const std::string& push, const std::string& x2) const;
1186 
1187 
1188  /**
1189  * Get the pop/push set attached to this transition
1190  *
1191  * @param rTrans
1192  * the transition
1193  * @return
1194  * the pop/push set
1195  */
1196  const PopPushSet& PopPush(const Transition& rTrans) const;
1197 
1198  /**
1199  * Get an iterator to the beginning of the pop/push set attached to this
1200  * transition
1201  *
1202  * @param rTrans
1203  * the transition
1204  * @return
1205  * iterator to the beginning of the pop/push set
1206  */
1207  PopPushSet::const_iterator PopPushBegin(const Transition& rTrans) const;
1208 
1209  /**
1210  * Get an iterator to the end of the pop/push set attached to this
1211  * transition
1212  *
1213  * @param rTrans
1214  * the transition
1215  * @return
1216  * iterator to the end of the pop/push set
1217  */
1218  PopPushSet::const_iterator PopPushEnd(const Transition& rTrans) const;
1219 
1220  /**XXX: NEW
1221  * Add lambda stack symbol to generator or return existing one
1222  *
1223  * @return
1224  * index of lambda stack symbol
1225  */
1226  Idx InsLambdaStackSymbol();
1227 
1228  /**
1229  * determine if the stack symbol associated with the given index is lambda
1230  *
1231  * @param index
1232  * index of a stack symbol
1233  * @return
1234  * true if the associated stack symbol is lambda, else false
1235  */
1236  bool IsStackSymbolLambda(Idx index) const;
1237 
1238  /**
1239  * determine if the event associated with the given index is lambda
1240  *
1241  * @param index
1242  * index of an event
1243  * @return
1244  * true if the associated event is lambda, else false
1245  */
1246  bool IsEventLambda(Idx index) const;
1247 
1248 
1249  /**
1250  * Throw exception if stack symbol refers to stack symbol not
1251  * in stack symbol set
1252  *
1253  * @exception Exception
1254  * - invalid stack symbol (id 1001)
1255  */
1256  void ConsistentStackSymbol(const StackSymbol& rStackSymbol) const;
1257 
1258  /**
1259  * Throw exception if stack symbol refers to stack symbol not
1260  * in stack symbol set
1261  *
1262  * @exception Exception
1263  * - invalid stack symbol (id 1001)
1264  */
1265  void ConsistentStackSymbol(Idx idx) const;
1266 
1267  /**
1268  * Throw exception if vector of stack symbols contains stack symbols not
1269  * in generators stack symbol set
1270  *
1271  * @exception Exception
1272  * - invalid stack symbol (id 1001)
1273  */
1274  void ConsistentVectorStackSymbol(const std::vector<StackSymbol>& rVector) const;
1275 
1276  /**
1277  * Throw exception if vector of stack symbols contains stack symbols not
1278  * in generators stack symbol set
1279  *
1280  * @exception Exception
1281  * - invalid stack symbol (id 1001)
1282  */
1283  void ConsistentVectorStackSymbol(const std::vector<Idx>& rVector) const;
1284 
1285  /**
1286  * Throw exception if vector of stack symbols is empty
1287  *
1288  * @exception Exception
1289  * - invalid stack symbol (id 1001)
1290  */
1291  void EmptyVectorPopPush(const std::vector<StackSymbol>& rVector) const;
1292 
1293  /**
1294  * Throw exception if vector of stack symbols is empty
1295  *
1296  * @exception Exception
1297  * - invalid stack symbol (id 1001)
1298  */
1299  void EmptyVectorPopPush(const std::vector<Idx>& rVector) const;
1300 
1301  /**
1302  * Marks a state as being merged from other data type by setting mpMerge.
1303  *
1304  * @param stateName
1305  * the name of the state to mark
1306  * @param rMerge
1307  * the merged state
1308  */
1309  void SetMerge(const std::string& stateName, MergeAbstract& rMerge);
1310 
1311  /**
1312  * Marks a state as being merged from other data type by setting mpMerge.
1313  *
1314  * @param index
1315  * the index of the state to mark
1316  * @param rMerge
1317  * the merged state
1318  */
1319  void SetMerge(Idx index, MergeAbstract& rMerge);
1320 
1321  /**
1322  * Return the merge attribute of a state.
1323  *
1324  * @param index
1325  * the index of the state
1326  */
1327  const MergeAbstract* Merge(Idx index) const;
1328 
1329  /**
1330  * Marks a state as being derived from the intersection with a DFA.
1331  *
1332  * @param stateName
1333  * the name of the state to mark
1334  * @param dfaIndex
1335  * the index of the DFA state
1336  */
1337  void SetDfaState(const std::string& stateName, Idx dfaIndex);
1338 
1339  /**
1340  * Marks a state as being derived from the intersection with a DPA.
1341  *
1342  * @param index
1343  * the index of the state to mark
1344  * @param dfaIndex
1345  * the index of the DFA state
1346  */
1347  void SetDfaState(Idx index, Idx dfaIndex);
1348 
1349  /**
1350  * Return the dfaState attribute of a state.
1351  *
1352  * @param index
1353  * the index of the state
1354  */
1355  Idx DfaState(Idx index) const;
1356 
1357  /**
1358  * Check if generator is valid
1359  *
1360  * @return
1361  * Success
1362  */
1363  virtual bool Valid(void) const;
1364 
1365  /**
1366  * XXX: NEW !
1367  * Writes generator to dot input format.
1368  * The dot file format is specified by the graphviz package; see http://www.graphviz.org.
1369  * The package includes the dot command line tool to generate a graphical
1370  * representation of the generators graph. See also vGenerator::GraphWrite().
1371  *
1372  *
1373  * @param rFileName
1374  * File to write
1375  *
1376  * @exception Exception
1377  * - IO errors (id 2)
1378  */
1379  virtual void DotWrite(const std::string& rFileName) const;
1380 
1381  /**
1382  * XXX: NEW !
1383  * Writes generator to dot input format.
1384  * The dot file format is specified by the graphviz package; see http://www.graphviz.org.
1385  * The package includes the dot command line tool to generate a graphical
1386  * representation of the generators graph.
1387  *
1388  *
1389  * @param rFileName
1390  * File to write
1391  *
1392  * @param printInfo
1393  * Printing contained informations
1394  * (eg. Alphabet, Stack symbols etc.)
1395  *
1396  * @param lr
1397  * Create graph from left to right
1398  *
1399  * @exception Exception
1400  * - IO errors (id 2)
1401  */
1402  virtual void DotWrite(const std::string& rFileName, bool printInfo, bool lr) const;
1403 
1404  /**
1405  * XXX: NEW !
1406  * Create generator from dot input format.
1407  * The dot file format is specified by the graphviz package (see http://www.graphviz.org).
1408  * The package includes the dot command line tool to generate a graphical
1409  * representation of the generators graph.
1410  * (For more details see pd_dotparser.h)
1411  *
1412  * Note: Function will clear current generator.
1413  *
1414  *
1415  * @param rFileName
1416  * File to parse
1417  *
1418  * @exception Exception
1419  * - IO errors (id 2)
1420  */
1421  virtual void DotRead(const std::string& rFileName);
1422 
1423 
1424 
1425 private:
1426 
1427  /**
1428  * Get stack symbols from given string.
1429  * stack symbol names should be written in squared brackets separated by comma
1430  */
1431  std::vector<std::string> ParseStackSymbolNames(const std::string& rStr) const;
1432 
1433 }; //end class TpdGenerator
1434 
1435 /** Convenience typedef for PushdownGenerator */
1436 typedef TpdGenerator<AttributePushdownGlobal, AttributePushdownState,
1438 
1440 
1441 
1442 // convenient scope macros
1443 #define THIS TpdGenerator<GlobalAttr, StateAttr, EventAttr, TransAttr>
1444 #define BASE TcGenerator<GlobalAttr, StateAttr, EventAttr, TransAttr>
1445 #define TEMP template <class GlobalAttr, class StateAttr, class EventAttr, class TransAttr>
1446 
1447 // TpdGenerator(void)
1448 TEMP THIS::TpdGenerator(void) : BASE() {
1449  // set basic members (cosmetic)
1450  BASE::pGlobalAttribute->mStackSymbols.Name("StackSymbols");
1451  BASE::pGlobalAttribute->mpStackSymbolTable=StackSymbolSet::StaticSymbolTablep();
1452  FD_DG("PushdownGenerator(" << this << ")::PushdownGenerator() with csymtab "
1453  << (BASE::pGlobalAttribute->mpStackSymbolTable ));
1454 }
1455 
1456 // TpdGenerator(rOtherGen)
1457 TEMP THIS::TpdGenerator(const TpdGenerator& rOtherGen) : BASE(rOtherGen) {
1458  FD_DG("PushdownGenerator(" << this << ")::PushdownGenerator(rOtherGen) with csymtab"
1459  << "(BASE::pGlobalAttribute->mpStackSymbolTable)" );
1460 }
1461 
1462 // TpdGenerator(rOtherGen)
1463 TEMP THIS::TpdGenerator(const vGenerator& rOtherGen) : BASE(rOtherGen) {
1464  // set basic members (cosmetic)
1465  BASE::pGlobalAttribute->mStackSymbols.Name("StackSymbols");
1466  BASE::pGlobalAttribute->mpStackSymbolTable=StackSymbolSet::StaticSymbolTablep();
1467  FD_DG("PushdownGenerator(" << this << ")::PushdownGenerator(rOtherGen) with csymtab"
1468  << "(BASE::pGlobalAttribute->mpStackSymbolTable)" );
1469 }
1470 
1471 // TpdGenerator(rFilename)
1472 TEMP THIS::TpdGenerator(const std::string& rFileName)/* : BASE(rFileName)*/ {
1473  FD_DG("PushdownGenerator(" << this << ")::PushdownGenerator(" << rFileName << ") with csymtab"
1474  << "(BASE::pGlobalAttribute->mpStackSymbolTable)" );
1475  if(rFileName.substr(rFileName.find_last_of(".") + 1) == "dot")
1476  {
1477  // set basic members (cosmetic)
1478  BASE::pGlobalAttribute->mStackSymbols.Name("StackSymbols");
1479  BASE::pGlobalAttribute->mpStackSymbolTable=StackSymbolSet::StaticSymbolTablep();
1480  THIS::DotRead(rFileName);
1481  }
1482  else
1483  BASE(rFileName);
1484 }
1485 
1486 // copy from other faudes type
1487 TEMP THIS& THIS::Assign(const Type& rSrc) {
1488  FD_DG("TpdGenerator(" << this << ")::Assign([type] " << &rSrc << ")");
1489  // bail out on match
1490  if(&rSrc==static_cast<const Type*>(this)) return *this;
1491  // pass on to base
1492  BASE::Assign(rSrc);
1493  return *this;
1494 }
1495 
1496 //StateStr(idx)
1497 TEMP std::string THIS::StateStr(Idx idx) const{
1498  FD_DG("TpdGenerator(" << this << ")::StateStr("<< idx <<"\")");
1499  #ifdef FAUDES_CHECKED
1500  if (! BASE::ExistsState(idx)) {
1501  std::stringstream errstr;
1502  errstr << "state \"" << idx << "\" not found in generator \""
1503  << BASE::Name() << "\"";
1504  throw Exception("TpdGenerator::StateStr(idx)", errstr.str(), 89);
1505  }
1506  #endif
1507 
1508  std::string str= BASE::StateName(idx);
1509  if(str =="") str="Idx:" + ToStringInteger(idx);
1510  return str;
1511 }
1512 
1513 //EventStr(idx)
1514 TEMP std::string THIS::EventStr(Idx idx) const{
1515  FD_DG("TpdGenerator(" << this << ")::EventStr("<< idx <<"\")");
1516  #ifdef FAUDES_CHECKED
1517  if (! BASE::ExistsEvent(idx)) {
1518  std::stringstream errstr;
1519  errstr << "event \"" << idx << "\" not found in generator \""
1520  << BASE::Name() << "\"";
1521  throw Exception("TpdGenerator::EventStr(idx)", errstr.str(), 89);
1522  }
1523  #endif
1524 
1525  std::string str= BASE::EventName(idx);
1526  if(str =="") str="Idx:" + ToStringInteger(idx);
1527  return str;
1528 }
1529 
1530 //GlobalStackSymbolTablep
1531 TEMP SymbolTable* THIS::GlobalStackSymbolTablep(void) {
1533 }
1534 
1535 // StackSymbolTablep()
1536 TEMP SymbolTable* THIS::StackSymbolTablep(void) const {
1537  return BASE::pGlobalAttribute->mpStackSymbolTable;
1538 }
1539 
1540 // StackSymbolTablep(pSymTab)
1541 TEMP void THIS::StackSymbolTablep(SymbolTable* pSymTab) {
1542  BASE::Clear();
1543  BASE::pGlobalAttribute->mpStackSymbolTable=pSymTab;
1544 }
1545 
1546 // New
1547 TEMP THIS* THIS::New(void) const {
1548  // allocate
1549  THIS* res = new THIS;
1550  // fix base data
1551  res->EventSymbolTablep(BASE::mpEventSymbolTable);
1552  res->mStateNamesEnabled=BASE::mStateNamesEnabled;
1553  res->mReindexOnWrite=BASE::mReindexOnWrite;
1554  // fix my data
1555  res->StackSymbolTablep(StackSymbolTablep());
1556  return res;
1557 }
1558 
1559 // Copy
1560 TEMP THIS* THIS::Copy(void) const {
1561  // allocate
1562  THIS* res = new THIS(*this);
1563  // done
1564  return res;
1565 }
1566 
1567 // NewTGen
1568 TEMP THIS THIS::NewPdGen(void) const {
1569  // call base (fixes by assignment constructor)
1570  THIS res= BASE::NewCGen();
1571  // fix my data
1572  res.StackSymbolTablep(StackSymbolTablep());
1573  return res;
1574 }
1575 
1576 // StackSymbolsSize() const
1577 TEMP Idx THIS::StackSymbolsSize(void) const {
1578  return BASE::pGlobalAttribute->mStackSymbols.Size();
1579 }
1580 
1581 // StackSymbols()
1582 TEMP const StackSymbolSet& THIS::StackSymbols(void) const {
1583  return BASE::pGlobalAttribute->mStackSymbols;
1584 }
1585 
1586 // StackSymbolssp()
1587 TEMP StackSymbolSet* THIS::StackSymbolsp(void) {
1588  return &BASE::pGlobalAttribute->mStackSymbols;
1589 }
1590 
1591 // InjectStackSymbols(set)
1592 TEMP void THIS::InjectStackSymbols(const StackSymbolSet& newstacksymbols) {
1593  BASE::pGlobalAttribute->mStackSymbols=newstacksymbols;
1594  BASE::pGlobalAttribute->mStackSymbols.Name("StackSymbols");
1595 }
1596 
1597 // StackSymbolName(index)
1598 TEMP std::string THIS::StackSymbolName(Idx index) const {
1599  return BASE::pGlobalAttribute->mStackSymbols.SymbolicName(index);
1600 }
1601 
1602 // StackSymbolName(index,name)
1603 TEMP void THIS::StackSymbolName(Idx index, const std::string& rName) const {
1604  FD_DG("TpdGenerator(" << this << ")::StackSymbolName("
1605  << index << ",\"" << rName << "\")");
1606  #ifdef FAUDES_CHECKED
1607  if (! ExistsStackSymbol(index)) {
1608  std::stringstream errstr;
1609  errstr << "stack symbol idex \"" << index << "\" not found in generator \""
1610  << BASE::Name() << "\"";
1611  throw Exception("TpdGenerator::StateName(index, name)", errstr.str(), 90);
1612  }
1613  #endif
1614  BASE::pGlobalAttribute->mStackSymbols.SymbolicName(index, rName);
1615 }
1616 
1617 //StackSymbolObj(index)
1618 TEMP StackSymbol THIS::StackSymbolObj(Idx index) const {
1619  return StackSymbol(BASE::pGlobalAttribute->mStackSymbols.SymbolicName(index));
1620 }
1621 
1622 // StackSymbolIndex(name)
1623 TEMP Idx THIS::StackSymbolIndex(const std::string& rName) const {
1624  return BASE::pGlobalAttribute->mStackSymbols.Index(rName);
1625 }
1626 
1627 // InsStackSymbol(name)
1628 TEMP Idx THIS::InsStackSymbol(const std::string& rName) {
1629  return BASE::pGlobalAttribute->mStackSymbols.Insert(rName);
1630 }
1631 
1632 //InsStackSymbol(symbol)
1633 TEMP Idx THIS::InsStackSymbol(const StackSymbol& rSymbol){
1634  return BASE::pGlobalAttribute->mStackSymbols.Insert(rSymbol.Symbol());
1635 }
1636 
1637 // InsStackSymbols(set)
1638 TEMP void THIS::InsStackSymbols(const StackSymbolSet& rStackSymbolSet) {
1639  BASE::pGlobalAttribute->mStackSymbols.InsertSet(rStackSymbolSet);
1640 }
1641 
1642 // SetStackBottom(name)
1643 TEMP Idx THIS::SetStackBottom(const std::string& rName) {
1644  Idx i = BASE::pGlobalAttribute->mStackSymbols.Insert(rName);
1645  BASE::pGlobalAttribute->mStackBottom = i;
1646  return i;
1647 }
1648 
1649 //SetStackBottom(symbol)
1650 TEMP Idx THIS::SetStackBottom(const StackSymbol& rSymbol){
1651  Idx i = BASE::pGlobalAttribute->mStackSymbols.Insert(rSymbol.Symbol());
1652  BASE::pGlobalAttribute->mStackBottom = i;
1653  return i;
1654 }
1655 
1656 //SetStackBottom(index)
1657 TEMP Idx THIS::SetStackBottom(const Idx idx){
1658  if(!ExistsStackSymbol(idx)) {
1659  std::stringstream errstr;
1660  errstr << "stack symbol with index " << idx << " not found in generator. " << std::endl;
1661  throw Exception("PushdownGenerator::SetStackBottom(idx)", errstr.str(), 200);
1662  }
1663  BASE::pGlobalAttribute->mStackBottom = StackSymbol(StackSymbolName(idx));
1664  return idx;
1665 }
1666 
1667 //StackBottom()
1668 TEMP Idx THIS::StackBottom() const{
1669  return BASE::pGlobalAttribute->mStackBottom;
1670 }
1671 
1672 // DelStackSymbol(index)
1673 TEMP bool THIS::DelStackSymbol(Idx index) {
1674  FD_DG("PushdownGenerator(" << this << ")::DelStackSymbol(" << index << ")");
1675  return BASE::pGlobalAttribute->mStackSymbols.Erase(index);
1676 }
1677 
1678 // DelStackSymbol(name)
1679 TEMP bool THIS::DelStackSymbol(const std::string& rName) {
1680  Idx index=BASE::pGlobalAttribute->mStackSymbols.Index(rName);
1681  return DelStackSymbol(index);
1682 }
1683 
1684 // DelStackSymbols(set)
1685 TEMP void THIS::DelStackSymbols(const StackSymbolSet& rStackSymbols) {
1686  StackSymbolSet::Iterator it=StackSymbolsBegin();
1687  while(it!=StackSymbolsEnd()){
1688  DelStackSymbol(*(it++)); // fixed: 2013-12-17
1689  }
1690 }
1691 
1692 // ExistsStackSymbol(index)
1693 TEMP bool THIS::ExistsStackSymbol(Idx index) const {
1694  return BASE::pGlobalAttribute->mStackSymbols.Exists(index);
1695 }
1696 
1697 // ExistsStackSymbol(name)
1698 TEMP bool THIS::ExistsStackSymbol(
1699  const std::string& rName) const {
1700  return BASE::pGlobalAttribute->mStackSymbols.Exists(rName);
1701 }
1702 
1703 // FindStackSymbol(index)
1704 TEMP StackSymbolSet::Iterator THIS::FindStackSymbol(Idx index) const {
1705  return BASE::pGlobalAttribute->mStackSymbols.Find(index);
1706 }
1707 
1708 // FindStackSymbol(name)
1709 TEMP StackSymbolSet::Iterator THIS::FindStackSymbol(const std::string& rName) const {
1710  return BASE::pGlobalAttribute->mStackSymbols.Find(rName);
1711 }
1712 
1713 //StackSymbolStr(idx)
1714 TEMP std::string THIS::StackSymbolStr(Idx idx) const{
1715  FD_DG("TpdGenerator(" << this << ")::StackSymbolStr("<< idx <<"\")");
1716  #ifdef FAUDES_CHECKED
1717  if (! ExistsStackSymbol(idx)) {
1718  std::stringstream errstr;
1719  errstr << "stack symbol \"" << idx << "\" not found in generator \""
1720  << BASE::Name() << "\"";
1721  throw Exception("TpdGenerator::StackSymbolStr(idx)", errstr.str(), 89);
1722  }
1723  #endif
1724  std::string str= THIS::StackSymbolName(idx);
1725  if(str =="") str="Idx:" + ToStringInteger(idx);
1726  return str;
1727 }
1728 
1729 //UniqueStackSymbolName(rName)
1730 TEMP std::string THIS::UniqueStackSymbolName(const std::string& rName) const {
1731  FD_DG("PushdownGenerator(" << this << ")::UniqueStackSymbolName(" << rName << ")");
1732  std::string name=rName;
1733  if(name=="") name="s";
1734  return BASE::pGlobalAttribute->mpStackSymbolTable->UniqueSymbol(name) ;
1735 }
1736 
1737 //Iterator StackSymbolsBegin() const
1738 TEMP StackSymbolSet::Iterator THIS::StackSymbolsBegin(void) const {
1739  return BASE::pGlobalAttribute->mStackSymbols.Begin();
1740 }
1741 
1742 //Iterator StackSymbolsEnd() const
1743 TEMP StackSymbolSet::Iterator THIS::StackSymbolsEnd(void) const {
1744  return BASE::pGlobalAttribute->mStackSymbols.End();
1745 }
1746 //StackSymbolsToIndices
1747 TEMP std::vector<Idx> THIS::StackSymbolsToIndices(const std::vector<StackSymbol> symbols) const{
1748  std::vector<StackSymbol>::const_iterator ssit;
1749  std::vector<Idx> rV;
1750  for(ssit = symbols.begin(); ssit != symbols.end(); ssit++){
1751  rV.push_back(StackSymbolIndex(ssit->Symbol()));
1752  }
1753  return rV;
1754 }
1755 
1756 //StackSymbolNamesToIndices
1757 TEMP std::vector<Idx> THIS::StackSymbolNamesToIndices(const std::vector<std::string> symbolnames) const{
1758  std::vector<std::string>::const_iterator ssit;
1759  std::vector<Idx> rV;
1760  for(ssit = symbolnames.begin(); ssit != symbolnames.end(); ssit++){
1761  rV.push_back(StackSymbolIndex(*ssit));
1762  }
1763  return rV;
1764 }
1765 
1766 //IsDeterministic() const
1768 
1769  StateSet::Iterator stateit;
1770  TransSet::Iterator transit1, transit2;
1771  PopPushSet::iterator ppit1, ppit2;
1772 
1773  //for each state
1774  for(stateit = BASE::StatesBegin(); stateit != BASE::StatesEnd(); ++stateit){
1775  //check each transition pair
1776  for(transit1 = BASE::TransRelBegin(*stateit); transit1 != BASE::TransRelEnd(*stateit); ++transit1){
1777  for(transit2 = transit1; transit2 != BASE::TransRelEnd(*stateit); ++transit2){
1778  //if same event or one event is lambda
1779  if((transit1->Ev == transit2->Ev) ||
1780  THIS::IsEventLambda(transit2->Ev) ||
1781  THIS::IsEventLambda(transit1->Ev)){
1782 
1783  uint matches = 0;
1784 
1785  //check popped stack symbols
1786  for(ppit1 = THIS::PopPushBegin(*transit1); ppit1 != THIS::PopPushEnd(*transit1); ++ppit1){
1787  for(ppit2 = THIS::PopPushBegin(*transit2); ppit2 != THIS::PopPushEnd(*transit2); ++ppit2){
1788  if(ppit1->first == ppit2->first)
1789  matches++;
1790  }
1791  if(transit1 == transit2){
1792  // decrease matches counter because for sure there will be one match (with the transition itself)
1793  matches--;
1794  }
1795  if(matches > 0)
1796  return false;
1797  }
1798  }
1799  }
1800  }
1801  }
1802 
1803  return true;
1804 }
1805 
1806 TEMP Idx THIS::TransRelSize() const{
1807 
1808  TransSet::Iterator transit;
1809  Idx s = 0;
1810  for(transit = BASE::TransRelBegin(); transit != BASE::TransRelEnd(); transit++){
1811  s += PopPush(*transit).size();
1812  }
1813  return s;
1814 }
1815 
1816 // SetTransition(rX1, rEv, rX2)
1817 TEMP bool THIS::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2) {
1818  return BASE::SetTransition(rX1,rEv,rX2);
1819 }
1820 
1821 
1822 // SetTransition(x1, ev, x2)
1823 TEMP bool THIS::SetTransition(Idx x1, Idx ev, Idx x2) {
1824  return BASE::SetTransition(Transition(x1,ev,x2));
1825 }
1826 
1827 // SetTransition(rTransition, rAttr)
1828 TEMP bool THIS::SetTransition(const Transition& rTransition, const TransAttr& rAttr) {
1829  return BASE::SetTransition(rTransition,rAttr);
1830 }
1831 
1832 // SetTransition(trans,....)
1833 TEMP bool THIS::SetTransition(const Transition& rTrans, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush) {
1834  return SetTransition(rTrans, StackSymbolsToIndices(rPop), StackSymbolsToIndices(rPush));
1835 }
1836 
1837 TEMP bool THIS::SetTransition(const Transition& rTrans,const std::vector<Idx>& rPop, const std::vector<Idx>& rPush) {
1838  FD_DG("PushdownGenerator(" << this << ")::SetTransition(" << (BASE::TStr(rTrans)) <<", " <<
1839  ", PopVector" << ", " << "PushVector" << ") const");
1840 #ifdef FAUDES_CHECKED
1841  EmptyVectorPopPush(rPop);
1842  EmptyVectorPopPush(rPush);
1843 #endif
1844  BASE::SetTransition(rTrans);
1845  //get the transition attribute or take new one if it does not exist
1846  TransAttr attr;
1847  if(BASE::TransAttributep(rTrans) != 0){
1848  attr = *BASE::TransAttributep(rTrans);
1849  }
1850  std::pair<std::vector<Idx>, std::vector<Idx> > popPushPair;
1851  popPushPair.first = rPop;
1852  popPushPair.second = rPush;
1853  //add new PopPushPair
1854  attr.mPopPush.insert(popPushPair);
1855 #ifdef FAUDES_CHECKED
1856  ConsistentVectorStackSymbol(rPop);
1857  ConsistentVectorStackSymbol(rPush);
1858 #endif
1859  return BASE::SetTransition(rTrans,attr);
1860 }
1861 
1862 // SetTransition(x1,ev,x2, pop, push)
1863 TEMP bool THIS::SetTransition(Idx x1, Idx ev, Idx x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush) {
1864  return SetTransition(Transition(x1,ev,x2),rPop,rPush);
1865 }
1866 
1867 // SetTransition(x1,ev,x2, pop, push)
1868 TEMP bool THIS::SetTransition(Idx x1, Idx ev, Idx x2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush) {
1869  return SetTransition(Transition(x1,ev,x2),rPop,rPush);
1870 }
1871 
1872 TEMP bool THIS::SetTransition(const Transition& rTrans, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush) {
1873  return SetTransition(rTrans,StackSymbolNamesToIndices(rPop),StackSymbolNamesToIndices(rPush));
1874 }
1875 
1876 // SetTransition(X1,Ev,X2, ...)
1877 TEMP bool THIS::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush) {
1878  FD_DG("PushdownGenerator(" << this << ")::SetTransition(" << rX1 << " " << rEv <<" " << rX2 <<
1879  ", PopVector" << ", " << "PushVector" << ") const");
1880  //try to add transition, will do nothing if transition exists
1881  bool res=BASE::SetTransition(rX1,rEv,rX2);
1882  //get transition via iterator
1883  Transition rTrans = *(BASE::FindTransition(rX1,rEv,rX2));
1884 #ifdef FAUDES_CHECKED
1885  EmptyVectorPopPush(rPop);
1886  EmptyVectorPopPush(rPush);
1887 #endif
1888  //get the transition attribute or take new one if it does not exist
1889  TransAttr attr;
1890  if(BASE::TransAttributep(rTrans) != 0){
1891  attr = *BASE::TransAttributep(rTrans);
1892  }
1893  std::pair<std::vector<Idx>, std::vector<Idx> > popPushPair;
1894  popPushPair.first = StackSymbolsToIndices(rPop);
1895  popPushPair.second = StackSymbolsToIndices(rPush);
1896  //add new PopPushPair
1897  attr.mPopPush.insert(popPushPair);
1898 #ifdef FAUDES_CHECKED
1899  ConsistentVectorStackSymbol(rPop);
1900  ConsistentVectorStackSymbol(rPush);
1901 #endif
1902  BASE::TransAttribute(Transition(BASE::StateIndex(rX1),BASE::EventIndex(rEv),BASE::StateIndex(rX2)),attr);
1903  return res;
1904 }
1905 
1906 // SetTransition(x1,ev,x2,rPop,rPush)
1907 TEMP bool THIS::SetTransition(Idx x1, Idx ev, Idx x2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush) {
1908  return SetTransition(Transition(x1,ev,x2),rPop,rPush);
1909 }
1910 
1911 // SetTransition(x1,ev,x2,rPop,rPush)
1912 TEMP bool THIS::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush) {
1913  return SetTransition(Transition(BASE::StateIndex(rX1),BASE::EventIndex(rEv),BASE::StateIndex(rX2)),rPop,rPush);
1914 }
1915 
1916 // SetTransition(x1,ev,x2,rPop,rPush)
1917 TEMP bool THIS::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush) {
1918  return SetTransition(Transition(BASE::StateIndex(rX1),BASE::EventIndex(rEv),BASE::StateIndex(rX2)),rPop,rPush);
1919 }
1920 
1921 // ParseStackSymbolNames("[X,Y]")
1922 TEMP std::vector<std::string> THIS::ParseStackSymbolNames(const std::string& rStr) const{
1923  std::string::size_type end_position,pos= 0;
1924  std::vector<std::string> syms;
1925  std::string s = rStr;
1926 
1927  //remove spaces from string
1928  s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
1929 
1930  //get pop/push symbols
1931  pos = s.find("[");
1932  if (pos != std::string::npos)
1933  {
1934  //get stacksymbols
1935  end_position = s.find("]",++pos);
1936  if (end_position != std::string::npos)
1937  {
1938  //get string between squared brackets
1939  std::string found_text = s.substr(pos, end_position-pos);
1940 
1941  if (!found_text.empty()) {
1942  std::string::size_type curr = 0, end = 0;
1943 
1944  //substring
1945  std::string sub;
1946 
1947  //while comma separator exists from current position
1948  while ((end = found_text.find(",", curr)) != std::string::npos) {
1949  sub = found_text.substr(curr, end - curr);
1950  syms.push_back(sub);
1951  curr = end + 1;
1952  }
1953 
1954  //add last symbol
1955  if (curr < found_text.size())
1956  syms.push_back(found_text.substr(curr));
1957  }
1958  }
1959  #ifdef FAUDES_CHECKED
1960  else{
1961  std::stringstream errstr;
1962  errstr << " Missing ']' for pop or push ." << std::endl;
1963  throw Exception("TpdGenerator::parsePPString", errstr.str(), 200);
1964  }
1965  #endif
1966  }
1967  #ifdef FAUDES_CHECKED
1968  else{
1969  std::stringstream errstr;
1970  errstr << " Missing '[' for pop or push ." << std::endl;
1971  throw Exception("TpdGenerator::parsePPString", errstr.str(), 200);
1972  }
1973  #endif
1974 
1975  //if no stacksym find, add lambda
1976  if(syms.empty())
1977  syms.push_back(FAUDES_PD_LAMBDA);
1978 
1979  return syms;
1980 }
1981 
1982 // SetTransition(rX1,rEv,rPop,rPush, rX2) (note: luabinding)
1983 TEMP bool THIS::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rPop,
1984  const std::string& rPush, const std::string& rX2){
1985  return SetTransition(rX1,rEv,rX2,ParseStackSymbolNames(rPop),ParseStackSymbolNames(rPush));
1986 }
1987 
1988 //clearTransition(x1,ev,x2,rPop,rPush)
1989 TEMP bool THIS::ClrTransition(Idx x1, Idx ev, Idx x2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush){
1990  return ClrTransition(Transition(x1,ev,x2),rPop,rPush);
1991 }
1992 
1993 //clearTransition(x1,ev,x2,rPop,rPush)
1994 TEMP bool THIS::ClrTransition(Idx x1, Idx ev, Idx x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush){
1995  return ClrTransition(Transition(x1,ev,x2),rPop,rPush);
1996 }
1997 
1998 //clearTransition(x1,ev,x2,rPop,rPush)
1999 TEMP bool THIS::ClrTransition(Idx x1, Idx ev, Idx x2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush){
2000  return ClrTransition(Transition(x1,ev,x2),rPop,rPush);
2001 }
2002 
2003 //clearTransition(x1,ev,x2,rPop,rPush)
2004 TEMP bool THIS::ClrTransition(std::string x1, std::string ev, std::string x2, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush){
2005  return ClrTransition(Transition(BASE::StateIndex(x1),BASE::EventIndex(ev),BASE::StateIndex(x2)),rPop,rPush);
2006 }
2007 
2008 //clearTransition(x1,ev,x2,rPop,rPush)
2009 TEMP bool THIS::ClrTransition(std::string x1, std::string ev, std::string x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush){
2010  return ClrTransition(Transition(BASE::StateIndex(x1),BASE::EventIndex(ev),BASE::StateIndex(x2)),rPop,rPush);
2011 }
2012 
2013 //clearTransition(x1,ev,x2,rPop,rPush)
2014 TEMP bool THIS::ClrTransition(std::string x1, std::string ev, std::string x2, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush){
2015  return ClrTransition(Transition(BASE::StateIndex(x1),BASE::EventIndex(ev),BASE::StateIndex(x2)),rPop,rPush);
2016 }
2017 
2018 //clearTransition(rTrans,rPop,rPush)
2019 TEMP bool THIS::ClrTransition(const Transition& rTrans, const std::vector<StackSymbol>& rPop,const std::vector<StackSymbol>& rPush){
2020  return ClrTransition(rTrans,StackSymbolsToIndices(rPop),StackSymbolsToIndices(rPush));
2021 }
2022 
2023 //clearTransition(rTrans,rPop,rPush)
2024 TEMP bool THIS::ClrTransition(const Transition& rTrans, const std::vector<std::string>& rPop,const std::vector<std::string>& rPush){
2025  return ClrTransition(rTrans,StackSymbolNamesToIndices(rPop),StackSymbolNamesToIndices(rPush));
2026 }
2027 
2028 //clearTransition(rTrans,rPop,rPush)
2029 TEMP bool THIS::ClrTransition(const Transition& rTrans, const std::vector<Idx>& rPop,const std::vector<Idx>& rPush){
2030  //check for existence of base transition
2031  if(!BASE::ExistsTransition(rTrans)){
2032  return false;
2033  }
2034 
2035  //delete pop/push pair in said transition
2036  if(!BASE::pTransRel->Attributep(rTrans)->ClrPopPush(rPop, rPush)){
2037  return false;
2038  }
2039 
2040  //delete transition if popPush is empty
2041  if(PopPush(rTrans).empty()){
2042  BASE::ClrTransition(rTrans);
2043  }
2044 
2045  return true;
2046 }
2047 
2048 // ClrTransition(rX1,rEv,rPop,rPush, rX2) (note: luabinding)
2049 TEMP bool THIS::ClrTransition(const std::string& rX1, const std::string& rEv, const std::string& rPop,const std::string& rPush, const std::string& rX2){
2050  return ClrTransition(rX1,rEv,rX2,ParseStackSymbolNames(rPop),ParseStackSymbolNames(rPush));
2051 }
2052 
2053 // ExistsTransition(rX1,rEv,rX2)
2054 TEMP bool THIS::ExistsTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2) const{
2055  return BASE::ExistsTransition(rX1,rEv,rX2);
2056 }
2057 
2058 // ExistsTransition(x1, ev, x2)
2059 TEMP bool THIS::ExistsTransition(Idx x1, Idx ev, Idx x2) const{
2060  return BASE::ExistsTransition(x1,ev,x2);
2061 }
2062 
2063 // ExistsTransition(rTrans)
2064 TEMP bool THIS::ExistsTransition(const Transition& rTrans) const{
2065  return BASE::ExistsTransition(rTrans);
2066 }
2067 
2068 // ExistsTransition(x1, ev)
2069 TEMP bool THIS::ExistsTransition(Idx x1, Idx ev) const{
2070  return BASE::ExistsTransition(x1, ev);
2071 }
2072 
2073 // ExistsTransition(x1)
2074 TEMP bool THIS::ExistsTransition(Idx x1) const{
2075  return BASE::ExistsTransition(x1);
2076 }
2077 
2078 //ExistsTransition(x1,ev,x2,pop,push)
2079 TEMP bool THIS::ExistsTransition(Idx x1, Idx ev, Idx x2, const std::vector<Idx>& pop, const std::vector<Idx>& push) const{
2080  return THIS::ExistsTransition(Transition(x1, ev, x2),pop,push);
2081 }
2082 
2083 //ExistsTransition(x1,ev,x2,pop,push)
2084 TEMP bool THIS::ExistsTransition(Idx x1, Idx ev, Idx x2, const std::vector<std::string>& pop, const std::vector<std::string>& push) const{
2085  return THIS::ExistsTransition(Transition(x1, ev, x2),pop,push);
2086 }
2087 
2088 //ExistsTransition(x1,ev,x2,rPop,rPush)
2089 TEMP bool THIS::ExistsTransition(Idx x1, Idx ev, Idx x2, const std::vector<StackSymbol>& rPop, const std::vector<StackSymbol>& rPush)const{
2090  return ExistsTransition(Transition(x1,ev,x2),rPop,rPush);
2091 }
2092 
2093 //ExistsTransition(x1,ev,x2,pop,push)
2094 TEMP bool THIS::ExistsTransition(const std::string& x1, const std::string& ev, const std::string& x2, const std::vector<StackSymbol>& pop, const std::vector<StackSymbol>& push) const{
2095  return THIS::ExistsTransition(Transition(BASE::StateIndex(x1), BASE::EventIndex(ev), BASE::StateIndex(x2)),pop,push);
2096 }
2097 
2098 //ExistsTransition(x1,ev,x2,pop,push)
2099 TEMP bool THIS::ExistsTransition(const std::string& x1, const std::string& ev, const std::string& x2, const std::vector<std::string>& pop, const std::vector<std::string>& push) const{
2100  return THIS::ExistsTransition(Transition(BASE::StateIndex(x1), BASE::EventIndex(ev), BASE::StateIndex(x2)),pop,push);
2101 }
2102 
2103 //ExistsTransition(x1,ev,x2,pop,push)
2104 TEMP bool THIS::ExistsTransition(const std::string& x1, const std::string& ev, const std::string& x2, const std::vector<Idx>& pop, const std::vector<Idx>& push) const{
2105  return THIS::ExistsTransition(Transition(BASE::StateIndex(x1), BASE::EventIndex(ev), BASE::StateIndex(x2)),pop,push);
2106 }
2107 
2108 //ExistsTransition(rTrans,rPop,rPush)
2109 TEMP bool THIS::ExistsTransition(const Transition& rTrans, const std::vector<StackSymbol>& rPop,const std::vector<StackSymbol>& rPush)const{
2110  return ExistsTransition(rTrans,StackSymbolsToIndices(rPop),StackSymbolsToIndices(rPush));
2111 }
2112 
2113 //ExistsTransition(rTrans,rPop,rPush)
2114 TEMP bool THIS::ExistsTransition(const Transition& rTrans, const std::vector<std::string>& rPop, const std::vector<std::string>& rPush) const{
2115  return ExistsTransition(rTrans,StackSymbolNamesToIndices(rPop),StackSymbolNamesToIndices(rPush));
2116 }
2117 
2118 //ExistsTransition(rTrans,rPop,rPush)
2119 TEMP bool THIS::ExistsTransition(const Transition& rTrans, const std::vector<Idx>& rPop, const std::vector<Idx>& rPush) const{
2120  if(BASE::ExistsTransition(rTrans)){
2121  PopPushSet popPushSet = PopPush(rTrans);
2122 
2123  std::pair<std::vector<Idx>, std::vector<Idx> > popPushPair;
2124  popPushPair.first = rPop;
2125  popPushPair.second = rPush;
2126 
2127  return popPushSet.find(popPushPair) != popPushSet.end();
2128  }
2129 
2130  return false;
2131 }
2132 
2133 // ExistsTransition(rX1,rEv,rPop,rPush, rX2) (note: luabinding)
2134 TEMP bool THIS::ExistsTransition(const std::string& rX1, const std::string& rEv, const std::string& rPop,
2135  const std::string& rPush, const std::string& rX2)const{
2136 
2137  return ExistsTransition(rX1,rEv,rX2,ParseStackSymbolNames(rPop),ParseStackSymbolNames(rPush));
2138 }
2139 
2140 //PopPush(trans)
2141 TEMP const PopPushSet& THIS::PopPush(const Transition& rTrans) const{
2142 #ifdef FAUDES_CHECKED
2143  if(!BASE::ExistsTransition(rTrans)) {
2144  std::stringstream errstr;
2145  errstr << "transition " << BASE::TStr(rTrans) << " not found ";
2146  errstr << std::endl;
2147  throw Exception("PushdownGenerator::PopPush(trans)", errstr.str(), 200);
2148  }
2149 #endif
2150  return BASE::pTransRel->Attribute(rTrans).PopPush();
2151 }
2152 
2153 //PopPushBegin(trans)
2154 TEMP PopPushSet::const_iterator THIS::PopPushBegin(const Transition& rTrans) const {
2155  return BASE::pTransRel->Attribute(rTrans).PopPush().begin();
2156 }
2157 
2158 //PopPushEnd(trans)
2159 TEMP PopPushSet::const_iterator THIS::PopPushEnd(const Transition& rTrans) const {
2160  return BASE::pTransRel->Attribute(rTrans).PopPush().end();
2161 }
2162 
2163 //InsLambdaStackSymbol
2164 TEMP Idx THIS::InsLambdaStackSymbol(){
2165  if(ExistsStackSymbol(FAUDES_PD_LAMBDA))
2166  return StackSymbolIndex(FAUDES_PD_LAMBDA);
2167  else
2168  return InsStackSymbol(FAUDES_PD_LAMBDA);
2169 }
2170 
2171 //IsStackSymbolLambda(index)
2172 TEMP bool THIS::IsStackSymbolLambda(Idx index) const{
2173  if(StackSymbolName(index).compare(FAUDES_PD_LAMBDA) == 0)
2174  return true;
2175  else
2176  return false;
2177 }
2178 
2179 //IsEventLambda(index)
2180 TEMP bool THIS::IsEventLambda(Idx index) const{
2181  if(BASE::EventName(index).compare(FAUDES_PD_LAMBDA) == 0)
2182  return true;
2183  else
2184  return false;
2185 }
2186 
2187 
2188 // ConsistentStackSymbol(rStackSymbol)
2189 TEMP void THIS::ConsistentStackSymbol(const StackSymbol& rStackSymbol) const {
2190  FD_DG("PushdownGenerator(" << this << ")::ConsistentStackSymbol(rStackSymbol)");
2191  if(!StackSymbols().Exists(rStackSymbol.Symbol())) {
2192  std::stringstream errstr;
2193  errstr << "stack symbol table mismatch (symbol " << rStackSymbol.mSymbol << " does not exist)" << std::endl;
2194  throw Exception("PushdownGenerator::ConsistentStackSymbol", errstr.str(), 1001);
2195  }
2196  FD_DG("PushdownGenerator(" << this << ")::ConsistentStackSymbol(rStackSymbol): ok");
2197 }
2198 
2199 // ConsistentStackSymbol(Idx)
2200 TEMP void THIS::ConsistentStackSymbol(Idx idx) const {
2201  FD_DG("PushdownGenerator(" << this << ")::ConsistentStackSymbol(idx)");
2202  if(!StackSymbols().Exists(idx)) {
2203  std::stringstream errstr;
2204  errstr << "stack symbol table mismatch (symbol with idx " << idx << " does not exist)" << std::endl;
2205  throw Exception("PushdownGenerator::ConsistentStackSymbol", errstr.str(), 1001);
2206  }
2207  FD_DG("PushdownGenerator(" << this << ")::ConsistentStackSymbol(idx): ok");
2208 }
2209 
2210 // ConsistentVectorStackSymbol(vector)
2211 TEMP void THIS::ConsistentVectorStackSymbol(const std::vector<StackSymbol>& rVector) const {
2212  FD_DG("PushdownGenerator(" << this << ")::ConsistentVectorStackSymbol(rVector)");
2213  std::vector<StackSymbol>::const_iterator it;
2214  it = rVector.begin();
2215  for ( ; it < rVector.end(); it++){
2216  if(!StackSymbols().Exists(it->Symbol())) {
2217  std::stringstream errstr;
2218  errstr << "stack symbol table mismatch (symbol " << it->mSymbol << " does not exist)" <<std::endl;
2219  throw Exception("PushdownGenerator::ConsistentVectorStackSymbol", errstr.str(), 1001);
2220  }
2221  }
2222  FD_DG("PushdownGenerator(" << this << ")::ConsistentVectorStackSymbol(rVector): ok");
2223 }
2224 
2225 // ConsistentVectorStackSymbol(vector)
2226 TEMP void THIS::ConsistentVectorStackSymbol(const std::vector<Idx>& rVector) const {
2227  FD_DG("PushdownGenerator(" << this << ")::ConsistentVectorStackSymbol(rVector)");
2228  std::vector<Idx>::const_iterator it;
2229  it = rVector.begin();
2230  for ( ; it < rVector.end(); it++){
2231  if(!StackSymbols().Exists(*it)) {
2232  std::stringstream errstr;
2233  errstr << "stack symbol table mismatch (symbol with index " << *it << " does not exist)" <<std::endl;
2234  throw Exception("PushdownGenerator::ConsistentVectorStackSymbol", errstr.str(), 1001);
2235  }
2236  }
2237  FD_DG("PushdownGenerator(" << this << ")::ConsistentVectorStackSymbol(rVector): ok");
2238 }
2239 
2240 // EmptyVector(vector)
2241 TEMP void THIS::EmptyVectorPopPush(const std::vector<StackSymbol>& rVector) const {
2242  FD_DG("PushdownGenerator(" << this << ")::EmptyVector(rVector)");
2243  if(rVector.empty()) {
2244  std::stringstream errstr;
2245  errstr << "empty vector not allowed in pop or push" <<std::endl;
2246  throw Exception("PushdownGenerator::EmptyVector", errstr.str(), 1001);
2247  }
2248  FD_DG("PushdownGenerator(" << this << ")::EmptyVectorPopPush(rVector): ok");
2249 }
2250 
2251 // EmptyVector(vector)
2252 TEMP void THIS::EmptyVectorPopPush(const std::vector<Idx>& rVector) const {
2253  FD_DG("PushdownGenerator(" << this << ")::EmptyVector(rVector)");
2254  if(rVector.empty()) {
2255  std::stringstream errstr;
2256  errstr << "empty vector not allowed in pop or push" <<std::endl;
2257  throw Exception("PushdownGenerator::EmptyVector", errstr.str(), 1001);
2258  }
2259  FD_DG("PushdownGenerator(" << this << ")::EmptyVectorPopPush(rVector): ok");
2260 }
2261 
2262 
2263 //SetMerge(stateName,rMerge)
2264 TEMP void THIS::SetMerge(const std::string& stateName, MergeAbstract& rMerge){
2265  Idx index=BASE::StateIndex(stateName);
2266  BASE::pStates->Attributep(index)->SetMerge(&rMerge);
2267 }
2268 
2269 //SetMerge(index,rMerge)
2270 TEMP void THIS::SetMerge(Idx index, MergeAbstract& rMerge){
2271  BASE::pStates->Attributep(index)->SetMerge(&rMerge);
2272 }
2273 
2274 //Merge(index)
2275 TEMP const MergeAbstract* THIS::Merge(Idx index) const{
2276  return BASE::pStates->Attributep(index)->Merge();
2277 }
2278 
2279 //SetDfaState(stateName, dpaIndex)
2280 TEMP void THIS::SetDfaState(const std::string& stateName, Idx dfaIndex){
2281  Idx index=BASE::StateIndex(stateName);
2282  BASE::pStates->Attributep(index)->DfaState(dfaIndex);
2283 }
2284 
2285 //SetDfaState(index, dpaIndex)
2286 TEMP void THIS::SetDfaState(Idx index, Idx dfaIndex){
2287  BASE::pStates->Attributep(index)->DfaState(dfaIndex);
2288 }
2289 
2290 //DfaState(index)
2291 TEMP Idx THIS::DfaState(Idx index) const{
2292  return BASE::pStates->Attributep(index)->DfaState();
2293 }
2294 
2295 // Valid() TODO checks?
2296 TEMP bool THIS::Valid(void) const {
2297  FD_DV("PushdownGenerator(" << this << ")::Valid()");
2298  //call base
2299  if(!BASE::Valid()) return false;
2300  // check my names
2301 
2302  // check my clockset
2303 
2304  // check all clocksymboltables
2305 
2306  return true;
2307 }
2308 
2309 
2310 //DotWrite(rFileName, printInfo, lr)
2311 TEMP void THIS::DotWrite(const std::string& rFileName, bool printInfo, bool lr) const {
2312  FD_DG("TpdGenerator(" << this << ")::DotWrite(" << rFileName << ","<< printInfo << "," << lr << ")");
2313 
2314  BASE::SetMinStateIndexMap();
2315  StateSet::Iterator sit;
2316  EventSet::Iterator eit;
2317  StackSymbolSet stacksymbols = StackSymbols();
2318  StackSymbolSet::Iterator ssit;
2319  TransSet::Iterator tit;
2320  PopPushSet::iterator ppit;
2321  std::vector<Idx>::iterator pit;
2322 
2323  try {
2324  std::ofstream stream;
2325  stream.exceptions(std::ios::badbit|std::ios::failbit);
2326  stream.open(rFileName.c_str());
2327  stream << "// dot output generated by libFAUDES TpdGenerator" << std::endl;
2328  stream << "digraph \"" << BASE::Name() << "\" {";
2329  stream << std::endl;
2330 
2331  if(lr) stream << " rankdir=LR" << std::endl;
2332 
2333 
2334  std::string initState = "_", stackbottom = "_";
2335  if(BASE::ExistsState(BASE::InitState()))
2336  initState = StateStr(BASE::InitState());
2337  if(ExistsStackSymbol(StackBottom()))
2338  stackbottom = StackSymbolStr(StackBottom());
2339 
2340  if(printInfo){
2341  //"M = (Q, Sigma, Gamma, initState, stackBottom, Qm, delta)
2342  //Sigma = Sigma_c U Sigma_uc
2343  //Sigma_c = {...}
2344  //Sigma_uc = {...}
2345  //Gamma = {...}
2346  stream << " \"\" [shape = none " << std::endl;
2347  stream << " label = < " << std::endl;
2348 
2349  //"M = (Q, Sigma, Gamma, initState, stackBottom, Qm, delta)
2350  stream << " M=(Q, &Sigma; , &Gamma; , "<< initState <<" , "<< stackbottom <<", &delta;, Qm) <br align=\"LEFT\"/>" << std::endl;
2351  //Sigma = Sigma_c U Sigma_uc
2352  stream << " &Sigma; = &Sigma;c &cup; &Sigma;uc <br align=\"LEFT\"/>" << std::endl;
2353  std::stringstream ConEv,UnConEv;
2354  for(eit = BASE::AlphabetBegin(); eit != BASE::AlphabetEnd(); ++eit)
2355  if(BASE::Controllable(*eit)){
2356  if(!IsEventLambda(*eit))
2357  ConEv << " "<< EventStr(*eit) << ",";
2358  //else
2359  // ConEv << " "<< "&lambda;" << ",";
2360  }else{
2361  if(!IsEventLambda(*eit))
2362  UnConEv << " "<< EventStr(*eit) << ",";
2363  }
2364  //Sigma_c
2365  std::string evstr = ConEv.str();
2366  if(!evstr.empty()) evstr.resize(evstr.size()-1);
2367  stream << " &Sigma;c = {"<< evstr <<" } <br align=\"LEFT\"/>" << std::endl;
2368  //Sigma_uc
2369  evstr = UnConEv.str();
2370  if(!evstr.empty()) evstr.resize(evstr.size()-1);
2371  stream << " &Sigma;uc = {"<< evstr <<" } <br align=\"LEFT\"/>" << std::endl;
2372  //Gamma = {...}
2373  stream << " &Gamma; = { ";
2374  int countSymbols = 0;
2375  for(ssit = StackSymbolsBegin(); ssit != StackSymbolsEnd(); ++ssit){
2376  if(!IsStackSymbolLambda(*ssit)){
2377  if(countSymbols % 10 == 9){
2378  stream << "<br align=\"LEFT\"/>" << std::endl;
2379  stream << " ";
2380  }
2381  if(countSymbols != 0)
2382  stream << ", ";
2383  stream << StackSymbolStr(*ssit);
2384  countSymbols++;
2385  }
2386  }
2387  stream << " } <br align=\"LEFT\"/>" << std::endl;
2388  stream << " >];" << std::endl;
2389  stream << std::endl;
2390  }
2391  stream << " node [shape=circle];" << std::endl;
2392  stream << std::endl;
2393 
2394  //initial states
2395  stream << " // initial states" << std::endl;
2396  int i = 1;
2397  for (sit = BASE::InitStatesBegin(); sit != BASE::InitStatesEnd(); ++sit) {
2398  stream << " dot_dummyinit_" << i << " [shape=none, label=\"\", width=\"0.0\", height=\"0.0\" ];" << std::endl;
2399  stream << " dot_dummyinit_" << i << " -> \"" << StateStr(*sit) << "\";" << std::endl;
2400  i++;
2401  }
2402  stream << std::endl;
2403 
2404  //stackbottom
2405  stream << " // stackbottom" << std::endl;
2406  if(stackbottom != "")
2407  stream << " \"" << stackbottom << "\" [style=\"invis\", attr=\"stackbottom\"];" <<std::endl;
2408 
2409  stream << std::endl;
2410 
2411  //marked states
2412  stream << " // mstates" << std::endl;
2413  for (sit = BASE::MarkedStatesBegin(); sit != BASE::MarkedStatesEnd(); ++sit)
2414  stream << " \"" << StateStr(*sit) << "\" [shape=doublecircle];" << std::endl;
2415 
2416  stream << std::endl;
2417 
2418  //rest of stateset
2419  stream << " // rest of stateset" << std::endl;
2420  for (sit = BASE::StatesBegin(); sit != BASE::StatesEnd(); ++sit) {
2421  if (! (BASE::ExistsInitState(*sit) || BASE::ExistsMarkedState(*sit)) )
2422  stream << " \"" << StateStr(*sit) << "\";" << std::endl;
2423  }
2424  stream << std::endl;
2425 
2426  //events
2427  stream << " // events" << std::endl;
2428  for(eit = BASE::Alphabet().Begin(); eit != BASE::Alphabet().End(); ++eit) {
2429  if(!THIS::IsEventLambda(*eit)){
2430  //"e" [style="invis", attr="cOfA"];
2431  stream << " \"" <<EventStr(*eit) <<"\" [style=\"invis\", attr=\"";
2432  stream << (BASE::Controllable(*eit)? "C" : "c");
2433  stream << (BASE::Observable(*eit)? "O" : "o");
2434  stream << (BASE::Forcible(*eit)? "F" : "f");
2435  stream << (BASE::Highlevel(*eit)? "A" : "a");
2436  stream << "\"];" << std::endl;
2437  }
2438  }
2439  stream << std::endl;
2440 
2441  //transition
2442  stream << " // transition relation" << std::endl;
2443  for(tit = BASE::TransRelBegin(); tit != BASE::TransRelEnd(); ++tit) {
2444  std::string eventname;
2445  if(BASE::EventName(tit->Ev) == FAUDES_PD_LAMBDA)
2446  eventname = "&lambda;";
2447  else
2448  eventname = EventStr(tit->Ev);
2449 
2450  if(PopPush(*tit).empty()){
2451  stream << " \"" << StateStr(tit->X1) << "\" -> \"" << StateStr(tit->X2)
2452  << "\" [label=\"" << eventname << " \"];" << std::endl;
2453  }else
2454  for (ppit = PopPushBegin(*tit); ppit != PopPushEnd(*tit); ++ppit) {
2455  std::vector<Idx> vPop = (*ppit).first;
2456  std::vector<Idx> vPush = (*ppit).second;
2457 
2458  // "x1" -> "x2" [label="ev,[pop],[push]"]
2459  stream << " \"" << StateStr(tit->X1) << "\" -> \"" << StateStr(tit->X2)
2460  << "\" [label=\"" << eventname << ",";
2461 
2462  //[pop]
2463  stream << "[";
2464  for (pit = vPop.begin(); pit != vPop.end(); ++pit) {
2465  if(!IsStackSymbolLambda(*pit))
2466  stream << StackSymbolName(*pit); //stackSymbol;
2467  else
2468  stream << "&lambda;";
2469 
2470  if(pit+1 != vPop.end()) stream << ",";
2471  }
2472  stream << "]";
2473 
2474  //[push]
2475  stream << "[";
2476  for (pit = vPush.begin(); pit != vPush.end(); ++pit) {
2477  if(!IsStackSymbolLambda(*pit))
2478  stream << StackSymbolName(*pit); //stackSymbol;
2479  else
2480  stream << "&lambda;";
2481 
2482  if(pit+1 != vPush.end()) stream << ",";
2483  }
2484  stream << "]\"";
2485 
2486  // if uncontrollable event transition
2487  // "x1" -> "x2" [label="ev,[pop],[push]" style ="dashed"]
2488  if(!BASE::Controllable(tit->Ev))
2489  stream << " style=\"dashed\"";
2490 
2491  stream << " ];" << std::endl;
2492  }
2493  }
2494  stream << "}" << std::endl;
2495  stream.close();
2496  }
2497  catch (std::ios::failure&) {
2498  throw Exception("vGenerator::DotWrite",
2499  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
2500  }
2501 }
2502 
2503 //DotWrite(rFileName)
2504 TEMP void THIS::DotWrite(const std::string& rFileName) const {
2505  FD_DG("TpdGenerator(" << this << ")::DotWrite(" << rFileName << ")");
2506  DotWrite(rFileName,true,true);
2507 }
2508 
2509 //CreatPdFromDot(rFileName) in pd_parseDot_pd.h
2510 TEMP void CreatPdFromDot(const std::string& rFileName,THIS& pd);
2511 
2512 //DotRead(rFileName)
2513 TEMP void THIS::DotRead(const std::string& rFileName) {
2514  FD_DG("TpdGenerator(" << this << ")::DotRead(" << rFileName << ")");
2515  this->Clear();
2516  try{
2517  CreatPdFromDot(rFileName,*this);
2518  }catch(...){
2519  std::stringstream errstr;
2520  errstr << "Unable to parse "<< rFileName << std::endl;
2521  throw Exception("TpdGenerator::DotRead", errstr.str(), 200);
2522  }
2523 }
2524 
2525 
2526 // clean up defs
2527 #undef THIS
2528 #undef BASE
2529 #undef TEMP
2530 
2531 
2532 } // namespace faudes
2533 
2534 //include "pd_dotparser.h" here because of dependencies to TpdGenerator class
2535 #include "pd_dotparser.h"
2536 
2537 #endif
2538 

libFAUDES 2.28c --- 2016.09.30 --- c++ api documentaion by doxygen