cfl_generator.cpp
Go to the documentation of this file.
1 /** @file cfl_generator.cpp Class vGenerator */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Bernd Opitz
6  Copyright (C) 2007, 2010, 2025 Thomas Moor
7  Exclusive copyright is granted to Klaus Schmidt
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 
24 #include "cfl_generator.h"
25 #include <stack>
26 
27 //local debug
28 //#undef FD_DG
29 //#define FD_DG(m) FD_WARN(m)
30 
31 namespace faudes {
32 
33 
34 // msObjectCount (static)
36 
37 // State names default (static)
39 
40 // Reindex default (static)
42 
43 
44 // static default prototypes (construct on first use design pattern)
46  static EventSet fls;
47  return fls;
48 }
50  static StateSet fls;
51  return fls;
52 }
54  static TransSet fls;
55  return fls;
56 }
58  static AttributeVoid fls;
59  return fls;
60 }
61 
62 
63 
64 
65 // constructor
67  // base
68  ExtType(),
69  // have std symboltables
70  mpStateSymbolTable(&mStateSymbolTable),
71  mpEventSymbolTable(GlobalEventSymbolTablep()),
72  // other members
73  mStateNamesEnabled(msStateNamesEnabledDefault),
74  mReindexOnWrite(msReindexOnWriteDefault),
75  // initialise heap members
76  mpAlphabet(0),
77  mpStates(0),
78  mpTransRel(0),
79  mpGlobalAttribute(0),
80  // initialise prototypes
81  pAlphabetPrototype(&AlphabetVoid()),
82  pStatesPrototype(&StatesVoid()),
83  pTransRelPrototype(&TransRelVoid()),
84  pGlobalPrototype(&GlobalVoid())
85 {
86  FAUDES_OBJCOUNT_INC("Generator");
87  FD_DG("vGenerator(" << this << ")::vGenerator()");
88  // track generator objects
89  msObjectCount++;
91  // overwrite base defaults
92  mObjectName="Generator",
93  // allocate core members
94  NewCore();
95  // fix std names
96  mInitStates.Name("InitStates");
97  mMarkedStates.Name("MarkedStates");
98 }
99 
100 // copy constructor
102  // base
103  ExtType(),
104  // have std symboltables
105  mpStateSymbolTable(&mStateSymbolTable),
106  mpEventSymbolTable(GlobalEventSymbolTablep()),
107  // other members
108  mStateNamesEnabled(msStateNamesEnabledDefault),
109  mReindexOnWrite(msReindexOnWriteDefault),
110  // initialise heap members
111  mpAlphabet(0),
112  mpStates(0),
113  mpTransRel(0),
114  mpGlobalAttribute(0),
115  // initialise prototypes
116  pAlphabetPrototype(&AlphabetVoid()),
117  pStatesPrototype(&StatesVoid()),
118  pTransRelPrototype(&TransRelVoid()),
119  pGlobalPrototype(&GlobalVoid())
120 {
121  FAUDES_OBJCOUNT_INC("Generator");
122  FD_DG("vGenerator(" << this << ")::vGenerator(" << &rOtherGen << ")");
123  // track generator objects
124  msObjectCount++;
125  mId = msObjectCount;
126  // overwrite base defaults
127  mObjectName="Generator",
128  // allocate core members
129  NewCore();
130  // perform copy
131  DoAssign(rOtherGen);
132 }
133 
134 // construct from file
135 vGenerator::vGenerator(const std::string& rFileName) :
136  // base
137  ExtType(),
138  // have std symboltables
139  mpStateSymbolTable(&mStateSymbolTable),
140  mpEventSymbolTable(GlobalEventSymbolTablep()),
141  // other members
142  mStateNamesEnabled(msStateNamesEnabledDefault),
143  mReindexOnWrite(msReindexOnWriteDefault),
144  // initialise heap members
145  mpAlphabet(0),
146  mpStates(0),
147  mpTransRel(0),
148  mpGlobalAttribute(0),
149  // initialise prototypes
150  pAlphabetPrototype(&AlphabetVoid()),
151  pStatesPrototype(&StatesVoid()),
152  pTransRelPrototype(&TransRelVoid()),
153  pGlobalPrototype(&GlobalVoid())
154 {
155  FAUDES_OBJCOUNT_INC("Generator");
156  FD_DG("vGenerator(" << this << ")::vGenerator(" << rFileName << ")");
157  // track generator objects
158  msObjectCount++;
159  mId = msObjectCount;
160  // overwrite base defaults
161  mObjectName="Generator",
162  // allocate core members
163  NewCore();
164  // fix std names
165  mInitStates.Name("InitStates");
166  mMarkedStates.Name("MarkedStates");
167  // set defaults for file io
168  mStateNamesEnabled=true;
169  // do read
170  Read(rFileName,"Generator");
171  // restore defaults
173 }
174 
175 // construct on heap
177  FD_DG("vGenerator(" << this << ")::New()");
178  // allocate
179  vGenerator* res = new vGenerator();
180  // fix configuration
184  return res;
185 }
186 
187 // construct on heap
189  FD_DG("vGenerator(" << this << ")::Copy()");
190  // copy construct
191  vGenerator* res = new vGenerator(*this);
192  return res;
193 }
194 
195 // cast
196 const Type* vGenerator::Cast(const Type* pOther) const {
197  return dynamic_cast< const vGenerator* > (pOther);
198 }
199 
200 
201 // destruct
203  FAUDES_OBJCOUNT_DEC("Generator");
204  // free my members
205  DeleteCore();
206 }
207 
208 // configure attribute types
209 void vGenerator::ConfigureAttributeTypes(const AttributeVoid* pNewGlobalPrototype,
210  const StateSet* pNewStatesPrototype, const EventSet* pNewAlphabetPrototype,
211  const TransSet* pNewTransRelPrototype) {
212  FD_DG("vGenerator(" << this << ")::ConfigureAtributes(..)");
213  pGlobalPrototype= pNewGlobalPrototype;
214  pStatesPrototype= pNewStatesPrototype;
215  pAlphabetPrototype= pNewAlphabetPrototype;
216  pTransRelPrototype= pNewTransRelPrototype;
217  FD_DG("vGenerator(" << this << ")::ConfigureAtributes(): done");
218 }
219 
220 // indicate new core
222  // fix std names
223  if(mpAlphabet) mpAlphabet->Name("Alphabet");
224  if(mpStates) mpStates->Name("States");
225  if(mpTransRel) mpTransRel->Name("TransRel");
226  // fix symbol table
228 }
229 
230 // protected helper: allocate core on heap
232  DeleteCore();
233  // allocate (use prototypes, fallback to void attributes)
235  else mpAlphabet = new EventSet();
237  else mpStates = new StateSet();
239  else mpTransRel = new TransSet();
241  else mpGlobalAttribute = new AttributeVoid();
242  // update callback
243  UpdateCore();
244 }
245 
246 // protected helper: free core from heap
248  if(mpAlphabet) delete mpAlphabet;
249  if(mpStates) delete mpStates;
250  if(mpTransRel) delete mpTransRel;
252  mpAlphabet=0;
253  mpStates=0;
254  mpTransRel=0;
256  // update callback
257  UpdateCore();
258 }
259 
260 
261 
262 // copy from other vGenerator (try to convert attributes)
263 void vGenerator::DoAssign(const vGenerator& rGen) {
264  FD_DG("vGenerator(" << this << ")::DoAssign(" << &rGen << ")");
265  // bail out on match
266  if(&rGen==this) return;
267  // prepare result (call clear for virtual stuff)
268  Clear();
269  // have same event symboltable
271  // copy state symboltable
273  // set other members
274  Name(rGen.Name());
279  // core members, try attributes
280  InjectStates(*rGen.mpStates);
281  InjectAlphabet(*rGen.mpAlphabet);
282  InjectTransRel(*rGen.mpTransRel);
284 #ifdef FAUDES_DEBUG_CODE
285  if(!Valid()) {
286  FD_DG("vGenerator()::Copy(): invalid generator");
287  DWrite();
288  abort();
289  }
290 #endif
291  FD_DG("vGenerator(" << this << ")::DoAssign(" << &rGen << "): done");
292 }
293 
294 // copy from other vGenerator (try to convert attributes)
296  FD_DG("vGenerator(" << this << ")::Assign([type] " << &rSrc << ")");
297  // bail out on match
298  if(&rSrc==this) return *this;
299  // run DoAssign if object casts to a generator
300  const vGenerator* vgen=dynamic_cast<const vGenerator*>(&rSrc);
301  if(vgen) {
302  DoAssign(*vgen);
303  return *this;
304  }
305  // clear to default
306  Clear();
307  return *this;
308 }
309 
310 // copy from other vGenerator (clear attributes)
312  FD_DG("vGenerator(" << this << ")::Assign(" << &rGen << ")");
313  // prepare result (call clear for virtual stuff)
314  Clear();
315  // have same event symboltable
317  // copy state symboltable
319  // set other members
320  Name(rGen.Name());
325  // core members, ignore attributes
329 #ifdef FAUDES_DEBUG_CODE
330  if(!Valid()) {
331  FD_DG("vGenerator()::Copy(): invalid generator");
332  DWrite();
333  abort();
334  }
335 #endif
336  return *this;
337 }
338 
339 
340 // Move(gen) destructive copy
342  FD_DG("vGenerator(" << this << ")::Move(" << &rGen << ")");
343  // test types
344  bool tmm=false;
345  const Type* pt;
346  const Type* opt;
347  pt=&Alphabet();
348  opt=&rGen.Alphabet();
349  if(typeid(*pt)!=typeid(*opt)) tmm=true;
350  pt=&States();
351  opt=&rGen.States();
352  if(typeid(*pt)!=typeid(*opt)) tmm=true;
353  pt=&TransRel();
354  opt=&rGen.TransRel();
355  if(typeid(*pt)!=typeid(*opt)) tmm=true;
356  pt=&GlobalAttribute();
357  opt=&rGen.GlobalAttribute();
358  if(typeid(*pt)!=typeid(*opt)) tmm=true;
359  // use copy on mismatch to convert
360  if(tmm) {
361  FD_DG("vGenerator(" << this << ")::Move(" << &rGen << "): using std copy");
362  rGen.DoAssign(*this);
363  Clear();
364  return;
365  }
366  // prepare result (call clear for virtual stuff)
367  rGen.Clear();
368  // have same event symboltable
370  // copy state symboltable (todo: make this pointer based?)
372  // copy members
373  rGen.Name(Name());
378  // delete destination core
379  if(rGen.mpStates) delete rGen.mpStates;
380  if(rGen.mpAlphabet) delete rGen.mpAlphabet;
381  if(rGen.mpTransRel) delete rGen.mpTransRel;
382  if(rGen.mpGlobalAttribute) delete rGen.mpGlobalAttribute;
383  // move and invalidate core members
384  rGen.mpStates=mpStates;
385  rGen.mpAlphabet=mpAlphabet;
386  rGen.mpTransRel=mpTransRel;
388  mpStates=0;
389  mpAlphabet=0;
390  mpTransRel=0;
392  // register core update
393  rGen.UpdateCore();
394  // install new empty core members
395  NewCore();
396  // clear myself (incl derived classes members)
397  Clear();
398 }
399 
400 // operator =
402  FD_DG("vGenerator(" << this << ")::operator = " << &rOtherGen);
403  FD_DG("vGenerator(" << this << ")::operator = types " << typeid(*this).name() << " <= " << typeid(rOtherGen).name());
404  return Assign(rOtherGen);
405 }
406 
407 // Version(idx)
408 void vGenerator::Version(Idx version, vGenerator& rResGen) const {
409  FD_DG("vGenerator(" << this << ")::Version(" << version << ")");
410  std::ostringstream o;
411  o << version;
412  Version(o.str(),rResGen);
413 }
414 
415 // Version(string)
416 void vGenerator::Version(const std::string& rVersion, vGenerator& rResGen) const {
417  FD_DG("vGenerator(" << this << ")::Version(" << rVersion << ")");
418  // second arg must not be us
419  if(this==&rResGen) {
420  std::stringstream errstr;
421  errstr << "Destination must not match source.";
422  throw Exception("vGenerator::Version(string)", errstr.str(), 96);
423  }
424  // prepare Empty generator
425  rResGen.Clear();
426  rResGen.GlobalAttribute(GlobalAttribute());
427  EventSet::Iterator eit;
428  StateSet::Iterator lit;
429  TransSet::Iterator tit;
430  std::map<Idx,Idx> eventoldnewmap;
431  rResGen.Name(Name()+"_"+rVersion);
432  // create versioned mAlphabet
433  for (eit = AlphabetBegin(); eit != AlphabetEnd(); ++eit) {
434  Idx newevent= rResGen.InsEvent(EventName(*eit)+"_"+rVersion);
435  eventoldnewmap[*eit] = newevent;
436  rResGen.EventAttribute(newevent,EventAttribute(*eit));
437  }
438  // create new stateset
439  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
440  rResGen.InsState(*lit);
441  rResGen.StateAttribute(*lit,StateAttribute(*lit)); //would be faster if directly copied ?
442  if (StateName(*lit) != "") rResGen.StateName(*lit,StateName(*lit));
443  }
444  // created versioned transrel
445  for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
446  Transition trans=Transition(tit->X1, eventoldnewmap[tit->Ev], tit->X2);
447  rResGen.SetTransition(trans);
448  rResGen.TransAttribute(trans, TransAttribute(*tit));
449  }
450  // set i/m states
451  rResGen.mInitStates=mInitStates;
453  // behavioural flags
456 }
457 
458 
459 // Version(string,string)
460 void vGenerator::Version(const std::string& rPattern, const std::string& rReplacement, vGenerator& rResGen) const {
461  FD_DG("vGenerator(" << this << ")::Version(" << rPattern << ", " << rReplacement << ", ...)");
462  // second arg must not be us
463  if(this==&rResGen) {
464  std::stringstream errstr;
465  errstr << "Destination must not match source.";
466  throw Exception("vGenerator::Version(string,string)", errstr.str(), 96);
467  }
468  // ignore invalid pattern
469  if(rPattern.empty()) {
470  rResGen.Assign(*this);
471  return;
472  }
473  // trivial case
474  if(rPattern==rReplacement) {
475  rResGen.Assign(*this);
476  return;
477  }
478  // prepare Empty generator
479  rResGen.Clear();
480  rResGen.GlobalAttribute(GlobalAttribute());
481  rResGen.Name(Name()+"_v");
482  EventSet::Iterator eit;
483  StateSet::Iterator lit;
484  TransSet::Iterator tit;
485  std::map<Idx,Idx> eventoldnewmap;
486  // create versioned mAlphabet
487  std::string newstring;
488  std::string::size_type pos = 0;
489  int patternlength=rPattern.size();
490  int replacementlength=rReplacement.size();
491  for (eit = AlphabetBegin(); eit != AlphabetEnd(); ++eit) {
492  // search for all pattern occurences in event name and replace
493  newstring=EventName(*eit);
494  pos=0;
495  while( (pos = newstring.find(rPattern, pos)) != std::string::npos ) {
496  newstring.replace(pos, patternlength, rReplacement);
497  //pos++;
498  pos=pos+replacementlength;
499  }
500  Idx newevent= rResGen.InsEvent(newstring);
501  eventoldnewmap[*eit] = newevent;
502  rResGen.EventAttribute(newevent,EventAttribute(*eit));
503  }
504  // have a nice neme too
505  newstring=Name();
506  pos=0;
507  while( (pos = newstring.find(rPattern, pos)) != std::string::npos ) {
508  newstring.replace(pos, patternlength, rReplacement);
509  pos=pos+replacementlength;
510  }
511  rResGen.Name(newstring);
512  // create new stateset
513  for(lit = StatesBegin(); lit != StatesEnd(); ++lit) {
514  rResGen.InsState(*lit);
515  rResGen.StateAttribute(*lit,StateAttribute(*lit)); //would be faster if directly copied ?
516  if(StateName(*lit) != "") rResGen.StateName(*lit,StateName(*lit));
517  }
518  // created versioned transrel
519  for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
520  Transition trans=Transition(tit->X1, eventoldnewmap[tit->Ev], tit->X2);
521  rResGen.SetTransition(trans);
522  rResGen.TransAttribute(trans, TransAttribute(*tit));
523  }
524  // set i/m states
525  rResGen.mInitStates=mInitStates;
527  // behavioural flags
530 }
531 
532 
533 // Valid()
534 bool vGenerator::Valid(void) const {
535  FD_DG("vGenerator(" << this << ")::Valid()");
536  // core members on heap
537  if(mpAlphabet==0) return false;
538  if(mpStates==0) return false;
539  if(mpTransRel==0) return false;
540  if(mpGlobalAttribute==0) return false;
541  // transitions to be known
542  TransSet::Iterator tit;
543  StateSet::Iterator lit;
544  for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
545  if(! ExistsState(tit->X1)) return false;
546  if(! ExistsEvent(tit->Ev)) return false;
547  if(! ExistsState(tit->X2)) return false;
548  }
549  // init states to be known
550  for(lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit)
551  if(! ExistsState(static_cast<Idx>(*lit))) return false;
552  for(lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit)
553  if(! ExistsState(static_cast<Idx>(*lit))) return false;
554  // sets to have proper names
555  if(mpAlphabet->Name() != "Alphabet") return false;
556  if(mpStates->Name() != "States") return false;
557  if(mInitStates.Name() != "InitStates") return false;
558  if(mMarkedStates.Name() != "MarkedStates") return false;
559  // event symbol table
560  NameSet::Iterator eit;
561  for(eit = AlphabetBegin(); eit != AlphabetEnd(); eit ++) {
562  if(EventName(*eit)=="") return false;
563  }
564  // done
565  return true;
566 }
567 
568 // AlphabetSize()
570  return mpAlphabet->Size();
571 }
572 
573 // Size()
574 Idx vGenerator::Size(void) const {
575  return mpStates->Size();
576 }
577 
578 // Clear()
579 void vGenerator::Clear(void) {
580  FD_DG("vGenerator(" << this << ")::Clear()");
581  mpAlphabet->Clear();
582  mpStates->Clear();
584  mpTransRel->Clear();
585  mInitStates.Clear();
588  FD_DG("vGenerator(" << this << ")::Clear(): done");
589 }
590 
591 // ClearGlobalAttribute()
594 }
595 
596 // ClearStateAttributes()
599 }
600 
601 // ClearEventAttributes()
604 }
605 
606 // ClearTransAttributes()
609 }
610 
611 // ClearAttributes()
617 }
618 
619 
620 // ClearStates()
622  mpStates->Clear();
623  mpTransRel->Clear();
624  mInitStates.Clear();
627 }
628 
629 // TransRelSize()
631  return mpTransRel->Size();
632 }
633 
634 // InitStatesSize()
636  return mInitStates.Size();
637 }
638 
639 // MarkedStatesSize()
641  return mMarkedStates.Size();
642 }
643 
644 // AlphabetEmpty()
645 bool vGenerator::AlphabetEmpty(void) const {
646  return mpAlphabet->Empty();
647 }
648 
649 // Empty()
650 bool vGenerator::Empty(void) const {
651  return mpStates->Empty();
652 }
653 
654 // TransRelEmpty()
655 bool vGenerator::TransRelEmpty(void) const {
656  return mpTransRel->Empty();
657 }
658 
659 // InitStatesEmpty()
660 bool vGenerator::InitStatesEmpty(void) const {
661  return mInitStates.Empty();
662 }
663 
664 // MarkedStatesEmpty()
666  return mMarkedStates.Empty();
667 }
668 
669 
670 // ClearMinStateIndexMap()
672  FD_DG("vGenerator::ClearMinStateIndexMap()");
673  // fake const
674  vGenerator* fakeconst = const_cast<vGenerator*>(this);
675  fakeconst->mMinStateIndexMap.clear();
676 }
677 
678 // MinStateIndexMap()
679 const std::map<Idx,Idx>& vGenerator::MinStateIndexMap(void) const {
680  return mMinStateIndexMap;
681 }
682 
683 
684 // SetMinStateIndexMap()
686  FD_DG("vGenerator::SetMinStateIndexMap()");
687  // fake const
688  vGenerator* fakeconst = const_cast<vGenerator*>(this);
689  // clear map
690  fakeconst->ClearMinStateIndexMap();
691  StateSet::Iterator it;
692  Idx minindex = 0;
693  // if generator states get names
694  if(StateNamesEnabled()) {
695  // named initial states first
696  for(it = InitStatesBegin(); it != InitStatesEnd(); ++it) {
697  if(StateName(static_cast<Idx>(*it)) != "") {
698  fakeconst->mMinStateIndexMap[*it] = ++minindex;
699  }
700  }
701  // then all other named states
702  for(it = StatesBegin(); it != StatesEnd(); ++it) {
703  if(mMinStateIndexMap.count(*it) == 0) {
704  if(StateName(static_cast<Idx>(*it)) != "") {
705  fakeconst->mMinStateIndexMap[*it] = ++minindex;
706  }
707  }
708  }
709  // at last all anonymous states
710  for(it = StatesBegin(); it != StatesEnd(); ++it) {
711  if(mMinStateIndexMap.count(*it) == 0) {
712  fakeconst->mMinStateIndexMap[*it] = ++minindex;
713  }
714  }
715  }
716  // if generator states are all anonymous
717  else {
718  // all initial states first
719  for(it = InitStatesBegin(); it != InitStatesEnd(); ++it) {
720  fakeconst->mMinStateIndexMap[*it] = ++minindex;
721  }
722  // then the rest
723  for(it = StatesBegin(); it != StatesEnd(); ++it) {
724  if(mMinStateIndexMap.count(*it) == 0) {
725  fakeconst->mMinStateIndexMap[*it] = ++minindex;
726  }
727  }
728  }
729 #ifdef FAUDES_DEBUG_CONTAINER
730  std::map<Idx,Idx>::const_iterator _it;
731  for(_it = mMinStateIndexMap.begin(); _it != mMinStateIndexMap.end(); ++_it) {
732  FD_DC("vGenerator::MinStateIndexMap: " << _it->first
733  << " <-- " << SStr(_it->second));
734  }
735 #endif
736 }
737 
738 
739 // MinStateIndex(index)
741  std::map<Idx,Idx>::const_iterator minit;
742  minit = mMinStateIndexMap.find(index);
743  if(minit != mMinStateIndexMap.end()) {
744  return minit->second;
745  }
746  return index;
747 }
748 
749 
750 // Max StateIndex
752  if(mpStates->Empty()) return 0;
753  return *(--(mpStates->End()));
754 }
755 
756 // Re-enumerate states to obtain a consecutive state set
758  // bail out on trivial
759  // if(MaxStateIndex()==Size()) return; tmoor 201206: dont bail out to be consistent with token IO
760  // prepare buffer and index map
761  vGenerator* dst = New();
762  dst->InsEvents(Alphabet());
764  // doit: states
765  StateSet::Iterator sit;
766  Idx s;
767  for(sit=StatesBegin(); sit!=StatesEnd(); ++sit) {
768  s=MinStateIndex(*sit);
769  dst->InsState(s);
770  dst->StateAttribute(s,StateAttribute(*sit));
771  if(StateNamesEnabled())
772  dst->StateName(s,StateName(*sit));
773  }
774  for(sit=InitStatesBegin(); sit!=InitStatesEnd(); ++sit) {
775  s=MinStateIndex(*sit);
776  dst->SetInitState(s);
777  }
778  for(sit=MarkedStatesBegin(); sit!=MarkedStatesEnd(); ++sit) {
779  s=MinStateIndex(*sit);
780  dst->SetMarkedState(s);
781  }
782  // doit: transitions
783  TransSet::Iterator tit;
784  for(tit=TransRelBegin(); tit!=TransRelEnd(); tit++) {
785  Transition dt(MinStateIndex(tit->X1),tit->Ev,MinStateIndex(tit->X2));
786  dst->SetTransition(dt);
787  dst->TransAttribute(dt,TransAttribute(*tit));
788  }
789  // move relevant core members
791  delete mpStates;
792  delete mpTransRel;
793  mpStates=dst->mpStates;
794  mpTransRel=dst->mpTransRel;
795  dst->mpStates=0;
796  dst->mpTransRel=0;
797  // move other members
798  mInitStates=dst->InitStates();
800  // update callback
801  UpdateCore();
802  // delete buffer
803  delete dst;
804  // invalidate map
806 }
807 
808 
809 // EventSymbolTablep() const
811  return mpEventSymbolTable;
812 }
813 
814 // GlobalEventSymbolTablep() const
817 }
818 
819 // EventSymbolTablep(pSymTab)
821  mpEventSymbolTable=pSymTab;
822  // todo: set symboltable in mpAlphabet
823 }
824 
825 // EventSymbolTablep(rOtherGen)
828 }
829 
830 // EventIndex(rName)
831 Idx vGenerator::EventIndex(const std::string& rName) const {
832  return mpEventSymbolTable->Index(rName);
833 }
834 
835 // EventName(index)
836 std::string vGenerator::EventName(Idx index) const {
837  return mpEventSymbolTable->Symbol(index);
838 }
839 
840 // EventName(index, name)
841 void vGenerator::EventName(Idx index, const std::string& rName) {
842  FD_DG("vGenerator(" << this << ")::EventName("
843  << index << ",\"" << rName << "\")");
844 #ifdef FAUDES_CHECKED
845  if (! ExistsEvent(index)) {
846  std::stringstream errstr;
847  errstr << "event \"" << index << "\" not found in generator \""
848  << Name() << "\"";
849  throw Exception("vGenerator::EventName(name)", errstr.str(), 89);
850  }
851 #endif
852  mpEventSymbolTable->SetEntry(index, rName);
853 }
854 
855 // UniqueEventName(rName)
856 std::string vGenerator::UniqueEventName(const std::string& rName) const {
857  std::string name=rName;
858  if(name=="") name="ev";
859  return mpEventSymbolTable->UniqueSymbol(name) ;
860 }
861 
862 
863 // EventRename
864 bool vGenerator::EventRename(Idx event, const std::string& rNewName) {
865  // consistency
866  FD_DG("vGenerator(" << this << ")::EventRename(" << EStr(event) << ", " << rNewName << ")");
867 #ifdef FAUDES_CHECKED
868  if (! ExistsEvent(event)) {
869  std::stringstream errstr;
870  errstr << "event \"" << event << "\" not found in generator \""
871  << Name() << "\"";
872  throw Exception("vGenerator::EventReame(name)", errstr.str(), 89);
873  }
874 #endif
875  // prepare formal result
876  bool res=ExistsEvent(rNewName);
877  // insert new event
878  Idx newidx=InsEvent(rNewName);
879  // bail out if events are the same
880  if(newidx==event) return true;
881  // copy event attribute
882  if(!res) EventAttribute(newidx,EventAttribute(event));
883  // store new transitions (with their attributes)
884  TransSet* newtrans= TransRel().New();
885  // iterate over transitions
887  while(tit != TransRelEnd()) {
888  if(tit->Ev!=event) {++tit; continue;}
889  Transition trans= Transition(tit->X1, newidx, tit->X2);
890  newtrans->Insert(trans);
891  newtrans->Attribute(trans,TransAttribute(*tit));
892  ClrTransition(tit++);
893  }
894  // merge transitions
895  for(tit=newtrans->Begin(); tit!=newtrans->End(); tit++) {
896  SetTransition(*tit);
897  TransAttribute(*tit,newtrans->Attribute(*tit));
898  }
899  // free temp
900  delete newtrans;
901  // remore original event
902  DelEvent(event);
903  // done
904  FD_DG("vGenerator(" << this << ")::EventRename(" << EStr(event) << ", " << rNewName << "):OK");
905  return res;
906 }
907 
908 // EventRename
909 bool vGenerator::EventRename(const std::string& rOldName, const std::string& rNewName) {
910  Idx oev = EventIndex(rOldName);
911  return EventRename(oev,rNewName);
912 }
913 
914 // NewEventSet()
916  EventSet res;
918  return res;
919 }
920 
921 // NewEventSetp()
923  EventSet* res = new EventSet();
925  return res;
926 }
927 
928 
929 // StateSymbolTable() const
931  return mStateSymbolTable;
932 }
933 
934 // StateSymbolTable(rSymTab)
936  mStateSymbolTable=rSymTab;
938 }
939 
940 // StateIndex(rName)
941 Idx vGenerator::StateIndex(const std::string& rName) const {
942  return mpStateSymbolTable->Index(rName);
943 }
944 
945 // StateName(index)
946 std::string vGenerator::StateName(Idx index) const {
947  return mpStateSymbolTable->Symbol(index);
948 }
949 
950 // StateName(index, name)
951 void vGenerator::StateName(Idx index, const std::string& rName) {
952  FD_DG("vGenerator(" << this << ")::StateName("
953  << index << ",\"" << rName << "\")");
954 #ifdef FAUDES_CHECKED
955  if (! ExistsState(index)) {
956  std::stringstream errstr;
957  errstr << "state name \"" << rName << "\" not found in generator \""
958  << Name() << "\"";
959  throw Exception("vGenerator::StateName(name)", errstr.str(), 90);
960  }
961 #endif
962  mpStateSymbolTable->SetEntry(index, rName);
963 }
964 
965 
966 // ClearStateNames()
968  FD_DG("vGenerator(" << this << ")::ClearStateNames()");
970 }
971 
972 
973 // ClrStateName(index)
975  FD_DG("Generator(" << this << ")::ClrStateName(\"" << index << "\")");
976 #ifdef FAUDES_CHECKED
977  if (! ExistsState(index)) {
978  std::stringstream errstr;
979  errstr << "state \"" << index << "\" not found in generator \""
980  << Name() << "\"";
981  throw Exception("vGenerator::ClrStateName(name)", errstr.str(), 90);
982  }
983 #endif
985 }
986 
987 // ClrStateName(rName)
988 void vGenerator::ClrStateName(const std::string& rName) {
989  FD_DG("vGenerator(" << this << ")::ClrStateName(\"" << rName << "\")");
990  Idx index = StateIndex(rName);
991  ClrStateName(index);
992 }
993 
994 
995 // StateNamesEnabled()
997  return mStateNamesEnabled;
998 }
999 
1000 // StateNamesEnabled(flag)
1002  mStateNamesEnabled = flag;
1003  if(!flag) ClearStateNames();
1004 }
1005 
1006 // StateNamesEnabled(flag)
1009 }
1010 
1011 // SetDefaultStateNames()
1013  FD_DG("vGenerator(" << this << ")::SetDefaultStateNames()");
1015  StateSet::Iterator it;
1016  for (it = StatesBegin(); it != StatesEnd(); ++it) {
1017  std::string dname;
1018  dname = std::string("S")+ToStringInteger(*it);
1019  mpStateSymbolTable->SetEntry(*it,dname);
1020  }
1021 }
1022 
1023 // EnforceStateNames(rTemplate)
1024 void vGenerator::EnforceStateNames(const std::string& rTemplate) {
1025  FD_DG("vGenerator(" << this << ")::EnforceStateNames(temp)");
1026  StateSet::Iterator it;
1027  for (it = StatesBegin(); it != StatesEnd(); ++it) {
1028  if(StateName(*it)=="") {
1029  std::string name=UniqueStateName(rTemplate + "_1");
1030  StateName(*it,name);
1031  }
1032  }
1033 }
1034 
1035 // UniqueStateName(rName)
1036 std::string vGenerator::UniqueStateName(const std::string& rName) const {
1037  std::string name=rName;
1038  if(name=="") name="st";
1039  return mpStateSymbolTable->UniqueSymbol(name) ;
1040 }
1041 
1042 
1043 // iterator AlphabetBegin() const
1044 EventSet::Iterator vGenerator::AlphabetBegin(void) const {
1045  return mpAlphabet->Begin();
1046 }
1047 
1048 // iterator AlphabetEnd() const
1049 EventSet::Iterator vGenerator::AlphabetEnd(void) const {
1050  return mpAlphabet->End();
1051 }
1052 
1053 // iterator StatesBegin() const
1054 StateSet::Iterator vGenerator::StatesBegin(void) const {
1055  return mpStates->Begin();
1056 }
1057 
1058 // iterator StatesEnd() const
1059 StateSet::Iterator vGenerator::StatesEnd(void) const {
1060  return mpStates->End();
1061 }
1062 
1063 // iterator TransRelBegin() const
1065  return mpTransRel->Begin();
1066 }
1067 
1068 // iterator TransRelEnd() const
1070  return mpTransRel->End();
1071 }
1072 
1073 // iterator TransRelBegin(x1) const
1075  return mpTransRel->Begin(x1);
1076 }
1077 
1078 // iterator TransRelEnd(x1) const
1080  return mpTransRel->End(x1);
1081 }
1082 
1083 // iterator TransRelBegin(x1, ev) const
1085  return mpTransRel->Begin(x1, ev);
1086 }
1087 
1088 // iterator TransRelEnd(x1, ev) const
1090  return mpTransRel->End(x1, ev);
1091 }
1092 
1093 // iterator FindTransition(trans)
1095  return mpTransRel->Find(rTrans);
1096 }
1097 
1098 // iterator FindTransition(x1, ex x2)
1100  return mpTransRel->Find(Transition(x1, ev, x2));
1101 }
1102 
1103 // iterator FindTransition(x1, ev, x2)
1105  const std::string& rX1, const std::string& rEv, const std::string& rX2) const
1106 {
1107  return mpTransRel->Find(StateIndex(rX1), EventIndex(rEv), StateIndex(rX2));
1108 }
1109 
1110 // iterator ExistsTransition(trans)
1111 bool vGenerator::ExistsTransition(const Transition& rTrans) const {
1112  return mpTransRel->Exists(rTrans);
1113 }
1114 
1115 // iterator ExistsTransition(x1, ex x2)
1116 bool vGenerator::ExistsTransition(Idx x1, Idx ev, Idx x2) const {
1117  return mpTransRel->Exists(Transition(x1, ev, x2));
1118 }
1119 
1120 // iterator ExistsTransition(x1, ev, x2)
1122  const std::string& rX1, const std::string& rEv, const std::string& rX2) const
1123 {
1124  return mpTransRel->Exists(StateIndex(rX1), EventIndex(rEv), StateIndex(rX2));
1125 }
1126 
1127 // iterator ExistsTransition(x1, ev)
1129  return mpTransRel->ExistsByX1Ev(x1, ev);
1130 }
1131 
1132 // iterator ExistsTransition(x1)
1134  return mpTransRel->ExistsByX1(x1);
1135 }
1136 
1137 
1138 // idx InitState() const
1140  if(mInitStates.Size()!=1) return 0;
1141  return *mInitStates.Begin();
1142 }
1143 
1144 
1145 
1146 // iterator InitStatesBegin() const
1147 StateSet::Iterator vGenerator::InitStatesBegin(void) const {
1148  return mInitStates.Begin();
1149 }
1150 
1151 // iterator InitStatesEnd() const
1152 StateSet::Iterator vGenerator::InitStatesEnd(void) const {
1153  return mInitStates.End();
1154 }
1155 
1156 // iterator MarkedStatesBegin()
1157 StateSet::Iterator vGenerator::MarkedStatesBegin(void) const {
1158  return mMarkedStates.Begin();
1159 }
1160 
1161 // iterator MarkedStatesEnd() const
1162 StateSet::Iterator vGenerator::MarkedStatesEnd(void) const {
1163  return mMarkedStates.End();
1164 }
1165 
1166 // InjectAlphabet(newalphabet)
1167 void vGenerator::InjectAlphabet(const EventSet& rNewAlphabet) {
1168  FD_DG("vGenerator::InjectAlphabet() " << rNewAlphabet.ToString());
1169 #ifdef FAUDES_CHECKED
1170  if(rNewAlphabet.SymbolTablep()!=mpEventSymbolTable) {
1171  std::stringstream errstr;
1172  errstr << "symboltable mismatch aka not implemented" << std::endl;
1173  throw Exception("vGenerator::InjectAlphabet", errstr.str(), 88);
1174  }
1175 #endif
1176  *mpAlphabet = rNewAlphabet;
1177  mpAlphabet->Name("Alphabet");
1178 }
1179 
1180 // RestrictAlphabet(newalphabet)
1181 void vGenerator::RestrictAlphabet(const EventSet& rNewAlphabet) {
1182  FD_DG("vGenerator::RestrictAlphabet() " << rNewAlphabet.ToString());
1183 #ifdef FAUDES_CHECKED
1184  if(rNewAlphabet.SymbolTablep()!=mpEventSymbolTable) {
1185  std::stringstream errstr;
1186  errstr << "symboltable mismatch aka not implemented" << std::endl;
1187  throw Exception("vGenerator::RestrictAlphabet", errstr.str(), 88);
1188  }
1189 #endif
1190  mpAlphabet->RestrictSet(rNewAlphabet);
1191  mpTransRel->RestrictEvents(rNewAlphabet);
1192 }
1193 
1194 // InsEvent(index)
1196  FD_DG("vGenerator(" << this << ")::InsEvent(" << index << ")");
1197  return mpAlphabet->Insert(index);
1198 }
1199 
1200 // InsEvent(rName)
1201 Idx vGenerator::InsEvent(const std::string& rName) {
1202  FD_DG("vGenerator(" << this << ")::InsEvent(\"" << rName << "\")");
1203  return mpAlphabet->Insert(rName);
1204 }
1205 
1206 // InsEvents(events)
1207 void vGenerator::InsEvents(const EventSet& events) {
1208  mpAlphabet->InsertSet(events);
1209 }
1210 
1211 // DelEvent(index)
1213  FD_DG("vGenerator(" << this << ")::DelEvent(" << index << ")");
1214  mpTransRel->EraseByEv(index);
1215  return mpAlphabet->Erase(index);
1216 }
1217 
1218 // DelEvent(rName)
1219 bool vGenerator::DelEvent(const std::string& rName) {
1220  FD_DG("vGenerator(" << this << ")::DelEvent(\"" << rName << "\")");
1221  Idx index = mpAlphabet->Index(rName);
1222  mpTransRel->EraseByEv(index);
1223  return mpAlphabet->Erase(index);
1224 }
1225 
1226 // DelEvents(events)
1227 void vGenerator::DelEvents(const EventSet& rEvents) {
1228  FD_DG("vGenerator(" << this << ")::DelEvents(\""
1229  << rEvents.ToString() << "\")");
1230  EventSet::Iterator it;
1231  for (it = rEvents.Begin(); it != rEvents.End(); ++it) {
1232  DelEvent(*it);
1233  }
1234 }
1235 
1236 // DelEventFromAlphabet(index)
1238  FD_DG("vGenerator(" << this << ")::DelEventFromAlphabet("
1239  << index << ")");
1240  return mpAlphabet->Erase(index);
1241 }
1242 
1243 // InsState()
1245  FD_DG("vGenerator(" << this << ")::InsState()");
1246  return mpStates->Insert();
1247 }
1248 
1249 // InsState(index)
1251  FD_DG("vGenerator(" << this << ")::InsState(" << index << ")");
1252  return mpStates->Insert(index);
1253 }
1254 
1255 // InsState(rName)
1256 Idx vGenerator::InsState(const std::string& rName) {
1257  FD_DG("vGenerator(" << this << ")::InsState(\"" << rName << "\")");
1258  Idx index=mpStates->Insert();
1259  StateName(index,rName);
1260  return index;
1261 }
1262 
1263 // InsStates(states)
1264 void vGenerator::InsStates(const StateSet& states) {
1265  mpStates->InsertSet(states);
1266 }
1267 
1268 // InjectState(index)
1270  FD_DG("vGenerator(" << this << ")::InjectState(\"" << SStr(index) << "\")");
1271  mpStates->Insert(index);
1272 }
1273 
1274 // InjectStates(rNewStates)
1275 void vGenerator::InjectStates(const StateSet& rNewStates) {
1276  FD_DG("vGenerator(" << this << ")::InjectStates(" << rNewStates.ToString() << ")");
1277  *mpStates=rNewStates;
1278  mpStates->Name("States");
1280  FD_DG("vGenerator(" << this << ")::InjectStates(): report " << mpStates->ToString());
1281 }
1282 
1283 // InsInitState()
1285  FD_DG("vGenerator(" << this << ")::InsInitState()");
1286  Idx index;
1287  index = InsState();
1288  mInitStates.Insert(index);
1289  return index;
1290 }
1291 
1292 // InsInitState(name)
1293 Idx vGenerator::InsInitState(const std::string& rName) {
1294  FD_DG("vGenerator(" << this << ")::InsInitState(\"" << rName << "\")");
1295  Idx index;
1296  index = InsState(rName);
1297  mInitStates.Insert(index);
1298  return index;
1299 }
1300 
1301 // InsInitState(name)
1303  bool res=InsState(index);
1304  mInitStates.Insert(index);
1305  return res;
1306 }
1307 
1308 // InsInitStates(states)
1310  mpStates->InsertSet(states);
1311  mInitStates.InsertSet(states);
1312 }
1313 
1314 // InsMarkedState()
1316  FD_DG("vGenerator(" << this << ")::InsMarkedState()");
1317  Idx index;
1318  index = InsState();
1319  mMarkedStates.Insert(index);
1320  return index;
1321 }
1322 
1323 // InsInitState(name)
1325  bool res=InsState(index);
1326  mMarkedStates.Insert(index);
1327  return res;
1328 }
1329 
1330 // InsMarkedState(rName)
1331 Idx vGenerator::InsMarkedState(const std::string& rName) {
1332  FD_DG("vGenerator(" << this << ")::InsMarkedState(\"" << rName << "\")");
1333  Idx index;
1334  index = InsState(rName);
1335  mMarkedStates.Insert(index);
1336  return index;
1337 }
1338 
1339 // InsMarkedStates(states)
1341  mpStates->InsertSet(states);
1342  mMarkedStates.InsertSet(states);
1343 }
1344 
1345 
1346 // DelState(index)
1348  FD_DG("vGenerator(" << this << ")::DelState(" << index << ")");
1349  // mInitStates
1350  mInitStates.Erase(index);
1351  // mstates
1352  mMarkedStates.Erase(index);
1353  // transrel
1354  mpTransRel->EraseByX1OrX2(index);
1355  // symbolic name
1356  mpStateSymbolTable->ClrEntry(index);
1357  // finally ... remove the state
1358  return mpStates->Erase(index);
1359 }
1360 
1361 // DelState(rName)
1362 bool vGenerator::DelState(const std::string& rName) {
1363  FD_DG("vGenerator(" << this << ")::DelState(\"" << rName << "\")");
1364  Idx index;
1365  index = StateIndex(rName);
1366 #ifdef FAUDES_CHECKED
1367  if (index == 0) {
1368  std::stringstream errstr;
1369  errstr << "state name \"" << rName << "\" not found in generator \""
1370  << Name() << "\"";
1371  throw Exception("vGenerator::DelState(name)", errstr.str(), 90);
1372  }
1373 #endif
1374  return DelState(index);
1375 }
1376 
1377 // DelStates(rDelStates)
1378 void vGenerator::DelStates(const StateSet& rDelStates) {
1379  FD_DG("vGenerator(" << this << ")::DelStates("
1380  << rDelStates.ToString() << ")");
1381  StateSet::Iterator cit;
1382  StateSet::Iterator cit_end;
1383  // symbolic state names
1384  for (cit = rDelStates.Begin(); cit != rDelStates.End(); ++cit) {
1386  }
1387  // statesets
1388  mpStates->EraseSet(rDelStates);
1389  mInitStates.EraseSet(rDelStates);
1390  mMarkedStates.EraseSet(rDelStates);
1391  // mpTransRel:
1392  mpTransRel->EraseByX1OrX2(rDelStates);
1393 }
1394 
1395 // DelStateFromStates(index)
1397  FD_DG("vGenerator(" << this << ")::DelStateFromStates(" << index << ")");
1398  // mStates + global
1399  return mpStates->Erase(index);
1400 }
1401 
1402 // DelStateFromStates(pos)
1403 StateSet::Iterator vGenerator::DelStateFromStates(StateSet::Iterator pos) {
1404  FD_DG("vGenerator(" << this << ")::DelState(" << *pos << ")");
1405  return mpStates->Erase(pos);
1406 }
1407 
1408 // RestrictStates(rStates)
1409 void vGenerator::RestrictStates(const StateSet& rStates) {
1410  FD_DG("vGenerator(" << this << ")::RestrictStates("
1411  << rStates.ToString() << ")");
1412 
1413  StateSet::Iterator cit;
1414  StateSet::Iterator cit_end;
1415  // symbolic state names
1416  for(cit = StatesBegin(); cit != StatesEnd(); ++cit) {
1417  if(!rStates.Exists(*cit)) mpStateSymbolTable->ClrEntry(*cit);
1418  }
1419  // statesets
1420  mpStates->RestrictSet(rStates);
1421  mInitStates.RestrictSet(rStates);
1422  mMarkedStates.RestrictSet(rStates);
1423  // mpTransRel:
1424  mpTransRel->RestrictStates(rStates);
1425 }
1426 
1427 
1428 // SetInitState(index)
1430  FD_DG("vGenerator(" << this << ")::SetInitState(" << index << ")");
1431 #ifdef FAUDES_CHECKED
1432  if (! mpStates->Exists(index)) {
1433  std::stringstream errstr;
1434  errstr << "vGenerator::SetMarkedState: index " << index
1435  << " not in stateset";
1436  throw Exception("vGenerator::SetInitState(..)", errstr.str(), 91);
1437  }
1438 #endif
1439  mInitStates.Insert(index);
1440 }
1441 
1442 // SetInitState(rName)
1443 void vGenerator::SetInitState(const std::string& rName) {
1444  FD_DG("vGenerator(" << this << ")::SetInitState(\"" << rName << "\")");
1445  Idx index = StateIndex(rName);
1446 #ifdef FAUDES_CHECKED
1447  if (index == 0) {
1448  std::stringstream errstr;
1449  errstr << "State name \"" << rName << "\" not known in Generator";
1450  throw Exception("vGenerator::SetInitState(..)", errstr.str(), 90);
1451  }
1452 #endif
1453  SetInitState(index);
1454 }
1455 
1456 // InjectInitStates(rNewInitStates)
1457 void vGenerator::InjectInitStates(const StateSet& rNewInitStates) {
1458  FD_DG("vGenerator(" << this << ")::InjectInitStates("
1459  << rNewInitStates.ToString() << ")");
1460  mInitStates = rNewInitStates;
1461  mInitStates.Name("InitStates");
1462 }
1463 
1464 // ClrInitState(index)
1466  FD_DG("vGenerator(" << this << ")::ClrInitState(" << index << ")");
1467 #ifdef FAUDES_CHECKED
1468  if (! mpStates->Exists(index)) {
1469  std::stringstream errstr;
1470  errstr << "vGenerator::SetMarkedState: index " << index
1471  << " not in stateset";
1472  throw Exception("vGenerator::ClrInitState(..)", errstr.str(), 91);
1473  }
1474 #endif
1475  mInitStates.Erase(index);
1476 }
1477 
1478 // ClrInitState(rName)
1479 void vGenerator::ClrInitState(const std::string& rName) {
1480  FD_DG("vGenerator(" << this << ")::ClrInitState(\"" << rName << "\")");
1481  Idx index = StateIndex(rName);
1482 #ifdef FAUDES_CHECKED
1483  if (index == 0) {
1484  std::stringstream errstr;
1485  errstr << "State name \"" << rName << "\" not known in Generator";
1486  throw Exception("vGenerator::ClrInitState(..)", errstr.str(), 90);
1487  }
1488 #endif
1489  ClrInitState(index);
1490 }
1491 
1492 // ClrInitState(pos)
1493 StateSet::Iterator vGenerator::ClrInitState(StateSet::Iterator pos) {
1494  FD_DG("vGenerator(" << this << ")::ClrInitState(" << *pos << ")");
1495  return mInitStates.Erase(pos);
1496 }
1497 
1498 // ClearInitStates()
1500  mInitStates.Clear();
1501 }
1502 
1503 // SetMarkedState(index)
1505  FD_DG("vGenerator(" << this << ")::SetMarkedState(" << index << ")");
1506 #ifdef FAUDES_CHECKED
1507  if (! mpStates->Exists(index)) {
1508  std::stringstream errstr;
1509  errstr << "vGenerator::SetMarkedState: index " << index
1510  << " not in stateset";
1511  throw Exception("vGenerator::SetMarkedState(..)", errstr.str(), 91);
1512  }
1513 #endif
1514  mMarkedStates.Insert(index);
1515 }
1516 
1517 // SetMarkedState(rName)
1518 void vGenerator::SetMarkedState(const std::string& rName) {
1519  FD_DG("vGenerator(" << this << ")::SetMarkedState(\"" << rName << "\")");
1520  Idx index = StateIndex(rName);
1521 #ifdef FAUDES_CHECKED
1522  if (index == 0) {
1523  std::stringstream errstr;
1524  errstr << "State name \"" << rName << "\" not known in Generator";
1525  throw Exception("vGenerator::SetMarkedState(..)", errstr.str(), 90);
1526  }
1527 #endif
1528  SetMarkedState(index);
1529 }
1530 
1531 // InjectMarkedStates(rNewMarkedStates)
1532 void vGenerator::InjectMarkedStates(const StateSet& rNewMarkedStates) {
1533  FD_DG("vGenerator(" << this << ")::InjectMarkedStates("
1534  << rNewMarkedStates.ToString() << ")");
1535  mMarkedStates = rNewMarkedStates;
1536  mMarkedStates.Name("MarkedStates");
1537 }
1538 
1539 // ClrMarkedState(index)
1541  FD_DG("vGenerator(" << this << ")::ClrMarkedState(" << index << ")");
1542 #ifdef FAUDES_CHECKED
1543  if (! mpStates->Exists(index)) {
1544  std::stringstream errstr;
1545  errstr << "vGenerator::ClrMarkedState: index " << index
1546  << " not in stateset";
1547  throw Exception("vGenerator::ClrMarkedState(..)", errstr.str(), 91);
1548  }
1549 #endif
1550  mMarkedStates.Erase(index);
1551 }
1552 
1553 // ClrMarkedState(rName)
1554 void vGenerator::ClrMarkedState(const std::string& rName) {
1555  FD_DG("vGenerator(" << this << ")::ClrMarkedState(\"" << rName << "\")");
1556  Idx index = StateIndex(rName);
1557 #ifdef FAUDES_CHECKED
1558  if (index == 0) {
1559  std::stringstream errstr;
1560  errstr << "State name \"" << rName << "\" not known in Generator";
1561  throw Exception("vGenerator::ClrMarkedState(..)", errstr.str(), 90);
1562  }
1563 #endif
1564  ClrMarkedState(index);
1565 }
1566 
1567 // ClrMarkedState(pos)
1568 StateSet::Iterator vGenerator::ClrMarkedState(StateSet::Iterator pos) {
1569  FD_DG("vGenerator(" << this << ")::ClrMarkedState(" << *pos << ")");
1570  return mMarkedStates.Erase(pos);
1571 }
1572 
1573 // ClearMarkedStates()
1575  mMarkedStates.Clear();
1576 }
1577 
1578 // InjectTransition(newtrans)
1580  FD_DG("vGenerator::InjectTransition(" << TStr(rTrans) << ")");
1581  mpTransRel->Inject(rTrans);
1582 }
1583 
1584 // InjectTransRel(newtransrel)
1585 void vGenerator::InjectTransRel(const TransSet& rNewTransrel) {
1586  FD_DG("vGenerator::InjectTransRel(...)");
1587  *mpTransRel=rNewTransrel;
1588  mpTransRel->Name("TransRel");
1589 }
1590 
1591 // SetTransition(rX1, rEv, rX2)
1592 bool vGenerator::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2) {
1593  FD_DG("vGenerator(" << this << ")::SetTransition(\""
1594  << rX1 << "\", \"" << rEv << "\", \"" << rX2 << "\")");
1595  Idx x1 = StateIndex(rX1);
1596  Idx x2 = StateIndex(rX2);
1597 #ifdef FAUDES_CHECKED
1598  if (x1 == 0) {
1599  FD_ERR("vGenerator::SetTransition: state " << rX1
1600  << " not in stateset");
1601  std::stringstream errstr;
1602  errstr << "State name " << rX1 << " not found in Generator";
1603  throw Exception("vGenerator::SetTransition(..)", errstr.str(), 90);
1604  }
1605  if (! mpAlphabet->Exists(rEv)) {
1606  FD_ERR("vGenerator::SetTransition: event " << rEv << " not in alphabet");
1607  std::stringstream errstr;
1608  errstr << "Event name " << rEv << " not found in event domain of Generator";
1609  throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
1610  }
1611  if (x2 == 0) {
1612  FD_ERR("vGenerator::SetTransition: state " << rX2 << " not in stateset");
1613  std::stringstream errstr;
1614  errstr << "State name " << rX2 << " not found in Generator";
1615  throw Exception("vGenerator::SetTransition(..)", errstr.str(), 90);
1616  }
1617 #endif
1618  return SetTransition(Transition(x1, EventIndex(rEv), x2));
1619 }
1620 
1621 
1622 // SetTransition(x1, ev, x2)
1624  return SetTransition(Transition(x1,ev,x2));
1625 }
1626 
1627 // SetTransition(rTransition)
1628 bool vGenerator::SetTransition(const Transition& rTransition) {
1629  FD_DG("vGenerator(" << this << ")::SetTransition(" << rTransition.X1 << ","
1630  << rTransition.Ev << "," << rTransition.X2 << ")");
1631 #ifdef FAUDES_CHECKED
1632  if (! mpStates->Exists(rTransition.X1)) {
1633  std::stringstream errstr;
1634  errstr << "vGenerator::SetTransition: state " << SStr(rTransition.X1)
1635  << " not in stateset";
1636  throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
1637  }
1638  if (! mpAlphabet->Exists(rTransition.Ev)) {
1639  std::stringstream errstr;
1640  errstr << "vGenerator::SetTransition: event " << EStr(rTransition.Ev)
1641  << " not in alphabet ";
1642  throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
1643  }
1644  if (! mpStates->Exists(rTransition.X2)) {
1645  std::stringstream errstr;
1646  errstr << "vGenerator::SetTransition: state " << SStr(rTransition.X2)
1647  << " not in stateset";
1648  throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
1649  }
1650 #endif
1651  return mpTransRel->Insert(rTransition);
1652 }
1653 
1654 
1655 
1656 // ClrTransition.X1, ev, x2)
1658  FD_DG("vGenerator(" << this << ")::ClrTransition("
1659  << x1 << "," << ev << "," << x2 << ")");
1660  mpTransRel->Erase(x1, ev, x2);
1661 }
1662 
1663 // ClrTransition(rTransition)
1664 void vGenerator::ClrTransition(const Transition& rTransition) {
1665  FD_DG("vGenerator(" << this << ")::ClrTransition(" << TStr(rTransition) << ")");
1666  mpTransRel->Erase(rTransition);
1667 }
1668 
1669 // ClrTransition(it)
1671  FD_DG("vGenerator(" << this << ")::ClrTransition(" << TStr(*it)<< ")" );
1672  return mpTransRel->Erase(it);
1673 }
1674 
1675 // ClrTransitions(X1, ev)
1677  FD_DG("vGenerator(" << this << ")::ClrTransition("
1678  << x1 << "," << ev << ")");
1679  mpTransRel->EraseByX1Ev(x1, ev);
1680 }
1681 
1682 // ClrTransitions(X1)
1684  FD_DG("vGenerator(" << this << ")::ClrTransition("
1685  << x1 << ")");
1686  mpTransRel->EraseByX1(x1);
1687 }
1688 
1689 // TransAttribute(trans, attr)
1690 void vGenerator::TransAttribute(const Transition& rTrans, const Type& rAttr) {
1691  FD_DG("vGenerator(" << this << ")::TransAttribute("
1692  << TStr(rTrans) << ",\"" << rAttr.ToString() << "\")");
1693  mpTransRel->Attribute(rTrans, rAttr);
1694 }
1695 
1696 // TransAttributep(trans)
1698  return mpTransRel->Attributep(rTrans);
1699 }
1700 
1701 
1702 // TransAttribute(trans)
1704  return mpTransRel->Attribute(rTrans);
1705 }
1706 
1707 // ClrTransAttribute(trans)
1709  mpTransRel->ClrAttribute(rTrans);
1710 }
1711 
1712 
1713 // ClearTransRel()
1715  mpTransRel->Clear();
1716 }
1717 
1718 // EventAttribute(index, attr)
1719 void vGenerator::EventAttribute(Idx index, const Type& rAttr) {
1720  FD_DG("vGenerator(" << this << ")::EventAttribute("
1721  << EStr(index) << ",\"" << rAttr.ToString() << "\")");
1722  mpAlphabet->Attribute(index, rAttr);
1723 }
1724 
1725 
1726 // EventAttributes(set)
1727 void vGenerator::EventAttributes(const EventSet& rEventSet) {
1728  FD_DG("vGenerator(" << this << ")::EventAttributes("
1729  << rEventSet.ToString() << "\")");
1730  mpAlphabet->Attributes(rEventSet);
1731 }
1732 
1733 // ClrEventAttribute(index)
1735  FD_DG("vGenerator(" << this << ")::ClrEventAttribute(\"" << EStr(index) << "\")");
1736  mpAlphabet->ClrAttribute(index);
1737 }
1738 
1739 // StateAttribute(index, attr)
1740 void vGenerator::StateAttribute(Idx index, const Type& rAttr) {
1741  FD_DG("vGenerator(" << this << ")::StateAttribute("
1742  << SStr(index) << ",\"" << rAttr.ToString() << "\")");
1743  mpStates->Attribute(index, rAttr);
1744 }
1745 
1746 // ClrStateAttribute(index)
1748  FD_DG("vGenerator(" << this << ")::ClrStateAttribute(\"" << index << "\")");
1749  mpStates->ClrAttribute(index);
1750 }
1751 
1752 // ExistsEvent(index)
1753 bool vGenerator::ExistsEvent(Idx index) const {
1754  return mpAlphabet->Exists(index);
1755 }
1756 
1757 // ExistsEvent(rName)
1758 bool vGenerator::ExistsEvent(const std::string& rName) const {
1759  return mpAlphabet->Exists(rName);
1760 }
1761 
1762 // FindEvent(index) const
1763 EventSet::Iterator vGenerator::FindEvent(Idx index) const {
1764  return mpAlphabet->Find(index);
1765 }
1766 
1767 // FindEvent(rName)
1768 EventSet::Iterator vGenerator::FindEvent(const std::string& rName) const {
1769  return mpAlphabet->Find(rName);
1770 }
1771 
1772 // ExistsState(index)
1773 bool vGenerator::ExistsState(Idx index) const {
1774  return mpStates->Exists(index);
1775 }
1776 
1777 // ExistsName(name)
1778 bool vGenerator::ExistsState(const std::string& rName) const {
1779  return ExistsState(StateIndex(rName));
1780 }
1781 
1782 // FindState(rName) const
1783 StateSet::Iterator vGenerator::FindState(const std::string& rName) const {
1784  return mpStates->Find(mpStateSymbolTable->Index(rName));
1785 }
1786 
1787 // FindState(index) const
1788 StateSet::Iterator vGenerator::FindState(Idx index) const {
1789  return mpStates->Find(index);
1790 }
1791 
1792 // ExistsInitState(index)
1794  return mInitStates.Exists(index);
1795 }
1796 
1797 // FindInitState(index)
1798 StateSet::Iterator vGenerator::FindInitState(Idx index) const {
1799  return mInitStates.Find(index);
1800 }
1801 
1802 // ExistsMarkedState(index)
1804  return mMarkedStates.Exists(index);
1805 }
1806 
1807 // FindMarkedState(index)
1808 StateSet::Iterator vGenerator::FindMarkedState(Idx index) const {
1809  return mMarkedStates.Find(index);
1810 }
1811 
1812 // EventAttribute(index)
1814  return mpAlphabet->Attribute(index);
1815 }
1816 
1817 // EventAttributep(index)
1819  return mpAlphabet->Attributep(index);
1820 }
1821 
1822 // EventAttribute(rName)
1823 const AttributeVoid& vGenerator::EventAttribute(const std::string& rName) const {
1824  return EventAttribute(EventIndex(rName));
1825 }
1826 
1827 // EventAttributep(rName)
1828 AttributeVoid* vGenerator::EventAttributep(const std::string& rName) {
1829  return EventAttributep(EventIndex(rName));
1830 }
1831 
1832 // StateAttribute(index)
1834  return mpStates->Attribute(index);
1835 }
1836 
1837 // StateAttributep(index)
1839  return mpStates->Attributep(index);
1840 }
1841 
1842 // GlobalAttribute(attr)
1843 void vGenerator::GlobalAttribute(const Type& rAttr) {
1844  FD_DG("vGenerator(" << this << ")::GlobalAttribute("
1845  << rAttr.ToString() << "\")");
1846  // set to void is ok for silient ignore
1847  if(typeid(rAttr)==typeid(AttributeVoid)) return;
1848  // error:
1849  std::stringstream errstr;
1850  errstr << "cannot cast global attribute " << rAttr.ToString() << " for generator " << Name();
1851  throw Exception("vGenerator::GlobalAttribute", errstr.str(), 63);
1852 }
1853 
1854 // GlobalAttributeTry(attr)
1856  FD_DG("vGenerator(" << this << ")::GlobalAttributeTry("
1857  << rAttr.ToString() << "\")");
1858  // ignore
1859 }
1860 
1861 // GlobalAttribute()
1863  FD_DG("vGenerator(" << this << ")::GlobalAttribute()");
1864  return *mpGlobalAttribute;
1865 }
1866 
1867 // GlobalAttributep()
1869  FD_DG("vGenerator(" << this << ")::GlobalAttributep()");
1870  return mpGlobalAttribute;
1871 }
1872 
1873 
1874 // Alphabet()
1875 const EventSet& vGenerator::Alphabet(void) const {
1876  return *mpAlphabet;
1877 }
1878 
1879 // States()
1880 const StateSet& vGenerator::States(void) const {
1881  return *mpStates;
1882 }
1883 
1884 // TransRel()
1885 const TransSet& vGenerator::TransRel(void) const {
1886  return *mpTransRel;
1887 }
1888 
1889 
1890 // TransRel(res)
1893 void vGenerator::TransRel(TransSetEvX2X1& res) const { mpTransRel->ReSort(res); }
1895 void vGenerator::TransRel(TransSetX2X1Ev& res) const { mpTransRel->ReSort(res); }
1896 void vGenerator::TransRel(TransSetX1X2Ev& res) const { mpTransRel->ReSort(res); }
1897 
1898 
1900  const std::string& rX1, const std::string& rEv, const std::string& rX2) const {
1901  return Transition(StateIndex(rX1),EventIndex(rEv),StateIndex(rX2));
1902 }
1903 
1904 // InitStates()
1905 const StateSet& vGenerator::InitStates(void) const {
1906  return mInitStates;
1907 }
1908 
1909 // MarkedStates()
1911  return mMarkedStates;
1912 }
1913 
1914 // MinimizeAlphabet()
1916  mpAlphabet->NameSet::EraseSet(UnusedEvents());
1917 }
1918 
1919 // UsedEvents()
1921  EventSet resultset = NewEventSet();
1922  TransSet::Iterator it;
1923  for (it = mpTransRel->Begin(); it != mpTransRel->End(); ++it) {
1924  resultset.Insert(it->Ev);
1925  }
1926  return resultset;
1927 }
1928 
1929 // UnusedEvents()
1931  return *mpAlphabet - UsedEvents();
1932 }
1933 
1934 // ActiveEventSet(x1)
1936  EventSet result = NewEventSet();
1937  TransSet::Iterator it;
1938  for (it = TransRelBegin(x1); it != TransRelEnd(x1); ++it) {
1939  result.Insert(it->Ev);
1940  }
1941  return result;
1942 }
1943 
1944 // ActiveTransSet(x1)
1946  TransSet result;
1947  TransSet::Iterator it;
1948  for (it = TransRelBegin(x1); it != TransRelEnd(x1); ++it) {
1949  result.Insert(*it);
1950  }
1951  return result;
1952 }
1953 
1954 // TransRelStates()
1956  StateSet states;
1957  TransSet::Iterator it;
1958  for (it=mpTransRel->Begin(); it != mpTransRel->End(); ++it) {
1959  states.Insert(it->X1);
1960  states.Insert(it->X2);
1961  }
1962  return states;
1963 }
1964 
1965 // SuccessorStates(x1)
1967  return mpTransRel->SuccessorStates(x1);
1968 }
1969 
1970 // SuccessorStates(x1,ev)
1972  return mpTransRel->SuccessorStates(x1,ev);
1973 }
1974 
1975 
1976 // idx SuccessorState() const
1978  TransSet::Iterator it = mpTransRel->Begin(x1,ev);
1979  TransSet::Iterator it_end = mpTransRel->End(x1,ev);
1980  if(it==it_end) return 0;
1981  Idx res=(*it).X2;
1982 #ifdef FAUDES_CHECKED
1983  it++;
1984  if(it!=it_end) {
1985  std::stringstream errstr;
1986  errstr << "successor state does not exist uniquely" << std::endl;
1987  throw Exception("vGenerator::SuccessorState", errstr.str(), 92);
1988  }
1989 #endif
1990  return res;
1991 }
1992 
1993 
1994 // AccessibleSet()
1996  // initialize todo stack
1997  std::stack<Idx> todo;
1998  StateSet::Iterator sit;
1999  for(sit = InitStatesBegin(); sit != InitStatesEnd(); ++sit)
2000  todo.push(*sit);
2001  // loop variables
2002  StateSet accessibleset;
2003  TransSet::Iterator tit;
2004  TransSet::Iterator tit_end;
2005  // loop
2006  while(!todo.empty()) {
2007  // pop
2008  Idx x1=todo.top();
2009  todo.pop();
2010  // sense known
2011  if(accessibleset.Exists(x1)) continue;
2012  // record
2013  accessibleset.Insert(x1);
2014  // iterate/push
2015  tit=TransRelBegin(x1);
2016  tit_end=TransRelEnd(x1);
2017  for(; tit != tit_end; ++tit)
2018  if(tit->X2 != x1)
2019  todo.push(tit->X2);
2020  }
2021  // done
2022  accessibleset.Name("AccessibleSet");
2023  return accessibleset;
2024 }
2025 
2026 // Accessible()
2028  StateSet accessibleset = AccessibleSet();
2029  StateSet not_accessible = *mpStates - accessibleset;
2030  DelStates(not_accessible);
2031  // return true if there is an initial state
2032  if (!mInitStates.Empty()) {
2033  FD_DF("vGenerator::accessible: generator is accessible");
2034  return true;
2035  }
2036  FD_DF("vGenerator::accessible: generator is accessible but empty");
2037  return false;
2038 }
2039 
2040 // IsAccessible()
2041 bool vGenerator::IsAccessible(void) const {
2042  if(AccessibleSet() == *mpStates) {
2043  FD_DF("vGenerator::accessible: generator is accessible");
2044  return true;
2045  }
2046  FD_DF("vGenerator::accessible: generator is not accessible");
2047  return false;
2048 }
2049 
2050 // CoaccessibleSet()
2052  // build reverse transition relation
2053  TransSetX2EvX1 rtrel;
2054  TransRel(rtrel);
2055  // initialize todo stack
2056  StateSet::Iterator sit;
2057  std::stack<Idx> todo;
2058  for(sit = MarkedStatesBegin(); sit != MarkedStatesEnd(); ++sit)
2059  todo.push(*sit);
2060  // loop variables
2061  StateSet coaccessibleset;
2063  TransSetX2EvX1::Iterator tit_end;
2064  // loop
2065  while(!todo.empty()) {
2066  // pop
2067  Idx x2=todo.top();
2068  todo.pop();
2069  // sense known
2070  if(coaccessibleset.Exists(x2)) continue;
2071  // record
2072  coaccessibleset.Insert(x2);
2073  // iterate/push
2074  tit=rtrel.BeginByX2(x2);
2075  tit_end=rtrel.EndByX2(x2);
2076  for(; tit != tit_end; ++tit)
2077  if(tit->X1 != x2)
2078  todo.push(tit->X1);
2079  }
2080  // done
2081  coaccessibleset.Name("CoaccessibleSet");
2082  return coaccessibleset;
2083 }
2084 
2085 // Coaccessible()
2087  StateSet coaccessibleset = CoaccessibleSet();
2088  StateSet not_coaccessible = *mpStates - coaccessibleset;
2089  DelStates(not_coaccessible);
2090  // return true if there is a marked state
2091  if (! mMarkedStates.Empty()) {
2092  FD_DF("vGenerator::coaccessible: generator is coaccessible");
2093  return true;
2094  }
2095  FD_DF("vGenerator::coaccessible: generator is not coaccessible");
2096  return false;
2097 }
2098 
2099 // IsCoaccessible()
2100 bool vGenerator::IsCoaccessible(void) const {
2101  if(CoaccessibleSet() == *mpStates) {
2102  FD_DF("vGenerator::coaccessible: generator is coaccessible");
2103  return true;
2104  }
2105  FD_DF("vGenerator::coaccessible: generator is not coaccessible");
2106  return false;
2107 }
2108 
2109 // TrimSet()
2111  FD_DF("vGenerator::trimset: trim states: "
2114  res.Name("TrimSet");
2115  return res;
2116 }
2117 
2118 // Trim()
2119 bool vGenerator::Trim(void) {
2120  FD_DF("vGenerator::trim: generator states: " << mpStates->ToString());
2121  // better: compute sets and do one state delete
2122  bool accessiblebool = Accessible();
2123  bool coaccessiblebool = Coaccessible();
2124  FD_DF("vGenerator::trim: trim states: " << mpStates->ToString());
2125  if(accessiblebool && coaccessiblebool) {
2126  FD_DF("vGenerator::Trim(): generator is nontrivial");
2127  return true;
2128  }
2129  FD_DF("vGenerator::Trim(): generator is trivial");
2130  return false;
2131 }
2132 
2133 
2134 // IsTrim()
2135 bool vGenerator::IsTrim(void) const {
2136  bool res=true;
2137  if(!IsAccessible()) res=false;
2138  else if(!IsCoaccessible()) res=false;
2139  FD_DF("vGenerator::IsTrim(): result " << res);
2140  return res;
2141 }
2142 
2143 
2144 // BlockingStates()
2146  FD_DF("vGenerator::BlockingSet: blocking states: "
2148  return AccessibleSet() - CoaccessibleSet();
2149 }
2150 
2151 
2152 
2153 // IsComplete
2154 bool vGenerator::IsComplete(const StateSet& rStates) const {
2155  FD_DG("IsComplete(" << Name() << ")");
2156 
2157  // loop over provided states
2158  StateSet::Iterator sit=rStates.Begin();
2159  StateSet::Iterator sit_end=rStates.End();
2160  for(;sit!=sit_end;sit++){
2162  TransSet::Iterator tit_end=TransRelEnd(*sit);
2163  if(tit==tit_end) break;
2164  }
2165  // return true if no terminal state has been found
2166  return sit==sit_end;
2167 }
2168 
2169 
2170 // IsComplete w.r.t. rSigmaO
2171 bool vGenerator::IsComplete(const EventSet& rSigmaO) const {
2172  FD_DC("IsComplete(" << Name() << ")");
2173  // find good states: where some rEvent is enabled
2174  std::stack<Idx> todo;
2176  TransSet::Iterator tit_end=TransRelEnd();
2177  while(tit!=tit_end){
2178  if(!rSigmaO.Exists(tit->Ev)) { ++tit; continue; }
2179  todo.push(tit->X1);
2180  tit=TransRelEnd(tit->X1);
2181  }
2182  // build reverse transition relation
2183  TransSetX2EvX1 rtrel;
2184  TransRel(rtrel);
2185  // reverse reachability analysis for more good states
2186  StateSet good;
2187  while(!todo.empty()) {
2188  // pop
2189  Idx x2=todo.top();
2190  todo.pop();
2191  // sense known
2192  if(good.Exists(x2)) continue;
2193  // record
2194  good.Insert(x2);
2195  // iterate/push
2196  TransSetX2EvX1::Iterator tit=rtrel.BeginByX2(x2);
2197  TransSetX2EvX1::Iterator tit_end=rtrel.EndByX2(x2);
2198  for(; tit != tit_end; ++tit)
2199  if(tit->X1 != x2) todo.push(tit->X1);
2200  }
2201  FD_DG("IsComplete(" << Name() << "): done");
2202  // done
2203  return good == States();
2204 }
2205 
2206 
2207 // IsComplete
2208 bool vGenerator::IsComplete(void) const {
2209  return IsComplete(States());
2210 }
2211 
2212 // Complete
2214  // states to remove
2215  StateSet termset = TerminalStates();
2216  // iterative search
2217  bool done;
2218  do {
2219  // over all states (could make use of reverse transrel here)
2220  StateSet::Iterator sit = States().Begin();
2221  StateSet::Iterator sit_end = States().End();
2222  done=true;
2223  for(; sit!=sit_end; ++sit) {
2224  if(termset.Exists(*sit)) continue;
2225  TransSet::Iterator tit = TransRelBegin(*sit);
2226  TransSet::Iterator tit_end = TransRelEnd(*sit);
2227  for (; tit != tit_end; ++tit) {
2228  if(!termset.Exists(tit->X2)) break;
2229  }
2230  if(tit==tit_end) {
2231  termset.Insert(*sit);
2232  done=false;
2233  }
2234  }
2235  } while(!done);
2236  // remove those states
2237  DelStates(termset);
2238  // done
2239  return !InitStates().Empty();
2240 }
2241 
2242 // Complete w.r.t. rSigmaO
2243 bool vGenerator::Complete(const EventSet& rSigmaO) {
2244 
2245  // prepare reverse transition relation
2246  TransSetX2EvX1 rtrel;
2247  TransRel(rtrel);
2248 
2249  // initialize nu-iteration
2250  StateSet domain=States();
2251 
2252  // nu-loop
2253  while(true){
2254 
2255  // initialize mu-iteration
2256  StateSet target;
2258  TransSet::Iterator tit_end=TransRelEnd();
2259  while(tit!=tit_end) {
2260  if(!rSigmaO.Exists(tit->Ev)) { ++tit; continue; }
2261  if(!domain.Exists(tit->X2)) { ++tit; continue; }
2262  target.Insert(tit->X1);
2263  tit=TransRelEnd(tit->X1);
2264  }
2265 
2266  // mu-loop: find good states by reverse reachability
2267  StateSet good;
2268  StateSet::Iterator sit;
2269  std::stack<Idx> todo;
2270  for(sit = target.Begin(); sit != target.End(); ++sit)
2271  todo.push(*sit);
2272  while(!todo.empty()) {
2273  // pop
2274  Idx x2=todo.top();
2275  todo.pop();
2276  // sense known
2277  if(good.Exists(x2)) continue;
2278  // record
2279  good.Insert(x2);
2280  // iterate/push
2281  TransSetX2EvX1::Iterator tit=rtrel.BeginByX2(x2);
2282  TransSetX2EvX1::Iterator tit_end=rtrel.EndByX2(x2);
2283  for(; tit != tit_end; ++tit)
2284  if(tit->X1 != x2) todo.push(tit->X1);
2285  }
2286 
2287  // nu-break: target will not change on update
2288  if(domain <= good) break;
2289 
2290  // nu-update: restrict target to have a successor within domain
2291  domain = domain * good;
2292 
2293  }
2294 
2295  // remove other states
2296  RestrictStates(domain);
2297 
2298  // done
2299  return !InitStates().Empty();
2300 }
2301 
2302 
2303 
2304 // TerminalStates()
2306  FD_DG("Generator::TerminalStates(" << Name() << ")");
2307 
2308  // prepare result
2309  StateSet res;
2310 
2311  // loop states
2312  StateSet::Iterator sit=rStates.Begin();
2313  StateSet::Iterator sit_end=rStates.End();
2314  for(;sit!=sit_end;sit++){
2316  TransSet::Iterator tit_end=TransRelEnd(*sit);
2317  if(tit==tit_end) res.Insert(*sit);
2318  }
2319  // return terminal states
2320  res.Name("TerminalStates");
2321  return res;
2322 }
2323 
2324 // TerminalStates()
2326  return TerminalStates(States());
2327 }
2328 
2329 
2330 
2331 
2332 // IsDeterministic()
2334  // if there is more than one initial state ... nondet
2335  if (InitStatesSize() > 1) {
2336  FD_DG("vGenerator::IsDeterministic: more than one initial state");
2337  return false;
2338  }
2339  // if there is a state/event pair with non-unique successor ... nondet
2340  if (TransRelSize() < 2) return true;
2341  TransSet::Iterator it1;
2342  TransSet::Iterator it2;
2343  for (it1 = TransRelBegin(), it2 = it1++; it1 != TransRelEnd(); it2 = it1++) {
2344  if ((it1->X1 == it2->X1) && (it1->Ev == it2->Ev)) {
2345  FD_DG("IsDeterministic(): at least one state "
2346  << "contains more than on transition with same event: "
2347  << TStr(*it1));
2348  return false;
2349  }
2350  }
2351  // in all other cases generator is deterministic
2352  return true;
2353 }
2354 
2355 
2356 // ReindexOnWrite()
2357 bool vGenerator::ReindexOnWrite(void) const {
2358  return mReindexOnWrite;
2359 }
2360 
2361 // ReindexOnWrite(flag)
2363  mReindexOnWrite = flag;
2364 }
2365 
2366 // ReindexOnWrite(flag)
2368  msReindexOnWriteDefault = flag;
2369 }
2370 
2371 // ReindexOnWrite(flag)
2373  return msReindexOnWriteDefault;
2374 }
2375 
2376 
2377 
2378 // DoWrite()
2379 void vGenerator::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
2380  (void) pContext;
2381  // pre 2.20 behaviour: re-index on file output
2382  /*
2383  if(rTw.FileMode())
2384  SetMinStateIndexMap();
2385  */
2386  // post 2.20 beaviour: re-index by configuration
2387  if(ReindexOnWrite())
2389  // figure section
2390  std::string label=rLabel;
2391  if(label=="") label="Generator";
2392  FD_DG("vGenerator(" << this << ")::DoWrite(): section " << label);
2393  // write generator
2394  Token btag;
2395  btag.SetBegin(label);
2396  if(mObjectName!=label) btag.InsAttributeString("name",mObjectName);
2397  rTw.Write(btag);
2398  rTw << "\n";
2399  SWrite(rTw);
2400  rTw << "\n";
2401  mpAlphabet->Write(rTw);
2402  rTw << "\n";
2403  WriteStates(rTw);
2404  rTw << "\n";
2405  WriteTransRel(rTw);
2406  rTw << "\n";
2407  WriteStateSet(rTw, mInitStates);
2408  rTw << "\n";
2410  rTw << "\n";
2411  mpGlobalAttribute->Write(rTw,"",this);
2412  rTw << "\n";
2413  rTw.WriteEnd(label);
2414  // end of reindex
2416 }
2417 
2418 // DoDWrite()
2419 void vGenerator::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
2420  (void) pContext;
2421  // figure section
2422  std::string label=rLabel;
2423  if(label=="") label="Generator";
2424  FD_DG("vGenerator(" << this << ")::DoDWrite(): section " << label);
2425  // write generator
2426  rTw.WriteBegin(label);
2427  rTw << mObjectName;
2428  rTw << "\n";
2429  rTw << "\n";
2430  SWrite(rTw);
2431  rTw << "\n";
2432  mpAlphabet->DWrite(rTw);
2433  rTw << "\n";
2434  DWriteStateSet(rTw, *mpStates);
2435  rTw << "\n";
2436  DWriteTransRel(rTw);
2437  rTw << "\n";
2439  rTw << "\n";
2441  rTw << "\n";
2442  mpGlobalAttribute->DWrite(rTw,"",this);
2443  rTw << "\n";
2444  rTw.WriteEnd(label);
2445  rTw << "\n";
2446 }
2447 
2448 // DoXWrite()
2449 void vGenerator::DoXWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
2450  (void) pContext;
2451  // Set up outer tag
2452  std::string label=rLabel;
2453  std::string ftype=TypeName();
2454  if(label=="") label="Generator";
2455  Token btag;
2456  btag.SetBegin(label);
2457  if(Name()!=label && Name()!="") btag.InsAttributeString("name",Name());
2458  //2.24e: make ftype mandatory for XML format to allow for more flexible faudes/plain format
2459  //if(ftype!=label && ftype!="") btag.InsAttributeString("ftype",ftype); // pre 2.22e
2460  btag.InsAttributeString("ftype",ftype); // 2.24e
2461  FD_DG("vGenerator(" << this << ")::DoXWrite(..): section " << btag.StringValue() << " #" << Size());
2462  rTw.Write(btag);
2463  // Optional re-indexing
2465  // Write comcponents
2466  rTw << "\n";
2467  mpAlphabet->XWrite(rTw,"Alphabet");
2468  rTw << "\n";
2469  XWriteStateSet(rTw, *mpStates,"StateSet");
2470  rTw << "\n";
2471  XWriteTransRel(rTw);
2472  rTw << "\n";
2473  mpGlobalAttribute->XWrite(rTw,"",this);
2475  rTw << "\n";
2476  // Write end
2477  rTw.WriteEnd(btag.StringValue());
2478  // End of re-index
2480 }
2481 
2482 // WriteAlphabet()
2483 void vGenerator::WriteAlphabet(void) const {
2485  WriteAlphabet(tw);
2486 }
2487 
2488 // AlphabetToString()
2489 std::string vGenerator::AlphabetToString(void) const {
2491  WriteAlphabet(tw);
2492  return tw.Str();
2493 }
2494 
2495 // WriteAlphabet(rTw&)
2497  mpAlphabet->Write(rTw);
2498 }
2499 
2500 // WriteStateSet(rStateSet&)
2501 void vGenerator::WriteStateSet(const StateSet& rStateSet) const {
2503  WriteStateSet(tw,rStateSet);
2504 }
2505 
2506 // StateSetToString()
2507 std::string vGenerator::StateSetToString(const StateSet& rStateSet) const {
2509  WriteStateSet(tw,rStateSet);
2510  return tw.Str();
2511 }
2512 
2513 // StateSetToText()
2514 std::string vGenerator::StateSetToText(const StateSet& rStateSet) const {
2516  tw.Endl(true);
2517  WriteStateSet(tw,rStateSet);
2518  return tw.Str();
2519 }
2520 
2521 
2522 // WriteStateSet(rTw&, rStateSet&)
2524  // have my section
2525  rTw.WriteBegin("States");
2526  // test whether we reindex
2527  bool reindex=mMinStateIndexMap.size()>0;
2528  // if we reindex, setup reverse map to write in strategic order
2529  // to allow for consisten read (i.e. states with symbolic name first, starting
2530  // with index 1); this is the plain faudes file format from 2005
2531  if(reindex) {
2532  // reverse map
2533  std::map<Idx,Idx> reversemap;
2534  std::map<Idx,Idx>::const_iterator minit;
2535  StateSet::Iterator sit;
2536  for (sit = StatesBegin(); sit != StatesEnd(); ++sit)
2537  reversemap[MinStateIndex(*sit)] = *sit;
2538  // iterate states to write
2539  for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
2540  // identify anonymous block (consecutive state indices)
2541  std::map<Idx,Idx>::const_iterator conit=minit;
2542  Idx start = conit->first;
2543  Idx anoncount = 0;
2544  for(; conit != reversemap.end(); ++conit) {
2545  if(StateName(conit->second) != "") break;
2546  if(!StateAttribute(conit->second).IsDefault()) break;
2547  if(conit->first != start+anoncount) break;
2548  ++anoncount;
2549  }
2550  // write anonymous block
2551  if(anoncount > FD_CONSECUTIVE) {
2552  rTw.WriteBegin("Consecutive");
2553  rTw << start;
2554  rTw << start+anoncount-1;
2555  rTw.WriteEnd("Consecutive");
2556  minit=conit;
2557  }
2558  // break loop
2559  if(minit == reversemap.end()) break;
2560  // write non anonymous state name/idx
2561  std::string statename = StateName(minit->second);
2562  if (statename != "") rTw << statename;
2563  else rTw << minit->first;
2564  // write state attribute
2565  const AttributeVoid& attr=StateAttribute(minit->second);
2566  attr.Write(rTw);
2567  }
2568  }
2569  // if we dont reindex, write symbolic names with index suffix to
2570  // enable a consistent read; this was introduced with libfaudes 2.20j
2571  if(!reindex) {
2572  // iterate states to write
2573  bool symexpl = (States().MaxIndex() != States().Size());
2574  StateSet::Iterator sit;
2575  for(sit = StatesBegin(); sit != StatesEnd(); ++sit) {
2576  // identify anonymous block (consecutive state indices)
2577  StateSet::Iterator conit=sit;
2578  Idx start = *conit;
2579  Idx anoncount = 0;
2580  for(; conit != StatesEnd(); ++conit) {
2581  if(StateName(*conit) != "") break;
2582  if(!StateAttribute(*conit).IsDefault()) break;
2583  if(*conit != start+anoncount) break;
2584  ++anoncount;
2585  }
2586  // write anonymous block
2587  if(anoncount > FD_CONSECUTIVE) {
2588  rTw.WriteBegin("Consecutive");
2589  rTw << start;
2590  rTw << start+anoncount-1;
2591  rTw.WriteEnd("Consecutive");
2592  sit=conit;
2593  }
2594  // break loop
2595  if(sit == StatesEnd()) break;
2596  // write index or name with index suffix
2597  std::string statename = StateName(*sit);
2598  if((statename != "") && symexpl) {
2599  rTw << (statename + "#"+ToStringInteger(*sit)) ;
2600  } else if(statename != "") {
2601  rTw << statename;
2602  } else {
2603  rTw << *sit;
2604  }
2605  // write attribute
2606  const AttributeVoid& attr=StateAttribute(*sit);
2607  attr.Write(rTw);
2608  }
2609  }
2610  // write end tag
2611  rTw.WriteEnd("States");
2612 }
2613 
2614 
2615 // WriteStateSet(rTw&, rStateSet&)
2616 void vGenerator::WriteStateSet(TokenWriter& rTw, const StateSet& rStateSet, const std::string& rLabel) const {
2617  // begin tag
2618  std::string label=rLabel;
2619  if(label.empty()) label=rStateSet.Name();
2620  rTw.WriteBegin(label);
2621  // test whether we reindex
2622  bool reindex=mMinStateIndexMap.size()>0;
2623  // if we reindex, setup reverse map to write in strategic order;
2624  // reading back is no issue for external states, however, we would like
2625  // to provoke large consecutive blocks as a benefit from re-indexing
2626  if(reindex) {
2627  // reverse map
2628  std::map<Idx,Idx> reversemap;
2629  std::map<Idx,Idx>::const_iterator minit;
2630  StateSet::Iterator sit;
2631  for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit)
2632  reversemap[MinStateIndex(*sit)] = *sit;
2633  // iterate states to write
2634  for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
2635  // identify anonymous block (consecutive state indices)
2636  std::map<Idx,Idx>::const_iterator conit=minit;
2637  Idx start = conit->first;
2638  Idx anoncount = 0;
2639  for(; conit != reversemap.end(); ++conit) {
2640  if(StateName(conit->second) != "") break;
2641  if(!StateAttribute(conit->second).IsDefault()) break;
2642  if(conit->first != start+anoncount) break;
2643  ++anoncount;
2644  }
2645  // write anonymous block
2646  if(anoncount > FD_CONSECUTIVE) {
2647  rTw.WriteBegin("Consecutive");
2648  rTw << start;
2649  rTw << start+anoncount-1;
2650  rTw.WriteEnd("Consecutive");
2651  minit=conit;
2652  }
2653  // break loop
2654  if(minit == reversemap.end()) break;
2655  // write non anonymous state name/idx
2656  std::string statename = StateName(minit->second);
2657  if (statename != "") rTw << statename;
2658  else rTw << minit->first;
2659  // write state attribute
2660  const AttributeVoid& attr=rStateSet.Attribute(minit->second);
2661  attr.Write(rTw);
2662  }
2663  }
2664  // if we dont reindex, we dont need the reverse map; note that
2665  // external stateset will never have an explicit symbol table
2666  if(!reindex) {
2667  // iterate states to write
2668  StateSet::Iterator sit;
2669  for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
2670  // identify anonymous block (consecutive state indices)
2671  StateSet::Iterator conit=sit;
2672  Idx start = *conit;
2673  Idx anoncount = 0;
2674  for(; conit != rStateSet.End(); ++conit) {
2675  if(StateName(*conit) != "") break;
2676  if(!StateAttribute(*conit).IsDefault()) break;
2677  if(*conit != start+anoncount) break;
2678  ++anoncount;
2679  }
2680  // write anonymous block
2681  if(anoncount > FD_CONSECUTIVE) {
2682  rTw.WriteBegin("Consecutive");
2683  rTw << start;
2684  rTw << start+anoncount-1;
2685  rTw.WriteEnd("Consecutive");
2686  sit=conit;
2687  }
2688  // break loop
2689  if(sit == rStateSet.End()) break;
2690  // write non anonymous state name/idx
2691  std::string statename = StateName(*sit);
2692  if (statename != "") rTw << statename;
2693  else rTw << *sit;
2694  // write attribute
2695  const AttributeVoid& attr=rStateSet.Attribute(*sit);
2696  attr.Write(rTw);
2697  }
2698  }
2699  // write end tag
2700  rTw.WriteEnd(label);
2701 }
2702 
2703 
2704 // DWriteStateSet(rTw&, rStateSet&)
2705 void vGenerator::DWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet) const {
2706  rTw.WriteBegin(rStateSet.Name());
2707  StateSet::Iterator sit;
2708  for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
2709  rTw << SStr(*sit);
2710  const AttributeVoid& attr=rStateSet.Attribute(*sit);
2711  attr.Write(rTw);
2712  }
2713  rTw.WriteEnd(rStateSet.Name());
2714 }
2715 
2716 
2717 // XWriteStateSet(rTw&, rStateSet&)
2718 void vGenerator::XWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet, const std::string& rLabel) const {
2719  // figure label
2720  std::string label=rLabel;
2721  if(label=="") label=rStateSet.Name();
2722  if(label=="") label="StateSet";
2723  rTw.WriteBegin(label);
2724  // build reverse index map of states to write ( fileidx->idx )
2725  // -- this ensures named states to be written first; see SetMinStateIndexMap()
2726  // -- this is required to figure consecutive blocks
2727  std::map<Idx,Idx> reversemap;
2728  std::map<Idx,Idx>::const_iterator minit;
2729  StateSet::Iterator sit;
2730  for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
2731  reversemap[MinStateIndex(*sit)] = *sit;
2732  }
2733  // iterate states to write
2734  for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
2735  // identify anonymous block (consecutive state indices, no names, no attributes)
2736  std::map<Idx,Idx>::const_iterator conit=minit;
2737  Idx start = conit->first;
2738  Idx anoncount = 0;
2739  for(; conit != reversemap.end(); ++conit) {
2740  if(StateName(conit->second) != "") break;
2741  if(!StateAttribute(conit->second).IsDefault()) break;
2742  if(ExistsInitState(conit->second)) break;
2743  if(ExistsMarkedState(conit->second)) break;
2744  if(conit->first != start+anoncount) break;
2745  ++anoncount;
2746  }
2747  // write anonymous block
2748  if(anoncount > FD_CONSECUTIVE) {
2749  Token contag;
2750  contag.SetEmpty("Consecutive");
2751  contag.InsAttributeInteger("from",start);
2752  contag.InsAttributeInteger("to",start+anoncount-1);
2753  rTw.Write(contag);
2754  minit=conit;
2755  }
2756  // break loop
2757  if(minit == reversemap.end() )
2758  break;
2759  // prepare state token
2760  Token sttag;
2761  std::string statename = StateName(minit->second);
2762  Idx index=minit->first;
2763  sttag.SetBegin("State");
2764  sttag.InsAttributeInteger("id",index);
2765  if(statename!="")
2766  if(&rStateSet==mpStates)
2767  sttag.InsAttributeString("name",statename);
2768  rTw.Write(sttag);
2769  // marking
2770  if(ExistsInitState(minit->second)) { sttag.SetEmpty("Initial"); rTw.Write(sttag);};
2771  if(ExistsMarkedState(minit->second)) { sttag.SetEmpty("Marked"); rTw.Write(sttag);};
2772  // attribute
2773  const AttributeVoid& attr=rStateSet.Attribute(minit->second);
2774  if(!attr.IsDefault()) attr.XWrite(rTw);
2775  // done
2776  rTw.WriteEnd("State");
2777  }
2778  rTw.WriteEnd(label);
2779 }
2780 
2781 
2782 // StatesToString()
2783 std::string vGenerator::StatesToString(void) const {
2784  return StateSetToString(*mpStates);
2785 }
2786 
2787 // StatesToText()
2788 std::string vGenerator::StatesToText(void) const {
2789  return StateSetToText(*mpStates);
2790 }
2791 
2792 // MarkedStatesToString()
2793 std::string vGenerator::MarkedStatesToString(void) const {
2795 }
2796 
2797 // InitStatesToString()
2798 std::string vGenerator::InitStatesToString(void) const {
2799  return StateSetToString(mInitStates);
2800 }
2801 
2802 
2803 // WriteTransRel()
2804 void vGenerator::WriteTransRel(void) const {
2806  WriteTransRel(tw);
2807 }
2808 
2809 // TransRelToString()
2810 std::string vGenerator::TransRelToString(void) const {
2812  WriteTransRel(tw);
2813  return tw.Str();
2814 }
2815 
2816 // TransRelToText()
2817 std::string vGenerator::TransRelToText(void) const {
2819  tw.Endl(true);
2820  WriteTransRel(tw);
2821  return tw.Str();
2822 }
2823 
2824 // WriteTransRel(rTw&)
2826  TransSet::Iterator tit;
2827  int oldcolumns = rTw.Columns();
2828  rTw.Columns(3);
2829  rTw.WriteBegin("TransRel");
2830  bool smalltransrel = (Size() < FD_SMALLTRANSREL);
2831 
2832  // loop all transitions
2833  for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
2834 
2835  // write x1
2836  Idx x1=MinStateIndex(tit->X1);
2837  if (smalltransrel) {
2838  std::string x1name = StateName(tit->X1);
2839  if (x1name != "") {
2840  rTw << x1name;
2841  } else {
2842  rTw << x1;
2843  }
2844  } else {
2845  rTw << x1;
2846  }
2847 
2848  // write ev
2849  rTw << EventName(tit->Ev);
2850 
2851  // write x2
2852  Idx x2=MinStateIndex(tit->X2);
2853  if (smalltransrel) {
2854  std::string x2name = StateName(tit->X2);
2855  if (x2name != "") {
2856  rTw << x2name;
2857  } else {
2858  rTw << x2;
2859  }
2860  } else {
2861  rTw << x2;
2862  }
2863 
2864  // write attributes
2865  TransAttribute(*tit).Write(rTw);
2866 
2867  }
2868  rTw.WriteEnd("TransRel");
2869  rTw.Columns(oldcolumns);
2870 }
2871 
2872 // DWriteTransRel(rTw&)
2874  TransSet::Iterator tit;
2875  int oldcolumns = rTw.Columns();
2876  rTw.Columns(3);
2877  rTw.WriteBegin("TransRel");
2878  // iterate all transitions
2879  for (tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
2880  // write x1
2881  std::ostringstream ox1;
2882  Idx x1= tit->X1;
2883  std::string x1name = StateName(x1);
2884  if (x1name != "") {
2885  ox1 << x1name << "[" << x1 << "]";
2886  } else {
2887  ox1 << x1;
2888  }
2889  rTw << ox1.str();
2890  // write ev
2891  std::ostringstream oev;
2892  Idx ev= tit->Ev;
2893  std::string evname = EventName(ev);
2894  oev << evname << "[" << ev << "]";
2895  rTw << oev.str();
2896  // write x2
2897  std::ostringstream ox2;
2898  Idx x2= tit->X2;
2899  std::string x2name = StateName(x2);
2900  if (x2name != "") {
2901  ox2 << x2name << "[" << x2 << "]";
2902  } else {
2903  ox2 << x2;
2904  }
2905  rTw << ox2.str();
2906  // attribute
2907  mpTransRel->Attribute(*tit).Write(rTw);
2908  }
2909  rTw.WriteEnd("TransRel");
2910  rTw.Columns(oldcolumns);
2911 }
2912 
2913 
2914 // XWriteTransRel(rTw&)
2916  TransSet::Iterator tit;
2917  rTw.WriteBegin("TransitionRelation");
2918 
2919  // loop all transitions
2920  for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
2921 
2922  // retrieve values x1
2923  Idx x1=MinStateIndex(tit->X1);
2924  Idx x2=MinStateIndex(tit->X2);
2925  std::string ev=EventName(tit->Ev);
2926 
2927  // prepare tag
2928  Token trtag;
2929  trtag.SetEmpty("Transition");
2930  trtag.InsAttributeInteger("x1",x1);
2931  trtag.InsAttributeString("event",ev);
2932  trtag.InsAttributeInteger("x2",x2);
2933 
2934  // consider attribute
2935  const AttributeVoid& attr=TransAttribute(*tit);
2936  // case a: indeed no attribute value
2937  if(attr.IsDefault()) {
2938  rTw.Write(trtag);
2939  }
2940  // calse b: with attribute
2941  else {
2942  trtag.ClrEnd();
2943  rTw.Write(trtag);
2944  attr.XWrite(rTw);
2945  rTw.WriteEnd(trtag.StringValue());
2946  }
2947 
2948  }
2949  rTw.WriteEnd("TransitionRelation");
2950 }
2951 
2952 // DoSWrite(rTw&)
2954 {
2955  Type::DoSWrite(rTw);
2956  rTw.WriteComment(" States: " + ToStringInteger(Size()) );
2957  rTw.WriteComment(" Init/Marked: " + ToStringInteger(mInitStates.Size())
2958  + "/" + ToStringInteger(mMarkedStates.Size()));
2959  rTw.WriteComment(" Events: " + ToStringInteger(mpAlphabet->Size()) );
2960  rTw.WriteComment(" Transitions: " + ToStringInteger(mpTransRel->Size()) );
2961  rTw.WriteComment(" StateSymbols: " + ToStringInteger(mpStateSymbolTable->Size()) );
2962  rTw.WriteComment(" Attrib. E/S/T: " + ToStringInteger(mpAlphabet->AttributesSize())
2965  rTw.WriteComment("");
2966 }
2967 
2968 // DotWrite(rFileName)
2969 void vGenerator::DotWrite(const std::string& rFileName) const {
2970  FD_DG("vGenerator(" << this << ")::DotWrite(" << rFileName << ")");
2971  if(ReindexOnWrite())
2973  StateSet::Iterator lit;
2974  TransSet::Iterator tit;
2975  try {
2976  std::ofstream stream;
2977  stream.exceptions(std::ios::badbit|std::ios::failbit);
2978  stream.open(rFileName.c_str());
2979  stream << "// dot output generated by libFAUDES vGenerator" << std::endl;
2980  stream << "digraph \"" << Name() << "\" {" << std::endl;
2981  stream << " rankdir=LR" << std::endl;
2982  stream << " node [shape=circle];" << std::endl;
2983  stream << std::endl;
2984  stream << " // initial states" << std::endl;
2985  int i = 1;
2986  for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
2987  std::string xname= StateName(*lit);
2988  if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
2989  stream << " dot_dummyinit_" << i << " [shape=none, label=\"\", width=\"0.0\", height=\"0.0\" ];" << std::endl;
2990  stream << " dot_dummyinit_" << i << " -> \"" << xname << "\";" << std::endl;
2991  i++;
2992  }
2993  stream << std::endl;
2994  stream << " // mstates" << std::endl;
2995  for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
2996  std::string xname= StateName(*lit);
2997  if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
2998  stream << " \"" << xname << "\" [shape=doublecircle];" << std::endl;
2999  }
3000  stream << std::endl;
3001  stream << " // rest of stateset" << std::endl;
3002  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
3003  if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) {
3004  std::string xname= StateName(*lit);
3005  if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
3006  stream << " \"" << xname << "\";" << std::endl;
3007  }
3008  }
3009  stream << std::endl;
3010  stream << " // transition relation" << std::endl;
3011  for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
3012  std::string x1name= StateName(tit->X1);
3013  if(x1name=="") x1name=ToStringInteger(MinStateIndex(tit->X1));
3014  std::string x2name= StateName(tit->X2);
3015  if(x2name=="") x2name=ToStringInteger(MinStateIndex(tit->X2));
3016  stream << " \"" << x1name << "\" -> \"" << x2name
3017  << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl;
3018  }
3019  stream << "}" << std::endl;
3020  stream.close();
3021  }
3022  catch (std::ios::failure&) {
3023  throw Exception("vGenerator::DotWrite",
3024  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
3025  }
3027 }
3028 
3029 // DDotWrite(rFileName)
3030 void vGenerator::DDotWrite(const std::string& rFileName) const {
3031  FD_DG("vGenerator(" << this << ")::DDotWrite(" << rFileName << ")");
3032  StateSet::Iterator lit;
3033  TransSet::Iterator tit;
3034  try {
3035  std::ofstream stream;
3036  stream.exceptions(std::ios::badbit|std::ios::failbit);
3037  stream.open(rFileName.c_str());
3038  stream << "digraph \"" << Name() << "\" {" << std::endl;
3039  stream << " rankdir=LR" << std::endl;
3040  stream << " node [shape=circle];" << std::endl;
3041  stream << std::endl;
3042  stream << " // istates" << std::endl;
3043  int i = 1;
3044  for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
3045  stream << " dot_dummyinit_" << i << " [shape=none, label=\"\" ];" << std::endl;
3046  stream << " dot_dummyinit_" << i << " -> \""
3047  << SStr(*lit) << "\";" << std::endl;
3048  i++;
3049  }
3050  stream << std::endl;
3051  stream << " // mstates" << std::endl;
3052  for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
3053  stream << " \"" << SStr(*lit) << "\" [shape=doublecircle];" << std::endl;
3054  }
3055  stream << std::endl;
3056  stream << " // rest of stateset" << std::endl;
3057  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
3058  // if not in mInitStates or mMarkedStates
3059  if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) {
3060  stream << " \"" << SStr(*lit) << "\";" << std::endl;
3061  }
3062  }
3063  stream << std::endl;
3064  stream << " // transition relation" << std::endl;
3065  for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
3066  stream << " \"" << SStr(tit->X1)
3067  << "\" -> \"" << SStr(tit->X2)
3068  << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl;
3069  }
3070  stream << "}" << std::endl;
3071  stream.close();
3072  }
3073  catch (std::ios::failure&) {
3074  throw Exception("vGenerator::DDotWrite",
3075  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
3076  }
3077 }
3078 
3079 
3080 // XDotWrite(rFileName)
3081 void vGenerator::XDotWrite(const std::string& rFileName) const {
3082  FD_DG("vGenerator(" << this << ")::XDotWrite(" << rFileName << ")");
3083  StateSet::Iterator lit;
3084  TransSet::Iterator tit;
3085  try {
3086  std::ofstream stream;
3087  stream.exceptions(std::ios::badbit|std::ios::failbit);
3088  stream.open(rFileName.c_str());
3089  stream << "digraph \"___" << Name() << "___\" {" << std::endl;
3090  stream << " rankdir=LR" << std::endl;
3091  stream << " node [shape=circle];" << std::endl;
3092  stream << std::endl;
3093  stream << " // stateset" << std::endl;
3094  for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
3095  stream << " \"s" << *lit << "\";" << std::endl;
3096  }
3097  for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
3098  stream << " \"s" << *lit << "\";" << std::endl;
3099  }
3100  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
3101  if(ExistsInitState(*lit)) continue;
3102  if(ExistsMarkedState(*lit)) continue;
3103  stream << " \"s" << *lit << "\";" << std::endl;
3104  }
3105  stream << std::endl;
3106  stream << " // transition relation" << std::endl;
3107  for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
3108  stream << " \"s" << tit->X1
3109  << "\" -> \"s" << tit->X2
3110  << "\" [label=\"e" << tit->Ev << "\" " << "polyline" << "];" << std::endl;
3111  }
3112  stream << "}" << std::endl;
3113  stream.close();
3114  }
3115  catch (std::ios::failure&) {
3116  throw Exception("vGenerator::XDotWrite",
3117  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
3118  }
3119 }
3120 
3121 // DoRead(tr)
3122 void vGenerator::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
3123  (void) pContext;
3124  std::string label=rLabel;
3125  if(label=="") label="Generator";
3126  FD_DG("vGenerator(" << this << ")::DoRead(): file " << rTr.FileName() << " section " << label);
3127  // clear old stuff
3128  Clear();
3129  // find Generator tag
3130  Token btag;
3131  rTr.ReadBegin(label, btag);
3132  int seclev=rTr.Level();
3133  // hypothesis: format is either "relaxed native 2.24e" or "xml"
3134  bool native=true;
3135  bool xml= true;
3136  // the ftype attribute is mandatory to indicate xml format (as of 2.24e)
3137  if(btag.ExistsAttributeString("ftype")) { native=false;}
3138  // try name by relaxed native 2.24e
3139  if(native) {
3140  FD_DG("vGenerator(" << this << ")::DoRead(): relaxed native header")
3141  std::string name="Generator";
3142  // figure name: as attribute
3143  if(btag.ExistsAttributeString("name"))
3144  name=btag.AttributeStringValue("name");
3145  // figure name: as string token
3146  Token token;
3147  rTr.Peek(token);
3148  if(token.IsString()) { name=rTr.ReadString(); xml=false; }
3149  Name(name);
3150  }
3151  // try core sets by relaxed native 2.24e
3152  if(native) {
3153  FD_DG("vGenerator(" << this << ")::DoRead(): relaxed native core")
3154  // read alphabet (optional)
3155  ReadAlphabet(rTr);
3156  // read stateset (optional)
3157  ReadStates(rTr);
3158  // read transrel (required --- if not present, we might have mis-sensed pre 2.24e xml)
3159  Token token;
3160  rTr.Peek(token);
3161  FD_DG("vGenerator(" << this << ")::DoRead(): " << token.Str());
3162  if(token.IsBegin("TransRel") || token.IsBegin("T")) {
3163  ReadTransRel(rTr);
3164  } else {
3165  native=false;
3166  rTr.Reset(seclev);
3167  Clear();
3168  }
3169  }
3170  // try extra sets by relaxed native 2.24e
3171  if(native) {
3172  FD_DG("vGenerator(" << this << ")::DoRead(): native extra items")
3173  // read istates (optional)
3174  Token token;
3175  rTr.Peek(token);
3176  if(token.IsBegin("InitStates"))
3177  {ReadStateSet(rTr, "InitStates", mInitStates); xml=false;}
3178  if(token.IsBegin("I"))
3179  {ReadStateSet(rTr, "I", mInitStates); xml=false;}
3180  mInitStates.Name("InitStates");
3181  // read mstates (optional)
3182  rTr.Peek(token);
3183  if(token.IsBegin("MarkedStates"))
3184  {ReadStateSet(rTr, "MarkedStates", mMarkedStates); xml=false; }
3185  if(token.IsBegin("M"))
3186  {ReadStateSet(rTr, "M", mMarkedStates); xml=false;}
3187  mMarkedStates.Name("MarkedStates");
3188  // read attribute
3189  mpGlobalAttribute->Read(rTr,"",this);
3190  }
3191  // if we survived, its not xml
3192  if(native) xml=false;
3193  // read strict xml format
3194  if(xml) {
3195  FD_DG("vGenerator(" << this << ")::DoRead(): xml")
3196  // figure generator name
3197  std::string name="generator";
3198  if(btag.ExistsAttributeString("name"))
3199  name=btag.AttributeStringValue("name");
3200  Name(name);
3201  // read alphabet
3202  mpAlphabet->Read(rTr,"Alphabet");
3203  // read state set, incl. init/marked attribute
3204  XReadStateSet(rTr, *mpStates, "StateSet");
3205  mpStates->Name("States");
3206  // read trans rel
3207  XReadTransRel(rTr);
3208  // read attribute
3209  mpGlobalAttribute->Read(rTr,"",this);
3210  // fix labels
3211  mInitStates.Name("InitStates");
3212  mMarkedStates.Name("MarkedStates");
3213  }
3214  // read end
3215  rTr.ReadEnd(label);
3216  FD_DG("vGenerator(" << this << ")::DoRead(): done");
3217 }
3218 
3219 // ReadAlphabet(rTr)
3221  FD_DG("vGenerator(" << this << ")::ReadAlphabet(\""
3222  << rTr.FileName() << "\")");
3223  Token token;
3224  rTr.Peek(token);
3225  if(token.IsBegin("Alphabet"))
3226  mpAlphabet->Read(rTr,"Alphabet");
3227  if(token.IsBegin("A"))
3228  mpAlphabet->Read(rTr,"A");
3229  mpAlphabet->Name("Alphabet");
3230 }
3231 
3232 // ReadStates(tr)
3234  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\")");
3235  // HELPERS:
3236  Token token;
3237  std::string label="";
3238  rTr.Peek(token);
3239  if(token.IsBegin("States")) label=token.StringValue();
3240  if(token.IsBegin("S")) label=token.StringValue();
3241  if(label=="") return;
3242  AttributeVoid* attrp = mpStates->AttributeType()->New();
3243  FD_DG("vGenerator(" << this << ")::ReadStates(..): attribute type " << typeid(*attrp).name());
3244  // ALGORITHM:
3245  mpStates->Clear();
3246  mpStates->Name("States");
3248  // track occurence of explicit symboltable
3249  bool symimpl=false;
3250  bool symexpl=false;
3251  Idx symnext=1;
3252  // loop section
3253  rTr.ReadBegin(label);
3254  while(!rTr.Eos(label)) {
3255  // peek
3256  rTr.Peek(token);
3257  // read state by index
3258  if(token.IsInteger()) {
3259  rTr.Get(token);
3260  Idx index = token.IntegerValue();
3261  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by index " << index);
3262  if(mpStates->Exists(index)) {
3263  delete attrp;
3264  std::stringstream errstr;
3265  errstr << "Token " << token.IntegerValue() << " appears twice in stateset"
3266  << rTr.FileLine();
3267  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3268  }
3269  // read attribute
3270  attrp->Read(rTr,"",this);
3271  // skip unknown attributes
3272  AttributeVoid::Skip(rTr);
3273  // insert element with attribute
3274  InsState(index);
3275  StateAttribute(index,*attrp);
3276  symnext++;
3277  continue;
3278  }
3279  // read state by name
3280  if(token.IsString()) {
3281  rTr.Get(token);
3282  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by name " << token.StringValue());
3283  // interpret name, sense index suffx if present
3284  std::string statename=token.StringValue();
3285  Idx index=symnext;
3286  std::size_t pos= statename.find_first_of('#');
3287  if(pos==std::string::npos) symimpl=true;
3288  if(pos!=std::string::npos) symexpl=true;
3289  if(pos!=std::string::npos && pos < statename.size()-1) {
3290  std::string suffix=statename.substr(pos+1);
3291  index=ToIdx(suffix);
3292  statename=statename.substr(0,pos);
3293  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): extracted suffix from " << token.StringValue() << ": " << statename << " idx " << index);
3294  }
3295  // no doublets
3296  if(ExistsState(statename) || ExistsState(index)) {
3297  delete attrp;
3298  std::stringstream errstr;
3299  errstr << "State " << statename << "(idx " << index <<") appears twice in stateset"
3300  << rTr.FileLine();
3301  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3302  }
3303  // read attribute
3304  attrp->Read(rTr,"",this);
3305  // skip unknown attributes
3306  AttributeVoid::Skip(rTr);
3307  // insert element with attribute
3308  InsState(index);
3309  StateName(index,statename);
3310  StateAttribute(index,*attrp);
3311  symnext++;
3312  continue;
3313  }
3314  // read consecutive block of anonymous states
3315  if(token.IsBegin("Consecutive")) {
3316  rTr.ReadBegin("Consecutive");
3317  Token token1,token2;
3318  rTr.Get(token1);
3319  rTr.Get(token2);
3320  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): consecutive range");
3321  if ((!token1.IsInteger()) || (!token2.IsInteger())) {
3322  delete attrp;
3323  std::stringstream errstr;
3324  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3325  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3326  }
3327  for(Idx index = (Idx) token1.IntegerValue(); index <= (Idx) token2.IntegerValue(); ++index) {
3328  if(mpStates->Exists(index)) {
3329  delete attrp;
3330  std::stringstream errstr;
3331  errstr << "Index " << index << " appears twice in stateset"
3332  << rTr.FileLine();
3333  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3334  }
3335  InsState(index);
3336  symnext++;
3337  }
3338  rTr.ReadEnd("Consecutive");
3339  continue;
3340  }
3341  // cannot process token
3342  delete attrp;
3343  std::stringstream errstr;
3344  errstr << "Invalid token" << rTr.FileLine();
3345  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3346  }
3347  rTr.ReadEnd(label);
3348  // test consistent explicit symboltable
3349  if(symimpl && symexpl) {
3350  delete attrp;
3351  std::stringstream errstr;
3352  errstr << "StateSet with inconsitent explicit symboltable" << rTr.FileLine();
3353  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3354  }
3355  // dispose attribute
3356  delete attrp;
3357  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): done");
3358 }
3359 
3360 
3361 // ReadStateSet(tr, rLabel, rStateSet)
3362 void vGenerator::ReadStateSet(TokenReader& rTr, const std::string& rLabel, StateSet& rStateSet) const {
3363  FD_DG("vGenerator(" << this << ")::ReadStateSet(\"" << rLabel<< "\")");
3364  // HELPERS:
3365  Token token;
3366  AttributeVoid* attrp = rStateSet.AttributeType()->New();
3367  FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name());
3368  // ALGORITHM:
3369  rStateSet.Clear();
3370  rTr.ReadBegin(rLabel);
3371  rStateSet.Name(rLabel);
3372  // loop section
3373  while(!rTr.Eos(rLabel)) {
3374  // peek
3375  rTr.Peek(token);
3376 
3377  // read state by index
3378  if(token.IsInteger()) {
3379  rTr.Get(token);
3380  Idx index = token.IntegerValue();
3381  if(!ExistsState(index)) {
3382  delete attrp;
3383  std::stringstream errstr;
3384  errstr << "Token " << token.IntegerValue() << " not in generator stateset"
3385  << rTr.FileLine();
3386  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3387  }
3388  // read attribute
3389  attrp->Read(rTr,"",this);
3390  // skip unknown attributes
3391  AttributeVoid::Skip(rTr);
3392  // insert element with attribute
3393  rStateSet.Insert(index);
3394  rStateSet.Attribute(index,*attrp);
3395  continue;
3396  }
3397 
3398  // read state by name
3399  if(token.IsString()) {
3400  rTr.Get(token);
3401  // test validity of symbolic name (no suffixes allowed here ... simply ignore)
3402  std::string statename=token.StringValue();
3403  std::size_t pos= statename.find_first_of('#');
3404  if(pos!=std::string::npos) {
3405  delete attrp;
3406  std::stringstream errstr;
3407  errstr << "invalid symbolic name: " << token.StringValue()
3408  << " (no suffix allowed in external state sets)" << rTr.FileLine();
3409  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3410  }
3411  Idx index =StateIndex(statename);
3412  if(index==0) {
3413  delete attrp;
3414  std::stringstream errstr;
3415  errstr << "Symbolic name " << token.StringValue() << " not in stateset"
3416  << rTr.FileLine();
3417  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3418  }
3419  // read attribute
3420  attrp->Read(rTr,"",this);
3421  // skip unknown attributes
3422  AttributeVoid::Skip(rTr);
3423  // insert element with attribute
3424  rStateSet.Insert(index);
3425  rStateSet.Attribute(index,*attrp);
3426  continue;
3427  }
3428 
3429  // read state in XML style
3430  if(token.IsBegin() && token.StringValue() == "State") {
3431  rTr.Get(token);
3432  std::string name="";
3433  if(token.ExistsAttributeString("name"))
3434  name=token.AttributeStringValue("name");
3435  Idx index=0;
3436  if(token.ExistsAttributeInteger("id"))
3437  index=token.AttributeIntegerValue("id");
3438  FD_DG("vGenerator::ReadStateSet(): got idx " << index << " " << name);
3439  // reconstruct index from name if possible
3440  if(index==0) {
3441  index=StateIndex(name);
3442  }
3443  // failed to figure index
3444  if(index==0) {
3445  delete attrp;
3446  std::stringstream errstr;
3447  errstr << "Cannot figure index for state token " << token.Str() << rTr.FileLine();
3448  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3449  }
3450  // dont allow doublets
3451  if(rStateSet.Exists(index)) {
3452  delete attrp;
3453  std::stringstream errstr;
3454  errstr << "Doublet state from token " << token.Str() << rTr.FileLine();
3455  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3456  }
3457  // record state
3458  rStateSet.Insert(index);
3459  // record name if we read the core set
3460  if(&rStateSet==mpStates)
3461  if(name!="") {
3462  mpStateSymbolTable->SetEntry(index, name);
3463  }
3464  // test for attributes
3465  if(!rTr.Eos("State")) {
3466  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): attribute ?");
3467  attrp->Read(rTr,"",this);
3468  rStateSet.Attribute(index,*attrp);
3469  }
3470  // read end
3471  rTr.ReadEnd("State");
3472  continue;
3473  }
3474 
3475  // read consecutve block of anonymous states
3476  if(token.IsBegin() && token.StringValue() == "Consecutive") {
3477  Token ctag;
3478  rTr.ReadBegin("Consecutive",ctag);
3479  Idx idx1=0;
3480  Idx idx2=0;
3481  Token token1,token2;
3482  rTr.Peek(token1);
3483  // figure range a) XML
3484  if(token1.IsEnd() && token.StringValue() == "Consecutive") {
3485  if(ctag.ExistsAttributeInteger("from"))
3486  idx1= (Idx) ctag.AttributeIntegerValue("from");
3487  if(ctag.ExistsAttributeInteger("to"))
3488  idx2= (Idx) ctag.AttributeIntegerValue("to");
3489  }
3490  // figure range a) native
3491  if(token1.IsInteger()) {
3492  rTr.Get(token1);
3493  rTr.Get(token2);
3494  if(!token1.IsInteger() || !token2.IsInteger()) {
3495  delete attrp;
3496  std::stringstream errstr;
3497  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3498  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3499  }
3500  idx1=token1.IntegerValue();
3501  idx2=token2.IntegerValue();
3502  }
3503  // validate range
3504  if(idx1==0 || idx2 < idx1) {
3505  delete attrp;
3506  std::stringstream errstr;
3507  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3508  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3509  }
3510  // perform range
3511  FD_DG("vGenerator(" << this << ")::ReadStateSet(\"" << rTr.FileName() << "\"): consecutive range " << idx1 << " to " << idx2);
3512  for(Idx index = idx1; index <= idx2; ++index) {
3513  if(!ExistsState(index)) {
3514  delete attrp;
3515  std::stringstream errstr;
3516  errstr << "range not in generator stateset" << rTr.FileLine();
3517  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3518  }
3519  rStateSet.Insert(index);
3520  }
3521  rTr.ReadEnd("Consecutive");
3522  continue;
3523  }
3524 
3525  // Ignore other sections
3526  if(token.IsBegin()) {
3527  rTr.ReadEnd(token.StringValue());
3528  continue;
3529  }
3530 
3531  // cannot process token
3532  delete attrp;
3533  std::stringstream errstr;
3534  errstr << "Section " << rLabel << ": Invalid token" << rTr.FileLine() << ": " << token.Str();
3535  throw Exception("vGenerator::ReadStateSet", errstr.str(), 50);
3536  }
3537  rTr.ReadEnd(rLabel);
3538  // dispose attribute
3539  delete attrp;
3540 }
3541 
3542 // XReadStateSet(tr, rLabel, rStateSet)
3543 void vGenerator::XReadStateSet(TokenReader& rTr, StateSet& rStateSet, const std::string& rLabel) const {
3544  FD_DG("vGenerator(" << this << ")::XReadStateSet(\"" << rLabel<< "\")");
3545  AttributeVoid* attrp = rStateSet.AttributeType()->New();
3546  FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name());
3547  // Clear my set
3548  rStateSet.Clear();
3549  // Figure section
3550  std::string label=rLabel;
3551  if(label=="") label=rStateSet.Name();
3552  if(label=="") label="StateSet";
3553  // Read begin
3554  Token btag;
3555  rTr.ReadBegin(label,btag);
3556  // Use name if provided (std is no name)
3557  rStateSet.Name("");
3558  if(btag.ExistsAttributeString("name"))
3559  rStateSet.Name(btag.AttributeStringValue("name"));
3560  // Scan my section
3561  while(!rTr.Eos(label)) {
3562  Token sttag;
3563  rTr.Get(sttag);
3564  // Read consecutive block of anonymous states
3565  if(sttag.IsBegin("Consecutive")) {
3566  // Get range
3567  Idx idx1=0;
3568  Idx idx2=0;
3569  if(sttag.ExistsAttributeInteger("from"))
3570  idx1= (Idx) sttag.AttributeIntegerValue("from");
3571  if(sttag.ExistsAttributeInteger("to"))
3572  idx2= (Idx) sttag.AttributeIntegerValue("to");
3573  // Insist in valid range
3574  if(idx1==0 || idx2 < idx1) {
3575  delete attrp;
3576  std::stringstream errstr;
3577  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3578  throw Exception("vGenerator::XReadStates", errstr.str(), 80);
3579  }
3580  FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): consecutive range " << idx1 << " to " << idx2);
3581  for(Idx index = idx1; index <= idx2; ++index) {
3582  if(rStateSet.Exists(index)) {
3583  delete attrp;
3584  std::stringstream errstr;
3585  errstr << "Doublet state index " << index << " " << rTr.FileLine();
3586  throw Exception("vGenerator::XReadStates", errstr.str(), 80);
3587  }
3588  rStateSet.Insert(index);
3589  }
3590  // Done: consecutive
3591  rTr.ReadEnd("Consecutive");
3592  continue;
3593  }
3594  // Ignore other sections
3595  if(!sttag.IsBegin("State")) {
3596  if(sttag.IsBegin())
3597  rTr.ReadEnd(sttag.StringValue());
3598  continue;
3599  }
3600  // Its a state
3601  std::string name="";
3602  if(sttag.ExistsAttributeString("name"))
3603  name=sttag.AttributeStringValue("name");
3604  Idx index=0;
3605  if(sttag.ExistsAttributeInteger("id"))
3606  index=sttag.AttributeIntegerValue("id");
3607  FD_DG("vGenerator::XReadStateSet(): got idx " << index << " " << name);
3608  // reconstruct index from name if possible
3609  if(index==0) {
3610  index=StateIndex(name);
3611  }
3612  // failed to figure index
3613  if(index==0) {
3614  delete attrp;
3615  std::stringstream errstr;
3616  errstr << "Cannot figure index for state token " << sttag.Str() << rTr.FileLine();
3617  throw Exception("vGenerator::XReadStateSet", errstr.str(), 80);
3618  }
3619  // dont allow doublets
3620  if(rStateSet.Exists(index)) {
3621  delete attrp;
3622  std::stringstream errstr;
3623  errstr << "Doublet state from token " << sttag.Str() << rTr.FileLine();
3624  throw Exception("vGenerator::XReadStateSet", errstr.str(), 80);
3625  }
3626  // record state
3627  rStateSet.Insert(index);
3628  // record name if we read the core set
3629  if(&rStateSet==mpStates)
3630  if(name!="") {
3631  mpStateSymbolTable->SetEntry(index, name);
3632  }
3633  // test for attributes and such
3634  while(!rTr.Eos("State")) {
3635  Token token;
3636  rTr.Peek(token);
3637  // marking (if this is the main state set)
3638  Token mtag;
3639  if(token.IsBegin("Initial") && (&rStateSet==mpStates)) {
3640  rTr.ReadBegin("Initial",mtag);
3641  bool v=true;
3642  if(mtag.ExistsAttributeInteger("value"))
3643  v=mtag.AttributeIntegerValue("value");
3644  if(v) const_cast<vGenerator*>(this)->SetInitState(index);
3645  rTr.ReadEnd("Initial");
3646  continue;
3647  }
3648  if(token.IsBegin("Marked") && (&rStateSet==mpStates)) {
3649  rTr.ReadBegin("Marked",mtag);
3650  bool v=true;
3651  if(mtag.ExistsAttributeInteger("value"))
3652  v=mtag.AttributeIntegerValue("value");
3653  if(v) const_cast<vGenerator*>(this)->SetMarkedState(index);
3654  rTr.ReadEnd("Marked");
3655  continue;
3656  }
3657  // read attribute
3658  FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): attribute ?");
3659  attrp->Read(rTr,"",this);
3660  rStateSet.Attribute(index,*attrp);
3661  // break on first unknown/undigested
3662  break;
3663  }
3664  // read end
3665  rTr.ReadEnd("State");
3666  }
3667  rTr.ReadEnd(label);
3668  // dispose attribute
3669  delete attrp;
3670  FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): done");
3671 }
3672 
3673 
3674 
3675 // ReadTransRel(tr)
3677  FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\")");
3678  AttributeVoid* attrp = mpTransRel->AttributeType()->New();
3679  FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name());
3680 
3681  // sense begin
3682  std::string label="";
3683  Token token;
3684  rTr.Peek(token);
3685  if(token.IsBegin("TransRel")) label="TransRel";
3686  if(token.IsBegin("T")) label="T";
3687  if(label=="") {
3688  std::stringstream errstr;
3689  errstr << "Reading TransRel failed in " << rTr.FileLine() << ": no valid begin token";
3690  throw Exception("vGenerator::ReadTransRel", errstr.str(), 50);
3691  }
3692  rTr.ReadBegin(label);
3693 
3694  // 2.24e: allow for new states or new events if not specified so far
3695  bool isx = StateSet().Empty();
3696  bool isn = StateSet().Empty();
3697  bool ien = Alphabet().Empty();
3698 
3699  // read section
3700  try {
3701  while(!rTr.Eos(label)) {
3702 
3703  // local vars
3704  Token x1t;
3705  Token x2t;
3706  Token evt;
3707 
3708  // clear my transition
3709  Idx x1 = 0, ev = 0, x2 = 0;
3710 
3711  // 1: the x1 token
3712  rTr >> x1t;
3713  if(x1t.IsInteger()) {
3714  x1=x1t.IntegerValue();
3715  if((!ExistsState(x1)) && isx) {InsState(x1); isn=false; };
3716  } else if(x1t.IsString()) {
3717  x1=StateIndex(x1t.StringValue());
3718  if(x1==0 && isn) { x1=InsState(x1t.StringValue()); isx=false; };
3719  } else break;
3720 
3721  // 2: the event token
3722  rTr >> evt;
3723  if(evt.IsString()) {
3724  evt.StringValue();
3725  ev=EventIndex(evt.StringValue());
3726  if((!ExistsEvent(ev)) && ien) {ev = InsEvent(evt.StringValue());};
3727  } else break;
3728 
3729  // 3: the x2 token
3730  rTr >> x2t;
3731  if(x2t.IsInteger()) {
3732  x2=x2t.IntegerValue();
3733  if((!ExistsState(x2)) && isx) {InsState(x2); isn=false; };
3734  } else if(x2t.IsString()) {
3735  x2=StateIndex(x2t.StringValue());
3736  if(x2==0 && isn) { x2=InsState(x2t.StringValue()); isx=false; };
3737  } else break;
3738 
3739  // 4: attributes
3740  attrp->Read(rTr,"",this);
3741 
3742  // 5: skip unknown attributes
3743  AttributeVoid::Skip(rTr);
3744 
3745  // check values
3746  if(!ExistsState(x1)){
3747  std::stringstream errstr;
3748  errstr << "invalid state x1 " << x1t.StringValue() << " " << rTr.FileLine();
3749  throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
3750  }
3751  if(!ExistsState(x2)){
3752  std::stringstream errstr;
3753  errstr << "invalid state x2 " << x2t.StringValue() << " " << rTr.FileLine();
3754  throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
3755  }
3756  if(!ExistsEvent(ev)) {
3757  std::stringstream errstr;
3758  errstr << "invalid event " << evt.StringValue() << " " << rTr.FileLine();
3759  throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
3760  }
3761 
3762  // insert transition
3763  Transition trans=Transition(x1,ev,x2);
3764  SetTransition(trans);
3765  TransAttribute(trans,*attrp);
3766 
3767  } // end while
3768  } // end try
3769 
3770  catch (faudes::Exception& oex) {
3771  delete attrp;
3772  std::stringstream errstr;
3773  errstr << "Reading TransRel failed in " << rTr.FileLine() << " " << oex.What();
3774  throw Exception("vGenerator::ReadTransRel", errstr.str(), 50);
3775  }
3776 
3777  // read end token
3778  rTr.ReadEnd(label);
3779 
3780  // done
3781  FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\"): done");
3782 
3783  // dispose attribute
3784  delete attrp;
3785 }
3786 
3787 
3788 // XReadTransRel(tr)
3790  FD_DG("vGenerator(" << this << ")::XReadTransRel()");
3791  AttributeVoid* attrp = mpTransRel->AttributeType()->New();
3792  FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name());
3793  // Clear my set
3794  mpTransRel->Clear();
3795  mpTransRel->Name("TransRel");
3796  // Read begin
3797  Token btag;
3798  rTr.ReadBegin("TransitionRelation",btag);
3799  // Scan my section
3800  while(!rTr.Eos("TransitionRelation")) {
3801  Token trtag;
3802  rTr.Get(trtag);
3803  // Ignore other sections
3804  if(!trtag.IsBegin("Transition")) {
3805  if(trtag.IsBegin())
3806  rTr.ReadEnd(trtag.StringValue());
3807  continue;
3808  }
3809  // Its a transition
3810  Idx x1=0;
3811  Idx x2=0;
3812  Idx ev=0;
3813  std::string evname;
3814  std::string x1name;
3815  std::string x2name;
3816  if(trtag.ExistsAttributeInteger("x1"))
3817  x1=trtag.AttributeIntegerValue("x1");
3818  if(trtag.ExistsAttributeInteger("x2"))
3819  x2=trtag.AttributeIntegerValue("x2");
3820  if(trtag.ExistsAttributeString("x1"))
3821  x1name=trtag.AttributeStringValue("x1");
3822  if(trtag.ExistsAttributeString("x2"))
3823  x2name=trtag.AttributeStringValue("x2");
3824  if(trtag.ExistsAttributeString("event"))
3825  evname=trtag.AttributeStringValue("event");
3826  // Interpret names
3827  ev=EventIndex(evname);
3828  if(x1==0) x1=StateIndex(x1name);
3829  if(x2==0) x2=StateIndex(x2name);
3830  // Report
3831  FD_DG("vGenerator::XReadTransRel(): got transition " << TStr(Transition(x1,ev,x2)));
3832  // test 1: components specified
3833  if(x1==0 || x2==0 || ev==0) {
3834  delete attrp;
3835  std::stringstream errstr;
3836  errstr << "Invalid transition at token " << trtag.Str() << rTr.FileLine();
3837  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3838  }
3839  // test 2: no doublets
3840  if(ExistsTransition(x1,ev,x2)) {
3841  delete attrp;
3842  std::stringstream errstr;
3843  errstr << "Doublet transition at token " << trtag.Str() << rTr.FileLine();
3844  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3845  }
3846  // test 3: components must exist
3847  if(!ExistsState(x1)){
3848  delete attrp;
3849  std::stringstream errstr;
3850  errstr << "Invalid state x1 " << x1 << " " << rTr.FileLine();
3851  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3852  }
3853  if(!ExistsState(x2)){
3854  delete attrp;
3855  std::stringstream errstr;
3856  errstr << "Invalid state x2 " << x2 << " " << rTr.FileLine();
3857  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3858  }
3859  if(!ExistsEvent(ev)){
3860  delete attrp;
3861  std::stringstream errstr;
3862  errstr << "Invalid event " << evname << " " << rTr.FileLine();
3863  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3864  }
3865  // record transition
3866  SetTransition(x1,ev,x2);
3867  // test for attribute
3868  Token token;
3869  rTr.Peek(token);
3870  if(!token.IsEnd("Transition")) {
3871  // read attribute
3872  attrp->Read(rTr,"",this);
3873  TransAttribute(Transition(x1,ev,x2),*attrp);
3874  }
3875  // read end
3876  rTr.ReadEnd("Transition");
3877  }
3878  rTr.ReadEnd("TransitionRelation");
3879  // dispose attribute
3880  delete attrp;
3881  FD_DG("vGenerator(" << this << ")::XReadTransRel(\"" << rTr.FileName() << "\"): done");
3882 }
3883 
3884 // EStr(index)
3885 std::string vGenerator::EStr(Idx index) const {
3886  std::string name = EventName(index);
3887  return name+"#"+faudes::ToStringInteger(index);
3888 }
3889 
3890 // SStr(index)
3891 std::string vGenerator::SStr(Idx index) const {
3892  std::string name = StateName(index);
3893  if(name == "") name=ToStringInteger(index);
3894  return name+"#"+faudes::ToStringInteger(index);
3895 }
3896 
3897 // TStr(index)
3898 std::string vGenerator::TStr(const Transition& trans) const {
3899  return SStr(trans.X1) + "--(" + EStr(trans.Ev) + ")-->" + SStr(trans.X2);
3900 }
3901 
3902 
3903 // GraphWrite(rFileName,rOutFormat)
3904 void vGenerator::GraphWrite(const std::string& rFileName, const std::string& rOutFormat,
3905  const std::string& rDotExec) const {
3906  FD_DG("vGenerator::GraphWrite(...): " << typeid(*this).name());
3907  // generate temp dot input file
3908  std::string dotin = CreateTempFile();
3909  if(dotin == "") {
3910  std::stringstream errstr;
3911  errstr << "Exception opening temp file";
3912  throw Exception("vGenerator::GraphWrite", errstr.str(), 2);
3913  }
3914  try{
3915  DotWrite(dotin);
3916  }
3917  catch (faudes::Exception& exception) {
3918  FileDelete(dotin);
3919  std::stringstream errstr;
3920  errstr << "Exception writing dot input file";
3921  throw Exception("vGenerator::GraphWrite", errstr.str(), 2);
3922  }
3923  try{
3924  faudes::ProcessDot(dotin,rFileName,rOutFormat,rDotExec);
3925  }
3926  catch (faudes::Exception& exception) {
3927  FileDelete(dotin);
3928  std::stringstream errstr;
3929  errstr << "Exception processing dot file";
3930  throw Exception("vGenerator::GraphWrite", errstr.str(), 3);
3931  }
3932  FileDelete(dotin);
3933 }
3934 
3935 // rti wrapper
3936 bool IsAccessible(const vGenerator& rGen) {
3937  return rGen.IsAccessible();
3938 }
3939 
3940 // rti wrapper
3941 bool IsCoaccessible(const vGenerator& rGen) {
3942  return rGen.IsCoaccessible();
3943 }
3944 
3945 // rti wrapper
3946 bool IsTrim(const vGenerator& rGen) {
3947  return rGen.IsTrim();
3948 }
3949 
3950 
3951 // rti wrapper
3952 bool IsComplete(const vGenerator& rGen) {
3953  return rGen.IsComplete();
3954 }
3955 
3956 // rti wrapper
3957 bool IsComplete(const vGenerator& rGen, const StateSet& rStateSet) {
3958  return rGen.IsComplete(rStateSet);
3959 }
3960 
3961 // rti wrapper
3962 bool IsComplete(const vGenerator& rGen, const EventSet& rSigmaO) {
3963  return rGen.IsComplete(rSigmaO);
3964 }
3965 
3966 // rti wrapper
3967 bool IsDeterministic(const vGenerator& rGen) {
3968  return rGen.IsDeterministic();
3969 }
3970 
3971 
3972 // rti wrapper
3973 void Accessible(vGenerator& rGen) {
3974  rGen.Accessible();
3975 }
3976 
3977 // rti wrapper
3978 void Accessible(const vGenerator& rGen, vGenerator& rRes) {
3979  rRes=rGen;
3980  rRes.Accessible();
3981 }
3982 
3983 // rti wrapper
3985  rGen.Coaccessible();
3986 }
3987 
3988 // rti wrapper
3989 void Coaccessible(const vGenerator& rGen, vGenerator& rRes) {
3990  rRes=rGen;
3991  rRes.Coaccessible();
3992 }
3993 
3994 // rti wrapper
3995 void Complete(vGenerator& rGen) {
3996  rGen.Complete();
3997 }
3998 
3999 // rti wrapper
4000 void Complete(const vGenerator& rGen, vGenerator& rRes) {
4001  rRes=rGen;
4002  rRes.Complete();
4003 }
4004 
4005 // rti wrapper
4006 void Complete(vGenerator& rGen, const EventSet& rSigmaO) {
4007  rGen.Complete(rSigmaO);
4008 }
4009 
4010 // rti wrapper
4011 void Complete(const vGenerator& rGen, const EventSet& rSigmaO, vGenerator& rRes) {
4012  rRes=rGen;
4013  rRes.Complete(rSigmaO);
4014 }
4015 
4016 // rti wrapper
4017 void Trim(vGenerator& rGen) {
4018  rGen.Trim();
4019 }
4020 
4021 // rti wrapper
4022 void Trim(const vGenerator& rGen, vGenerator& rRes) {
4023  rRes=rGen;
4024  rRes.Trim();
4025 }
4026 
4027 
4028 // rti wrapper
4030  rGen.InjectMarkedStates(rGen.States());
4031 }
4032 
4033 // rti wrapper
4034 void AlphabetExtract(const vGenerator& rGen, EventSet& rRes) {
4035  // This function is an ideal debugging case for lbp_function.cpp.
4036  // FD_WARN("AlphabetExtract(): gen at " << &rGen << " sig at " << &rRes);
4037  // FD_WARN("AlphabetExtract(): gen id " << typeid(rGen).name() << " sig id " << typeid(rRes).name());
4038  rRes = rGen.Alphabet();
4039  // rRes.Write();
4040 }
4041 
4042 // rti convenience function
4043 void SetIntersection(const GeneratorVector& rGenVec, EventSet& rRes) {
4044  // prepare result
4045  rRes.Clear();
4046  // ignore empty
4047  if(rGenVec.Size()==0) return;
4048  // copy first
4049  rRes.Assign(rGenVec.At(0).Alphabet());
4050  // perform intersecttion
4051  for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++)
4052  SetIntersection(rGenVec.At(i).Alphabet(),rRes,rRes);
4053 }
4054 
4055 
4056 // rti convenience function
4057 void SetUnion(const GeneratorVector& rGenVec, EventSet& rRes) {
4058  // prepare result
4059  rRes.Clear();
4060  // ignore empty
4061  if(rGenVec.Size()==0) return;
4062  // copy first
4063  rRes.Assign(rGenVec.At(0).Alphabet());
4064  // perform intersecttion
4065  for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++)
4066  SetUnion(rGenVec.At(i).Alphabet(),rRes,rRes);
4067 }
4068 
4069 // rti convenience function
4070 void SetIntersection(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
4071  SetIntersection(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
4072 }
4073 
4074 // rti convenience function
4075 void SetUnion(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
4076  SetUnion(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
4077 }
4078 
4079 // rti convenience function
4080 void SetDifference(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
4081  SetDifference(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
4082 }
4083 
4084 
4085 } // name space
4086 
4087 
4088 /***** NOTES ****/
4089 
4090 /*
4091 class A {
4092 public:
4093  virtual A& operator=(const A& src) { std::cout << "A=A/"; return *this; };
4094  virtual A& assign(const A& src) { std::cout << "A=A/"; return *this; };
4095  int a;
4096 };
4097 class B : public A {
4098 public:
4099  virtual A& operator=(const A& src) { std::cout<<"B=A/"; return *this;};
4100  virtual A& assign(const A& src) { std::cout<<"B=A/"; return *this; };
4101  int b;
4102 };
4103 
4104 
4105 
4106 int main() {
4107 
4108  B mD1;
4109  B mD2;
4110  mD1=mD2; // << fails here, dont know why
4111  mD1.assign(mD2);
4112  A& rD1 = mD1;
4113  A& rD2 = mD2;
4114  rD1=rD2;
4115 }
4116 
4117 */
#define FD_DC(message)
#define FD_DG(message)
#define FD_DF(message)
#define FD_ERR(message)
#define FAUDES_OBJCOUNT_DEC(type)
#define FAUDES_OBJCOUNT_INC(type)
#define FD_SMALLTRANSREL
#define FD_CONSECUTIVE
static void Skip(TokenReader &rTr)
Definition: cfl_types.cpp:369
virtual bool IsDefault(void) const
Definition: cfl_types.h:1076
virtual const char * What() const
Type & operator=(const Type &rSrc)
Definition: cfl_types.cpp:104
std::string mObjectName
Definition: cfl_types.h:1233
const std::string & Name(void) const
Definition: cfl_types.cpp:422
virtual const std::string & TypeName(void) const
Definition: cfl_types.cpp:443
Idx MaxIndex(void) const
bool Exists(const Idx &rIndex) const
NameSet::Iterator Find(const Idx &rIndex) const
virtual void InsertSet(const NameSet &rOtherSet)
SymbolTable * SymbolTablep(void) const
bool Insert(const Idx &rIndex)
Idx Index(const std::string &rName) const
void RestrictSet(const NameSet &rOtherSet)
virtual bool Erase(const Idx &rIndex)
void RestrictDomain(const IndexSet &rDomain)
static SymbolTable * GlobalEventSymbolTablep(void)
std::string Symbol(Idx index) const
void ClrEntry(Idx index)
std::string UniqueSymbol(const std::string &rName) const
void SetEntry(Idx index, const std::string &rName)
Idx Size(void) const
Idx Index(const std::string &rName) const
std::vector< int >::size_type Position
virtual const T & At(const Position &pos) const
Iterator Begin(void) const
Iterator End(void) const
Iterator Find(Idx x1, Idx ev, Idx x2) const
void EraseByEv(Idx ev)
void EraseByX1(Idx x1)
bool Exists(const Transition &t) const
void RestrictStates(const StateSet &rStateSet)
Iterator BeginByX2(Idx x2) const
void EraseByX1Ev(Idx x1, Idx ev)
bool Insert(const Transition &rTransition)
Iterator EndByX2(Idx x2) const
bool ExistsByX1Ev(Idx x1, Idx ev) const
Iterator Inject(const Iterator &pos, const Transition &rTransition)
bool Erase(const Transition &t)
StateSet SuccessorStates(Idx x1) const
void RestrictEvents(const EventSet &rEventSet)
void EraseByX1OrX2(Idx x)
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Definition: cfl_transset.h:273
void ReSort(TTransSet< OtherCmp > &res) const
bool ExistsByX1(Idx x1) const
std::string FileLine(void) const
bool Eos(const std::string &rLabel)
bool Reset(int level=-1)
int Level(void) const
void ReadEnd(const std::string &rLabel)
std::string ReadString(void)
void ReadBegin(const std::string &rLabel)
bool Get(Token &token)
bool Peek(Token &token)
std::string FileName(void) const
std::string Str(void)
void WriteComment(const std::string &rComment)
void Write(Token &rToken)
void WriteEnd(const std::string &rLabel)
int Columns(void) const
void WriteBegin(const std::string &rLabel)
std::string Str(void) const
Definition: cfl_token.cpp:1297
const std::string & StringValue(void) const
Definition: cfl_token.cpp:178
Int AttributeIntegerValue(const std::string &name)
Definition: cfl_token.cpp:397
void ClrEnd(void)
Definition: cfl_token.cpp:161
bool IsString(void) const
Definition: cfl_token.cpp:244
Int IntegerValue(void) const
Definition: cfl_token.cpp:167
bool IsInteger(void) const
Definition: cfl_token.cpp:219
bool ExistsAttributeString(const std::string &name)
Definition: cfl_token.cpp:356
bool IsBegin(void) const
Definition: cfl_token.cpp:259
void SetEmpty(const std::string &rName)
Definition: cfl_token.cpp:106
void SetBegin(const std::string &rName)
Definition: cfl_token.cpp:92
bool ExistsAttributeInteger(const std::string &name)
Definition: cfl_token.cpp:366
void InsAttributeInteger(const std::string &name, Int value)
Definition: cfl_token.cpp:319
void InsAttributeString(const std::string &name, const std::string &value)
Definition: cfl_token.cpp:310
bool IsEnd(void) const
Definition: cfl_token.cpp:270
const std::string & AttributeStringValue(const std::string &name)
Definition: cfl_token.cpp:386
void DWrite(const Type *pContext=0) const
Definition: cfl_types.cpp:231
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Definition: cfl_types.cpp:267
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:175
virtual void XWrite(const std::string &pFileName, const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:206
virtual void Clear(void)
Definition: cfl_types.cpp:72
virtual Type & Assign(const Type &rSrc)
Definition: cfl_types.cpp:82
virtual Type * New(void) const
Definition: cfl_types.cpp:54
virtual void DoSWrite(TokenWriter &rTw) const
Definition: cfl_types.cpp:305
void SWrite(void) const
Definition: cfl_types.cpp:256
void Write(const Type *pContext=0) const
Definition: cfl_types.cpp:145
Idx Size(void) const
static bool ReindexOnWriteDefault(void)
const EventSet * pAlphabetPrototype
virtual void TransAttribute(const Transition &rTrans, const Type &rAttr)
StateSet::Iterator StatesBegin(void) const
StateSet::Iterator InitStatesBegin(void) const
virtual bool Valid(void) const
const TransSet & TransRel(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
const StateSet & MarkedStates(void) const
void ClearInitStates(void)
void WriteStates(TokenWriter &rTw) const
static const StateSet & StatesVoid(void)
const EventSet & Alphabet(void) const
void XReadStateSet(TokenReader &rTr, StateSet &rStateSet, const std::string &rLabel="") const
std::string TransRelToString(void) const
virtual void DDotWrite(const std::string &rFileName) const
static void StateNamesEnabledDefault(bool flag)
virtual void Move(vGenerator &rGen)
const AttributeVoid * pGlobalPrototype
std::string MarkedStatesToString(void) const
virtual vGenerator & Assign(const Type &rSrc)
virtual vGenerator * Copy(void) const
bool InitStatesEmpty(void) const
std::string StatesToString(void) const
EventSet ActiveEventSet(Idx x1) const
virtual ~vGenerator(void)
void DelEvents(const EventSet &rEvents)
const StateSet & InitStates(void) const
const SymbolTable & StateSymbolTable(void) const
TransSet::Iterator TransRelBegin(void) const
void ClrTransition(Idx x1, Idx ev, Idx x2)
EventSet * NewEventSetp(void) const
EventSet NewEventSet(void) const
SymbolTable * EventSymbolTablep(void) const
void WriteAlphabet(void) const
AttributeVoid * mpGlobalAttribute
Idx StateIndex(const std::string &rName) const
virtual void ClearEventAttributes(void)
bool DelEvent(Idx index)
void InjectState(Idx index)
static const AttributeVoid & GlobalVoid(void)
virtual void EventAttribute(Idx index, const Type &rAttr)
void SetMinStateIndexMap(void) const
virtual void StateAttribute(Idx index, const Type &rAttr)
virtual vGenerator & AssignWithoutAttributes(const vGenerator &rGen)
StateSet::Iterator FindInitState(Idx index) const
void ReadAlphabet(TokenReader &rTr)
void ClrTransitions(Idx x1, Idx ev)
virtual void RestrictStates(const StateSet &rStates)
EventSet::Iterator FindEvent(Idx index) const
Idx InitStatesSize(void) const
static bool msReindexOnWriteDefault
virtual void ClearTransAttributes(void)
bool IsAccessible(void) const
void ReadStates(TokenReader &rTr)
void InsEvents(const EventSet &events)
void ClrMarkedState(Idx index)
void InjectStates(const StateSet &rNewStates)
static SymbolTable * GlobalEventSymbolTablep(void)
virtual AttributeVoid * GlobalAttributep(void)
bool EventRename(Idx event, const std::string &rNewName)
virtual void GlobalAttribute(const Type &rAttr)
virtual AttributeVoid * TransAttributep(const Transition &rTrans)
EventSet::Iterator AlphabetBegin(void) const
SymbolTable mStateSymbolTable
void WriteStateSet(const StateSet &rStateSet) const
virtual void DeleteCore(void)
SymbolTable * mpEventSymbolTable
StateSet TransRelStates(void) const
static const EventSet & AlphabetVoid(void)
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
StateSet BlockingStates(void) const
bool IsComplete(void) const
bool MarkedStatesEmpty(void) const
StateSet::Iterator FindMarkedState(Idx index) const
virtual AttributeVoid * EventAttributep(Idx index)
const std::map< Idx, Idx > & MinStateIndexMap(void) const
void DWriteStateSet(TokenWriter &rTw, const StateSet &rStateSet) const
Idx MaxStateIndex(void) const
void ClrStateName(Idx index)
virtual vGenerator * New(void) const
void ClearMarkedStates(void)
virtual void UpdateCore(void)
virtual void ClearStateAttributes(void)
bool ExistsTransition(const std::string &rX1, const std::string &rEv, const std::string &rX2) const
void MinStateIndex(void)
void EnforceStateNames(const std::string &rTemplate)
void InjectMarkedStates(const StateSet &rNewMarkedStates)
virtual void ClearGlobalAttribute(void)
virtual void DoDWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Idx MarkedStatesSize(void) const
void SetInitState(Idx index)
virtual void DoSWrite(TokenWriter &rTw) const
void InsStates(const StateSet &rStates)
virtual void GlobalAttributeTry(const Type &rAttr)
void ClearStateNames(void)
TransSet ActiveTransSet(Idx x1) const
void WriteTransRel(void) const
void XWriteStateSet(TokenWriter &rTw, const StateSet &rStateSet, const std::string &rLabel="") const
void InsMarkedStates(const StateSet &rStates)
bool TransRelEmpty(void) const
StateSet TrimSet(void) const
std::string InitStatesToString(void) const
StateSet AccessibleSet(void) const
Idx EventIndex(const std::string &rName) const
bool ExistsState(Idx index) const
virtual const AttributeVoid & GlobalAttribute(void) const
virtual AttributeVoid * StateAttributep(Idx index)
virtual void ClrTransAttribute(const Transition &rTrans)
bool IsCoaccessible(void) const
void ConfigureAttributeTypes(const AttributeVoid *pNewGlobalPrototype, const StateSet *pNewStatesPrototype, const EventSet *pNewAlphabetPrototype, const TransSet *pNewTransRelPrototype)
StateSet::Iterator MarkedStatesBegin(void) const
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
const TransSet * pTransRelPrototype
void XWriteTransRel(TokenWriter &rTw) const
bool DelEventFromAlphabet(Idx index)
void InjectTransition(const Transition &rTrans)
StateSet::Iterator FindState(Idx index) const
std::string StateSetToString(const StateSet &rStateSet) const
std::string UniqueEventName(const std::string &rName) const
virtual void RestrictAlphabet(const EventSet &rNewalphabet)
std::string TStr(const Transition &rTrans) const
bool DelStateFromStates(Idx index)
static bool msStateNamesEnabledDefault
std::string StateName(Idx index) const
virtual void DotWrite(const std::string &rFileName) const
bool DelState(Idx index)
void XReadTransRel(TokenReader &rTr)
virtual void XDotWrite(const std::string &rFileName) const
StateSet::Iterator StatesEnd(void) const
void ClrInitState(Idx index)
void DelStates(const StateSet &rDelStates)
TransSet::Iterator TransRelEnd(void) const
Idx SuccessorState(Idx x1, Idx ev) const
bool IsDeterministic(void) const
bool ExistsEvent(Idx index) const
std::string EStr(Idx index) const
std::map< Idx, Idx > mMinStateIndexMap
StateSet TerminalStates(void) const
StateSet::Iterator MarkedStatesEnd(void) const
void InjectTransRel(const TransSet &rNewtransrel)
void SetMarkedState(Idx index)
bool Empty(void) const
Transition TransitionByNames(const std::string &rX1, const std::string &rEv, const std::string &rX2) const
Idx InitState(void) const
static Idx msObjectCount
std::string StateSetToText(const StateSet &rStateSet) const
void ReadStateSet(TokenReader &rTr, const std::string &rLabel, StateSet &rStateSet) const
bool ReindexOnWrite(void) const
virtual void EventAttributes(const EventSet &rEventSet)
void InsInitStates(const StateSet &rStates)
void InjectInitStates(const StateSet &rNewInitStates)
bool StateNamesEnabled(void) const
bool InsEvent(Idx index)
std::string TransRelToText(void) const
StateSet::Iterator InitStatesEnd(void) const
virtual void NewCore(void)
void SetDefaultStateNames(void)
void GraphWrite(const std::string &rFileName, const std::string &rOutFormat="", const std::string &rDotExec="dot") const
static const TransSet & TransRelVoid(void)
virtual void ClrStateAttribute(Idx index)
Idx TransRelSize(void) const
virtual void Version(const std::string &rVersion, vGenerator &rResGen) const
EventSet UsedEvents(void) const
EventSet UnusedEvents(void) const
virtual const Type * Cast(const Type *pOther) const
void ClearMinStateIndexMap(void) const
std::string EventName(Idx index) const
const StateSet * pStatesPrototype
EventSet::Iterator AlphabetEnd(void) const
std::string StatesToText(void) const
bool IsTrim(void) const
virtual void ClearAttributes(void)
virtual void DoXWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
StateSet CoaccessibleSet(void) const
void MinimizeAlphabet(void)
Idx Size(void) const
Idx AlphabetSize(void) const
SymbolTable * mpStateSymbolTable
virtual void ClrEventAttribute(Idx index)
bool ExistsInitState(Idx index) const
std::string SStr(Idx index) const
virtual void Clear(void)
bool ExistsMarkedState(Idx index) const
TransSet::Iterator FindTransition(const std::string &rX1, const std::string &rEv, const std::string &rX2) const
void DoAssign(const vGenerator &rSrc)
std::string AlphabetToString(void) const
std::string UniqueStateName(const std::string &rName) const
void ReadTransRel(const std::string &rFileName)
void DWriteTransRel(TokenWriter &rTw) const
const StateSet & States(void) const
void InjectAlphabet(const EventSet &rNewalphabet)
StateSet SuccessorStates(Idx x1) const
bool AlphabetEmpty(void) const
virtual const AttributeVoid * AttributeType(void) const
Definition: cfl_baseset.h:2236
virtual TBaseSet & AssignWithoutAttributes(const TBaseSet &rSourceSet)
Definition: cfl_baseset.h:2302
bool Empty(void) const
Definition: cfl_baseset.h:1787
void SetDifference(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1096
bool Exists(const T &rElem) const
Definition: cfl_baseset.h:2180
virtual void Attributes(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2311
IndexSet StateSet
Definition: cfl_indexset.h:273
virtual void Clear(void)
Definition: cfl_baseset.h:1962
TTransSet< TransSort::X1EvX2 > TransSet
Iterator Find(const T &rElem) const
Definition: cfl_baseset.h:2175
Idx AttributesSize(void) const
Definition: cfl_baseset.h:2247
Iterator End(void) const
Definition: cfl_baseset.h:1956
TTransSet< TransSort::X1X2Ev > TransSetX1X2Ev
virtual void RestrictSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2129
virtual void InsertSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2052
virtual AttributeVoid * Attributep(const T &rElem)
Definition: cfl_baseset.h:2344
Iterator Begin(void) const
Definition: cfl_baseset.h:1951
NameSet EventSet
Definition: cfl_nameset.h:534
virtual const AttributeVoid & Attribute(const T &rElem) const
Definition: cfl_baseset.h:2355
virtual bool Erase(const T &rElem)
Definition: cfl_baseset.h:2084
void SetUnion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1037
void SetIntersection(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1067
virtual void EraseSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2107
Idx Size(void) const
Definition: cfl_baseset.h:1782
void ClearAttributes(void)
Definition: cfl_baseset.h:2252
virtual void ClrAttribute(const T &rElem)
Definition: cfl_baseset.h:2382
bool IsComplete(const vGenerator &rGen)
void Trim(vGenerator &rGen)
void Complete(vGenerator &rGen)
bool IsAccessible(const vGenerator &rGen)
bool IsTrim(const vGenerator &rGen)
void MarkAllStates(vGenerator &rGen)
bool IsCoaccessible(const vGenerator &rGen)
void AlphabetExtract(const vGenerator &rGen, EventSet &rRes)
void Accessible(vGenerator &rGen)
void Coaccessible(vGenerator &rGen)
bool IsDeterministic(const vGenerator &rGen)
uint32_t Idx
Idx ToIdx(const std::string &rString)
Definition: cfl_utils.cpp:100
void ProcessDot(const std::string &rDotFile, const std::string &rOutFile, const std::string &rOutFormat, const std::string &rDotExec)
Definition: cfl_utils.cpp:177
std::string CreateTempFile(void)
Definition: cfl_utils.cpp:234
bool FileDelete(const std::string &rFilename)
Definition: cfl_utils.cpp:419
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
AttrType AttributeVoid

libFAUDES 2.33h --- 2025.06.18 --- c++ api documentaion by doxygen