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  std::string ftype=TypeName();
2392  if(label=="") label="Generator";
2393  FD_DG("vGenerator(" << this << ")::DoWrite(): section " << label);
2394  // figure begin tag
2395  Token btag;
2396  btag.SetBegin(label);
2397  if(mObjectName!=label) btag.InsAttributeString("name",mObjectName);
2398  if(ftype!=label && ftype!="") btag.InsAttributeString("ftype",ftype); // semi mandatory type v2.33j
2399  rTw.Write(btag);
2400  rTw << "\n";
2401  // write body
2402  SWrite(rTw);
2403  rTw << "\n";
2404  mpAlphabet->Write(rTw);
2405  rTw << "\n";
2406  WriteStates(rTw);
2407  rTw << "\n";
2408  WriteTransRel(rTw);
2409  rTw << "\n";
2410  WriteStateSet(rTw, mInitStates);
2411  rTw << "\n";
2413  rTw << "\n";
2414  mpGlobalAttribute->Write(rTw,"",this);
2415  rTw << "\n";
2416  rTw.WriteEnd(label);
2417  // end of reindex
2419 }
2420 
2421 // DoDWrite()
2422 void vGenerator::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
2423  (void) pContext;
2424  // figure section
2425  std::string label=rLabel;
2426  if(label=="") label="Generator";
2427  FD_DG("vGenerator(" << this << ")::DoDWrite(): section " << label);
2428  // write generator
2429  rTw.WriteBegin(label);
2430  rTw << mObjectName;
2431  rTw << "\n";
2432  rTw << "\n";
2433  SWrite(rTw);
2434  rTw << "\n";
2435  mpAlphabet->DWrite(rTw);
2436  rTw << "\n";
2437  DWriteStateSet(rTw, *mpStates);
2438  rTw << "\n";
2439  DWriteTransRel(rTw);
2440  rTw << "\n";
2442  rTw << "\n";
2444  rTw << "\n";
2445  mpGlobalAttribute->DWrite(rTw,"",this);
2446  rTw << "\n";
2447  rTw.WriteEnd(label);
2448  rTw << "\n";
2449 }
2450 
2451 // DoXWrite()
2452 void vGenerator::DoXWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
2453  (void) pContext;
2454  // Set up outer tag
2455  std::string label=rLabel;
2456  std::string ftype=TypeName();
2457  if(label=="") label="Generator";
2458  Token btag;
2459  btag.SetBegin(label);
2460  if(Name()!=label && Name()!="") btag.InsAttributeString("name",Name());
2461  btag.InsAttributeString("ftype",ftype); // mandatory as of 2.24e
2462  FD_DG("vGenerator(" << this << ")::DoXWrite(..): section " << btag.StringValue() << " #" << Size());
2463  rTw.Write(btag);
2464  // Optional re-indexing
2466  // Write comcponents
2467  rTw << "\n";
2468  mpAlphabet->XWrite(rTw,"Alphabet");
2469  rTw << "\n";
2470  XWriteStateSet(rTw, *mpStates,"StateSet");
2471  rTw << "\n";
2472  XWriteTransRel(rTw);
2473  rTw << "\n";
2474  mpGlobalAttribute->XWrite(rTw,"",this);
2476  rTw << "\n";
2477  // Write end
2478  rTw.WriteEnd(btag.StringValue());
2479  // End of re-index
2481 }
2482 
2483 // WriteAlphabet()
2484 void vGenerator::WriteAlphabet(void) const {
2486  WriteAlphabet(tw);
2487 }
2488 
2489 // AlphabetToString()
2490 std::string vGenerator::AlphabetToString(void) const {
2492  WriteAlphabet(tw);
2493  return tw.Str();
2494 }
2495 
2496 // WriteAlphabet(rTw&)
2498  mpAlphabet->Write(rTw);
2499 }
2500 
2501 // WriteStateSet(rStateSet&)
2502 void vGenerator::WriteStateSet(const StateSet& rStateSet) const {
2504  WriteStateSet(tw,rStateSet);
2505 }
2506 
2507 // StateSetToString()
2508 std::string vGenerator::StateSetToString(const StateSet& rStateSet) const {
2510  WriteStateSet(tw,rStateSet);
2511  return tw.Str();
2512 }
2513 
2514 // StateSetToText()
2515 std::string vGenerator::StateSetToText(const StateSet& rStateSet) const {
2517  tw.Endl(true);
2518  WriteStateSet(tw,rStateSet);
2519  return tw.Str();
2520 }
2521 
2522 
2523 // WriteStateSet(rTw&, rStateSet&)
2525  // have my section
2526  rTw.WriteBegin("States");
2527  // test whether we reindex
2528  bool reindex=mMinStateIndexMap.size()>0;
2529  // if we reindex, setup reverse map to write in strategic order
2530  // to allow for consisten read (i.e. states with symbolic name first, starting
2531  // with index 1); this is the plain faudes file format from 2005
2532  if(reindex) {
2533  // reverse map
2534  std::map<Idx,Idx> reversemap;
2535  std::map<Idx,Idx>::const_iterator minit;
2536  StateSet::Iterator sit;
2537  for (sit = StatesBegin(); sit != StatesEnd(); ++sit)
2538  reversemap[MinStateIndex(*sit)] = *sit;
2539  // iterate states to write
2540  for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
2541  // identify anonymous block (consecutive state indices)
2542  std::map<Idx,Idx>::const_iterator conit=minit;
2543  Idx start = conit->first;
2544  Idx anoncount = 0;
2545  for(; conit != reversemap.end(); ++conit) {
2546  if(StateName(conit->second) != "") break;
2547  if(!StateAttribute(conit->second).IsDefault()) break;
2548  if(conit->first != start+anoncount) break;
2549  ++anoncount;
2550  }
2551  // write anonymous block
2552  if(anoncount > FD_CONSECUTIVE) {
2553  rTw.WriteBegin("Consecutive");
2554  rTw << start;
2555  rTw << start+anoncount-1;
2556  rTw.WriteEnd("Consecutive");
2557  minit=conit;
2558  }
2559  // break loop
2560  if(minit == reversemap.end()) break;
2561  // write non anonymous state name/idx
2562  std::string statename = StateName(minit->second);
2563  if (statename != "") rTw << statename;
2564  else rTw << minit->first;
2565  // write state attribute
2566  const AttributeVoid& attr=StateAttribute(minit->second);
2567  attr.Write(rTw);
2568  }
2569  }
2570  // if we dont reindex, write symbolic names with index suffix to
2571  // enable a consistent read; this was introduced with libfaudes 2.20j
2572  if(!reindex) {
2573  // iterate states to write
2574  bool symexpl = (States().MaxIndex() != States().Size());
2575  StateSet::Iterator sit;
2576  for(sit = StatesBegin(); sit != StatesEnd(); ++sit) {
2577  // identify anonymous block (consecutive state indices)
2578  StateSet::Iterator conit=sit;
2579  Idx start = *conit;
2580  Idx anoncount = 0;
2581  for(; conit != StatesEnd(); ++conit) {
2582  if(StateName(*conit) != "") break;
2583  if(!StateAttribute(*conit).IsDefault()) break;
2584  if(*conit != start+anoncount) break;
2585  ++anoncount;
2586  }
2587  // write anonymous block
2588  if(anoncount > FD_CONSECUTIVE) {
2589  rTw.WriteBegin("Consecutive");
2590  rTw << start;
2591  rTw << start+anoncount-1;
2592  rTw.WriteEnd("Consecutive");
2593  sit=conit;
2594  }
2595  // break loop
2596  if(sit == StatesEnd()) break;
2597  // write index or name with index suffix
2598  std::string statename = StateName(*sit);
2599  if((statename != "") && symexpl) {
2600  rTw << (statename + "#"+ToStringInteger(*sit)) ;
2601  } else if(statename != "") {
2602  rTw << statename;
2603  } else {
2604  rTw << *sit;
2605  }
2606  // write attribute
2607  const AttributeVoid& attr=StateAttribute(*sit);
2608  attr.Write(rTw);
2609  }
2610  }
2611  // write end tag
2612  rTw.WriteEnd("States");
2613 }
2614 
2615 
2616 // WriteStateSet(rTw&, rStateSet&)
2617 void vGenerator::WriteStateSet(TokenWriter& rTw, const StateSet& rStateSet, const std::string& rLabel) const {
2618  // begin tag
2619  std::string label=rLabel;
2620  if(label.empty()) label=rStateSet.Name();
2621  rTw.WriteBegin(label);
2622  // test whether we reindex
2623  bool reindex=mMinStateIndexMap.size()>0;
2624  // if we reindex, setup reverse map to write in strategic order;
2625  // reading back is no issue for external states, however, we would like
2626  // to provoke large consecutive blocks as a benefit from re-indexing
2627  if(reindex) {
2628  // reverse map
2629  std::map<Idx,Idx> reversemap;
2630  std::map<Idx,Idx>::const_iterator minit;
2631  StateSet::Iterator sit;
2632  for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit)
2633  reversemap[MinStateIndex(*sit)] = *sit;
2634  // iterate states to write
2635  for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
2636  // identify anonymous block (consecutive state indices)
2637  std::map<Idx,Idx>::const_iterator conit=minit;
2638  Idx start = conit->first;
2639  Idx anoncount = 0;
2640  for(; conit != reversemap.end(); ++conit) {
2641  if(StateName(conit->second) != "") break;
2642  if(!StateAttribute(conit->second).IsDefault()) break;
2643  if(conit->first != start+anoncount) break;
2644  ++anoncount;
2645  }
2646  // write anonymous block
2647  if(anoncount > FD_CONSECUTIVE) {
2648  rTw.WriteBegin("Consecutive");
2649  rTw << start;
2650  rTw << start+anoncount-1;
2651  rTw.WriteEnd("Consecutive");
2652  minit=conit;
2653  }
2654  // break loop
2655  if(minit == reversemap.end()) break;
2656  // write non anonymous state name/idx
2657  std::string statename = StateName(minit->second);
2658  if (statename != "") rTw << statename;
2659  else rTw << minit->first;
2660  // write state attribute
2661  const AttributeVoid& attr=rStateSet.Attribute(minit->second);
2662  attr.Write(rTw);
2663  }
2664  }
2665  // if we dont reindex, we dont need the reverse map; note that
2666  // external stateset will never have an explicit symbol table
2667  if(!reindex) {
2668  // iterate states to write
2669  StateSet::Iterator sit;
2670  for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
2671  // identify anonymous block (consecutive state indices)
2672  StateSet::Iterator conit=sit;
2673  Idx start = *conit;
2674  Idx anoncount = 0;
2675  for(; conit != rStateSet.End(); ++conit) {
2676  if(StateName(*conit) != "") break;
2677  if(!StateAttribute(*conit).IsDefault()) break;
2678  if(*conit != start+anoncount) break;
2679  ++anoncount;
2680  }
2681  // write anonymous block
2682  if(anoncount > FD_CONSECUTIVE) {
2683  rTw.WriteBegin("Consecutive");
2684  rTw << start;
2685  rTw << start+anoncount-1;
2686  rTw.WriteEnd("Consecutive");
2687  sit=conit;
2688  }
2689  // break loop
2690  if(sit == rStateSet.End()) break;
2691  // write non anonymous state name/idx
2692  std::string statename = StateName(*sit);
2693  if (statename != "") rTw << statename;
2694  else rTw << *sit;
2695  // write attribute
2696  const AttributeVoid& attr=rStateSet.Attribute(*sit);
2697  attr.Write(rTw);
2698  }
2699  }
2700  // write end tag
2701  rTw.WriteEnd(label);
2702 }
2703 
2704 
2705 // DWriteStateSet(rTw&, rStateSet&)
2706 void vGenerator::DWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet) const {
2707  rTw.WriteBegin(rStateSet.Name());
2708  StateSet::Iterator sit;
2709  for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
2710  rTw << SStr(*sit);
2711  const AttributeVoid& attr=rStateSet.Attribute(*sit);
2712  attr.Write(rTw);
2713  }
2714  rTw.WriteEnd(rStateSet.Name());
2715 }
2716 
2717 
2718 // XWriteStateSet(rTw&, rStateSet&)
2719 void vGenerator::XWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet, const std::string& rLabel) const {
2720  // figure label
2721  std::string label=rLabel;
2722  if(label=="") label=rStateSet.Name();
2723  if(label=="") label="StateSet";
2724  rTw.WriteBegin(label);
2725  // build reverse index map of states to write ( fileidx->idx )
2726  // -- this ensures named states to be written first; see SetMinStateIndexMap()
2727  // -- this is required to figure consecutive blocks
2728  std::map<Idx,Idx> reversemap;
2729  std::map<Idx,Idx>::const_iterator minit;
2730  StateSet::Iterator sit;
2731  for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
2732  reversemap[MinStateIndex(*sit)] = *sit;
2733  }
2734  // iterate states to write
2735  for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
2736  // identify anonymous block (consecutive state indices, no names, no attributes)
2737  std::map<Idx,Idx>::const_iterator conit=minit;
2738  Idx start = conit->first;
2739  Idx anoncount = 0;
2740  for(; conit != reversemap.end(); ++conit) {
2741  if(StateName(conit->second) != "") break;
2742  if(!StateAttribute(conit->second).IsDefault()) break;
2743  if(ExistsInitState(conit->second)) break;
2744  if(ExistsMarkedState(conit->second)) break;
2745  if(conit->first != start+anoncount) break;
2746  ++anoncount;
2747  }
2748  // write anonymous block
2749  if(anoncount > FD_CONSECUTIVE) {
2750  Token contag;
2751  contag.SetEmpty("Consecutive");
2752  contag.InsAttributeInteger("from",start);
2753  contag.InsAttributeInteger("to",start+anoncount-1);
2754  rTw.Write(contag);
2755  minit=conit;
2756  }
2757  // break loop
2758  if(minit == reversemap.end() )
2759  break;
2760  // prepare state token
2761  Token sttag;
2762  std::string statename = StateName(minit->second);
2763  Idx index=minit->first;
2764  sttag.SetBegin("State");
2765  sttag.InsAttributeInteger("id",index);
2766  if(statename!="")
2767  if(&rStateSet==mpStates)
2768  sttag.InsAttributeString("name",statename);
2769  rTw.Write(sttag);
2770  // marking
2771  if(ExistsInitState(minit->second)) { sttag.SetEmpty("Initial"); rTw.Write(sttag);};
2772  if(ExistsMarkedState(minit->second)) { sttag.SetEmpty("Marked"); rTw.Write(sttag);};
2773  // attribute
2774  const AttributeVoid& attr=rStateSet.Attribute(minit->second);
2775  if(!attr.IsDefault()) attr.XWrite(rTw);
2776  // done
2777  rTw.WriteEnd("State");
2778  }
2779  rTw.WriteEnd(label);
2780 }
2781 
2782 
2783 // StatesToString()
2784 std::string vGenerator::StatesToString(void) const {
2785  return StateSetToString(*mpStates);
2786 }
2787 
2788 // StatesToText()
2789 std::string vGenerator::StatesToText(void) const {
2790  return StateSetToText(*mpStates);
2791 }
2792 
2793 // MarkedStatesToString()
2794 std::string vGenerator::MarkedStatesToString(void) const {
2796 }
2797 
2798 // InitStatesToString()
2799 std::string vGenerator::InitStatesToString(void) const {
2800  return StateSetToString(mInitStates);
2801 }
2802 
2803 
2804 // WriteTransRel()
2805 void vGenerator::WriteTransRel(void) const {
2807  WriteTransRel(tw);
2808 }
2809 
2810 // TransRelToString()
2811 std::string vGenerator::TransRelToString(void) const {
2813  WriteTransRel(tw);
2814  return tw.Str();
2815 }
2816 
2817 // TransRelToText()
2818 std::string vGenerator::TransRelToText(void) const {
2820  tw.Endl(true);
2821  WriteTransRel(tw);
2822  return tw.Str();
2823 }
2824 
2825 // WriteTransRel(rTw&)
2827  TransSet::Iterator tit;
2828  int oldcolumns = rTw.Columns();
2829  rTw.Columns(3);
2830  rTw.WriteBegin("TransRel");
2831  bool smalltransrel = (Size() < FD_SMALLTRANSREL);
2832 
2833  // loop all transitions
2834  for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
2835 
2836  // write x1
2837  Idx x1=MinStateIndex(tit->X1);
2838  if (smalltransrel) {
2839  std::string x1name = StateName(tit->X1);
2840  if (x1name != "") {
2841  rTw << x1name;
2842  } else {
2843  rTw << x1;
2844  }
2845  } else {
2846  rTw << x1;
2847  }
2848 
2849  // write ev
2850  rTw << EventName(tit->Ev);
2851 
2852  // write x2
2853  Idx x2=MinStateIndex(tit->X2);
2854  if (smalltransrel) {
2855  std::string x2name = StateName(tit->X2);
2856  if (x2name != "") {
2857  rTw << x2name;
2858  } else {
2859  rTw << x2;
2860  }
2861  } else {
2862  rTw << x2;
2863  }
2864 
2865  // write attributes
2866  TransAttribute(*tit).Write(rTw);
2867 
2868  }
2869  rTw.WriteEnd("TransRel");
2870  rTw.Columns(oldcolumns);
2871 }
2872 
2873 // DWriteTransRel(rTw&)
2875  TransSet::Iterator tit;
2876  int oldcolumns = rTw.Columns();
2877  rTw.Columns(3);
2878  rTw.WriteBegin("TransRel");
2879  // iterate all transitions
2880  for (tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
2881  // write x1
2882  std::ostringstream ox1;
2883  Idx x1= tit->X1;
2884  std::string x1name = StateName(x1);
2885  if (x1name != "") {
2886  ox1 << x1name << "#" << x1;
2887  } else {
2888  ox1 << x1;
2889  }
2890  rTw << ox1.str();
2891  // write ev
2892  std::ostringstream oev;
2893  Idx ev= tit->Ev;
2894  std::string evname = EventName(ev);
2895  oev << evname << "#" << ev;
2896  rTw << oev.str();
2897  // write x2
2898  std::ostringstream ox2;
2899  Idx x2= tit->X2;
2900  std::string x2name = StateName(x2);
2901  if (x2name != "") {
2902  ox2 << x2name << "#" << x2;
2903  } else {
2904  ox2 << x2;
2905  }
2906  rTw << ox2.str();
2907  // attribute
2908  mpTransRel->Attribute(*tit).Write(rTw);
2909  }
2910  rTw.WriteEnd("TransRel");
2911  rTw.Columns(oldcolumns);
2912 }
2913 
2914 
2915 // XWriteTransRel(rTw&)
2917  TransSet::Iterator tit;
2918  rTw.WriteBegin("TransitionRelation");
2919 
2920  // loop all transitions
2921  for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
2922 
2923  // retrieve values x1
2924  Idx x1=MinStateIndex(tit->X1);
2925  Idx x2=MinStateIndex(tit->X2);
2926  std::string ev=EventName(tit->Ev);
2927 
2928  // prepare tag
2929  Token trtag;
2930  trtag.SetEmpty("Transition");
2931  trtag.InsAttributeInteger("x1",x1);
2932  trtag.InsAttributeString("event",ev);
2933  trtag.InsAttributeInteger("x2",x2);
2934 
2935  // consider attribute
2936  const AttributeVoid& attr=TransAttribute(*tit);
2937  // case a: indeed no attribute value
2938  if(attr.IsDefault()) {
2939  rTw.Write(trtag);
2940  }
2941  // calse b: with attribute
2942  else {
2943  trtag.ClrEnd();
2944  rTw.Write(trtag);
2945  attr.XWrite(rTw);
2946  rTw.WriteEnd(trtag.StringValue());
2947  }
2948 
2949  }
2950  rTw.WriteEnd("TransitionRelation");
2951 }
2952 
2953 // DoSWrite(rTw&)
2955 {
2956  Type::DoSWrite(rTw);
2957  rTw.WriteComment(" States: " + ToStringInteger(Size()) );
2958  rTw.WriteComment(" Init/Marked: " + ToStringInteger(mInitStates.Size())
2959  + "/" + ToStringInteger(mMarkedStates.Size()));
2960  rTw.WriteComment(" Events: " + ToStringInteger(mpAlphabet->Size()) );
2961  rTw.WriteComment(" Transitions: " + ToStringInteger(mpTransRel->Size()) );
2962  rTw.WriteComment(" StateSymbols: " + ToStringInteger(mpStateSymbolTable->Size()) );
2963  rTw.WriteComment(" Attrib. E/S/T: " + ToStringInteger(mpAlphabet->AttributesSize())
2966  rTw.WriteComment("");
2967 }
2968 
2969 // DotWrite(rFileName)
2970 void vGenerator::DotWrite(const std::string& rFileName) const {
2971  FD_DG("vGenerator(" << this << ")::DotWrite(" << rFileName << ")");
2972  // prepare
2974  TransSetX1X2Ev trx1x2ev(TransRel());
2975  StateSet::Iterator lit;
2977  // inspect labels to decide on shape
2978  bool circles=true;
2979  for(lit = StatesBegin(); lit != StatesEnd(); ++lit) {
2980  std::string xname= StateName(*lit);
2981  if(!xname.empty()) circles=false;
2982  xname=ToStringInteger(MinStateIndex(*lit));
2983  if(xname.length()>2) circles=false;
2984  if(!circles) break;
2985  }
2986  // iterate items and write to dot file
2987  try {
2988  // header
2989  std::ofstream stream;
2990  stream.exceptions(std::ios::badbit|std::ios::failbit);
2991  stream.open(rFileName.c_str());
2992  stream << "// dot output generated by libFAUDES vGenerator" << std::endl;
2993  stream << "digraph \"" << Name() << "\" {" << std::endl;
2994  stream << " rankdir=LR" << std::endl;
2995  if(circles)
2996  stream << " node [shape=circle];" << std::endl;
2997  else
2998  stream << " node [shape=rectangle, style=rounded];" << std::endl;
2999  stream << std::endl;
3000  // fake init states
3001  stream << " // initial states" << std::endl;
3002  int i = 1;
3003  for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
3004  std::string xname= StateName(*lit);
3005  if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
3006  stream << " dot_dummyinit_" << i << " [shape=none, label=\"\", width=\"0.0\", height=\"0.0\" ];" << std::endl;
3007  stream << " dot_dummyinit_" << i << " -> \"" << xname << "\";" << std::endl;
3008  i++;
3009  }
3010  stream << std::endl;
3011  // marked states
3012  stream << " // mstates" << std::endl;
3013  for(lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
3014  std::string xname= StateName(*lit);
3015  if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
3016  if(circles) {
3017  stream << " \"" << xname << "\" [shape=doublecircle];" << std::endl;
3018  } else {
3019  std::string xlabel=
3020  "<<TABLE BORDER=\"0\"><TR><TD>" +
3021  xname +
3022  "</TD><TD WIDTH=\"2\"></TD><TD BGCOLOR=\"black\" BORDER=\"0\" WIDTH=\"8\"></TD></TR></TABLE>>";
3023  stream << " \"" << xname << "\" [ label=" << xlabel <<"];" << std::endl;
3024  }
3025  }
3026  stream << std::endl;
3027  // other states
3028  stream << " // rest of stateset" << std::endl;
3029  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
3030  if (! ExistsMarkedState(*lit) ) {
3031  std::string xname= StateName(*lit);
3032  if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
3033  stream << " \"" << xname << "\";" << std::endl;
3034  }
3035  }
3036  stream << std::endl;
3037  // transrel
3038  stream << " // transition relation" << std::endl;
3039  std::string elabel;
3040  for(tit = trx1x2ev.Begin(); tit != trx1x2ev.End();) {
3041  // accumulate label
3042  if(!elabel.empty()) elabel = elabel + ", ";
3043  if(elabel.length()>9) elabel = elabel + "\n";
3044  elabel=elabel + EventName(tit->Ev);
3045  Idx x1=tit->X1;
3046  Idx x2=tit->X2;
3047  bool flush=false;
3048  // next transition
3049  ++tit;
3050  if(tit==trx1x2ev.End())
3051  flush =true;
3052  else
3053  flush=((tit->X1 != x1) || (tit->X2 != x2));
3054  // write out
3055  if(flush) {
3056  std::string x1name= StateName(x1);
3057  if(x1name=="") x1name=ToStringInteger(MinStateIndex(x1));
3058  std::string x2name= StateName(x2);
3059  if(x2name=="") x2name=ToStringInteger(MinStateIndex(x2));
3060  stream << " \"" << x1name << "\" -> \"" << x2name
3061  << "\" [label=\"" << elabel << "\"];" << std::endl;
3062  elabel="";
3063  }
3064  }
3065  stream << "}" << std::endl;
3066  stream.close();
3067  }
3068  catch (std::ios::failure&) {
3069  throw Exception("vGenerator::DotWrite",
3070  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
3071  }
3073 }
3074 
3075 // DDotWrite(rFileName)
3076 void vGenerator::DDotWrite(const std::string& rFileName) const {
3077  FD_DG("vGenerator(" << this << ")::DDotWrite(" << rFileName << ")");
3078  StateSet::Iterator lit;
3079  TransSet::Iterator tit;
3080  try {
3081  std::ofstream stream;
3082  stream.exceptions(std::ios::badbit|std::ios::failbit);
3083  stream.open(rFileName.c_str());
3084  stream << "digraph \"" << Name() << "\" {" << std::endl;
3085  stream << " rankdir=LR" << std::endl;
3086  stream << " node [shape=circle];" << std::endl;
3087  stream << std::endl;
3088  stream << " // istates" << std::endl;
3089  int i = 1;
3090  for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
3091  stream << " dot_dummyinit_" << i << " [shape=none, label=\"\" ];" << std::endl;
3092  stream << " dot_dummyinit_" << i << " -> \""
3093  << SStr(*lit) << "\";" << std::endl;
3094  i++;
3095  }
3096  stream << std::endl;
3097  stream << " // mstates" << std::endl;
3098  for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
3099  stream << " \"" << SStr(*lit) << "\" [shape=doublecircle];" << std::endl;
3100  }
3101  stream << std::endl;
3102  stream << " // rest of stateset" << std::endl;
3103  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
3104  // if not in mInitStates or mMarkedStates
3105  if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) {
3106  stream << " \"" << SStr(*lit) << "\";" << std::endl;
3107  }
3108  }
3109  stream << std::endl;
3110  stream << " // transition relation" << std::endl;
3111  for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
3112  stream << " \"" << SStr(tit->X1)
3113  << "\" -> \"" << SStr(tit->X2)
3114  << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl;
3115  }
3116  stream << "}" << std::endl;
3117  stream.close();
3118  }
3119  catch (std::ios::failure&) {
3120  throw Exception("vGenerator::DDotWrite",
3121  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
3122  }
3123 }
3124 
3125 
3126 // XDotWrite(rFileName)
3127 void vGenerator::XDotWrite(const std::string& rFileName) const {
3128  FD_DG("vGenerator(" << this << ")::XDotWrite(" << rFileName << ")");
3129  StateSet::Iterator lit;
3130  TransSet::Iterator tit;
3131  try {
3132  std::ofstream stream;
3133  stream.exceptions(std::ios::badbit|std::ios::failbit);
3134  stream.open(rFileName.c_str());
3135  stream << "digraph \"___" << Name() << "___\" {" << std::endl;
3136  stream << " rankdir=LR" << std::endl;
3137  stream << " node [shape=circle];" << std::endl;
3138  stream << std::endl;
3139  stream << " // stateset" << std::endl;
3140  for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
3141  stream << " \"s" << *lit << "\";" << std::endl;
3142  }
3143  for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
3144  stream << " \"s" << *lit << "\";" << std::endl;
3145  }
3146  for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
3147  if(ExistsInitState(*lit)) continue;
3148  if(ExistsMarkedState(*lit)) continue;
3149  stream << " \"s" << *lit << "\";" << std::endl;
3150  }
3151  stream << std::endl;
3152  stream << " // transition relation" << std::endl;
3153  for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
3154  stream << " \"s" << tit->X1
3155  << "\" -> \"s" << tit->X2
3156  << "\" [label=\"e" << tit->Ev << "\" " << "polyline" << "];" << std::endl;
3157  }
3158  stream << "}" << std::endl;
3159  stream.close();
3160  }
3161  catch (std::ios::failure&) {
3162  throw Exception("vGenerator::XDotWrite",
3163  "Exception opening/writing dotfile \""+rFileName+"\"", 2);
3164  }
3165 }
3166 
3167 // DoRead(tr)
3168 void vGenerator::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
3169  (void) pContext;
3170  std::string label=rLabel;
3171  if(label=="") label="Generator";
3172  FD_DG("vGenerator(" << this << ")::DoRead(): file " << rTr.FileName() << " section " << label);
3173  // clear old stuff
3174  Clear();
3175  // find Generator tag
3176  Token btag;
3177  rTr.ReadBegin(label, btag);
3178  int seclev=rTr.Level();
3179  // hypothesis: format is either "relaxed native 2.24e" or "xml"
3180  bool native=true;
3181  bool xml= true;
3182  // as of 2.24e, we used the ftype to sense XML; as og 2.33j we have ftype also in native mode
3183  // so we may need another way to detect XML
3184  //if(btag.ExistsAttributeString("ftype")) { native=false;} // 2.24e
3185  // try name by relaxed native 2.24e
3186  if(native) {
3187  FD_DG("vGenerator(" << this << ")::DoRead(): relaxed native header")
3188  std::string name="Generator";
3189  // figure name: as attribute
3190  if(btag.ExistsAttributeString("name"))
3191  name=btag.AttributeStringValue("name");
3192  // figure name: as string token
3193  Token token;
3194  rTr.Peek(token);
3195  if(token.IsString()) { name=rTr.ReadString(); xml=false; }
3196  Name(name);
3197  }
3198  // try core sets by relaxed native 2.24e
3199  if(native) {
3200  FD_DG("vGenerator(" << this << ")::DoRead(): relaxed native core")
3201  // read alphabet (optional)
3202  ReadAlphabet(rTr);
3203  // read stateset (optional)
3204  ReadStates(rTr);
3205  // read transrel (required --- if not present, we might have mis-sensed pre 2.24e xml)
3206  Token token;
3207  rTr.Peek(token);
3208  FD_DG("vGenerator(" << this << ")::DoRead(): " << token.Str());
3209  if(token.IsBegin("TransRel") || token.IsBegin("T")) {
3210  ReadTransRel(rTr);
3211  } else {
3212  native=false;
3213  rTr.Reset(seclev);
3214  Clear();
3215  }
3216  }
3217  // try extra sets by relaxed native 2.24e
3218  if(native) {
3219  FD_DG("vGenerator(" << this << ")::DoRead(): native extra items")
3220  // read istates (optional)
3221  Token token;
3222  rTr.Peek(token);
3223  if(token.IsBegin("InitStates"))
3224  {ReadStateSet(rTr, "InitStates", mInitStates); xml=false;}
3225  if(token.IsBegin("I"))
3226  {ReadStateSet(rTr, "I", mInitStates); xml=false;}
3227  mInitStates.Name("InitStates");
3228  // read mstates (optional)
3229  rTr.Peek(token);
3230  if(token.IsBegin("MarkedStates"))
3231  {ReadStateSet(rTr, "MarkedStates", mMarkedStates); xml=false; }
3232  if(token.IsBegin("M"))
3233  {ReadStateSet(rTr, "M", mMarkedStates); xml=false;}
3234  mMarkedStates.Name("MarkedStates");
3235  // read attribute (mandatory if non-void --- should be optional?)
3236  mpGlobalAttribute->Read(rTr,"",this);
3237  }
3238  // if we survived, its not xml
3239  if(native) xml=false;
3240  // read strict xml format
3241  if(xml) {
3242  FD_DG("vGenerator(" << this << ")::DoRead(): xml")
3243  // figure generator name
3244  std::string name="generator";
3245  if(btag.ExistsAttributeString("name"))
3246  name=btag.AttributeStringValue("name");
3247  Name(name);
3248  // read alphabet
3249  mpAlphabet->Read(rTr,"Alphabet");
3250  // read state set, incl. init/marked attribute
3251  XReadStateSet(rTr, *mpStates, "StateSet");
3252  mpStates->Name("States");
3253  // read trans rel
3254  XReadTransRel(rTr);
3255  // read attribute
3256  mpGlobalAttribute->Read(rTr,"",this);
3257  // fix object names
3258  mInitStates.Name("InitStates");
3259  mMarkedStates.Name("MarkedStates");
3260  }
3261  // read end
3262  rTr.ReadEnd(label);
3263  FD_DG("vGenerator(" << this << ")::DoRead(): done");
3264 }
3265 
3266 // ReadAlphabet(rTr)
3268  FD_DG("vGenerator(" << this << ")::ReadAlphabet(\""
3269  << rTr.FileName() << "\")");
3270  Token token;
3271  rTr.Peek(token);
3272  if(token.IsBegin("Alphabet"))
3273  mpAlphabet->Read(rTr,"Alphabet");
3274  if(token.IsBegin("A"))
3275  mpAlphabet->Read(rTr,"A");
3276  mpAlphabet->Name("Alphabet");
3277 }
3278 
3279 // ReadStates(tr)
3281  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\")");
3282  // HELPERS:
3283  Token token;
3284  std::string label="";
3285  rTr.Peek(token);
3286  if(token.IsBegin("States")) label=token.StringValue();
3287  if(token.IsBegin("S")) label=token.StringValue();
3288  if(label=="") return;
3289  AttributeVoid* attrp = mpStates->AttributeType()->New();
3290  FD_DG("vGenerator(" << this << ")::ReadStates(..): attribute type " << typeid(*attrp).name());
3291  // ALGORITHM:
3292  mpStates->Clear();
3293  mpStates->Name("States");
3295  // track occurence of explicit symboltable
3296  bool symimpl=false;
3297  bool symexpl=false;
3298  Idx symnext=1;
3299  // loop section
3300  rTr.ReadBegin(label);
3301  while(!rTr.Eos(label)) {
3302  // peek
3303  rTr.Peek(token);
3304  // read state by index
3305  if(token.IsInteger()) {
3306  rTr.Get(token);
3307  Idx index = token.IntegerValue();
3308  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by index " << index);
3309  if(mpStates->Exists(index)) {
3310  delete attrp;
3311  std::stringstream errstr;
3312  errstr << "Token " << token.IntegerValue() << " appears twice in stateset"
3313  << rTr.FileLine();
3314  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3315  }
3316  // read attribute
3317  attrp->Read(rTr,"",this);
3318  // skip unknown attributes
3319  AttributeVoid::Skip(rTr);
3320  // insert element with attribute
3321  InsState(index);
3322  StateAttribute(index,*attrp);
3323  symnext++;
3324  continue;
3325  }
3326  // read state by name
3327  if(token.IsString()) {
3328  rTr.Get(token);
3329  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by name " << token.StringValue());
3330  // interpret name, sense index suffx if present
3331  std::string statename=token.StringValue();
3332  Idx index=symnext;
3333  std::size_t pos= statename.find_first_of('#');
3334  if(pos==std::string::npos) symimpl=true;
3335  if(pos!=std::string::npos) symexpl=true;
3336  if(pos!=std::string::npos && pos < statename.size()-1) {
3337  std::string suffix=statename.substr(pos+1);
3338  index=ToIdx(suffix);
3339  statename=statename.substr(0,pos);
3340  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): extracted suffix from " << token.StringValue() << ": " << statename << " idx " << index);
3341  }
3342  // no doublets
3343  if(ExistsState(statename) || ExistsState(index)) {
3344  delete attrp;
3345  std::stringstream errstr;
3346  errstr << "State " << statename << "(idx " << index <<") appears twice in stateset"
3347  << rTr.FileLine();
3348  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3349  }
3350  // read attribute
3351  attrp->Read(rTr,"",this);
3352  // skip unknown attributes
3353  AttributeVoid::Skip(rTr);
3354  // insert element with attribute
3355  InsState(index);
3356  StateName(index,statename);
3357  StateAttribute(index,*attrp);
3358  symnext++;
3359  continue;
3360  }
3361  // read consecutive block of anonymous states
3362  if(token.IsBegin("Consecutive")) {
3363  rTr.ReadBegin("Consecutive");
3364  Token token1,token2;
3365  rTr.Get(token1);
3366  rTr.Get(token2);
3367  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): consecutive range");
3368  if ((!token1.IsInteger()) || (!token2.IsInteger())) {
3369  delete attrp;
3370  std::stringstream errstr;
3371  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3372  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3373  }
3374  for(Idx index = (Idx) token1.IntegerValue(); index <= (Idx) token2.IntegerValue(); ++index) {
3375  if(mpStates->Exists(index)) {
3376  delete attrp;
3377  std::stringstream errstr;
3378  errstr << "Index " << index << " appears twice in stateset"
3379  << rTr.FileLine();
3380  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3381  }
3382  InsState(index);
3383  symnext++;
3384  }
3385  rTr.ReadEnd("Consecutive");
3386  continue;
3387  }
3388  // cannot process token
3389  delete attrp;
3390  std::stringstream errstr;
3391  errstr << "Invalid token" << rTr.FileLine();
3392  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3393  }
3394  rTr.ReadEnd(label);
3395  // test consistent explicit symboltable
3396  if(symimpl && symexpl) {
3397  delete attrp;
3398  std::stringstream errstr;
3399  errstr << "StateSet with inconsitent explicit symboltable" << rTr.FileLine();
3400  throw Exception("vGenerator::ReadStates", errstr.str(), 80);
3401  }
3402  // dispose attribute
3403  delete attrp;
3404  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): done");
3405 }
3406 
3407 
3408 // ReadStateSet(tr, rLabel, rStateSet)
3409 void vGenerator::ReadStateSet(TokenReader& rTr, const std::string& rLabel, StateSet& rStateSet) const {
3410  FD_DG("vGenerator(" << this << ")::ReadStateSet(\"" << rLabel<< "\")");
3411  // HELPERS:
3412  Token token;
3413  AttributeVoid* attrp = rStateSet.AttributeType()->New();
3414  FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name());
3415  // ALGORITHM:
3416  rStateSet.Clear();
3417  rTr.ReadBegin(rLabel);
3418  rStateSet.Name(rLabel);
3419  // loop section
3420  while(!rTr.Eos(rLabel)) {
3421  // peek
3422  rTr.Peek(token);
3423 
3424  // read state by index
3425  if(token.IsInteger()) {
3426  rTr.Get(token);
3427  Idx index = token.IntegerValue();
3428  if(!ExistsState(index)) {
3429  delete attrp;
3430  std::stringstream errstr;
3431  errstr << "Token " << token.IntegerValue() << " not in generator stateset"
3432  << rTr.FileLine();
3433  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3434  }
3435  // read attribute
3436  attrp->Read(rTr,"",this);
3437  // skip unknown attributes
3438  AttributeVoid::Skip(rTr);
3439  // insert element with attribute
3440  rStateSet.Insert(index);
3441  rStateSet.Attribute(index,*attrp);
3442  continue;
3443  }
3444 
3445  // read state by name
3446  if(token.IsString()) {
3447  rTr.Get(token);
3448  // test validity of symbolic name (no suffixes allowed here ... simply ignore)
3449  std::string statename=token.StringValue();
3450  std::size_t pos= statename.find_first_of('#');
3451  if(pos!=std::string::npos) {
3452  delete attrp;
3453  std::stringstream errstr;
3454  errstr << "invalid symbolic name: " << token.StringValue()
3455  << " (no suffix allowed in external state sets)" << rTr.FileLine();
3456  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3457  }
3458  Idx index =StateIndex(statename);
3459  if(index==0) {
3460  delete attrp;
3461  std::stringstream errstr;
3462  errstr << "Symbolic name " << token.StringValue() << " not in stateset"
3463  << rTr.FileLine();
3464  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3465  }
3466  // read attribute
3467  attrp->Read(rTr,"",this);
3468  // skip unknown attributes
3469  AttributeVoid::Skip(rTr);
3470  // insert element with attribute
3471  rStateSet.Insert(index);
3472  rStateSet.Attribute(index,*attrp);
3473  continue;
3474  }
3475 
3476  // read state in XML style
3477  if(token.IsBegin() && token.StringValue() == "State") {
3478  rTr.Get(token);
3479  std::string name="";
3480  if(token.ExistsAttributeString("name"))
3481  name=token.AttributeStringValue("name");
3482  Idx index=0;
3483  if(token.ExistsAttributeInteger("id"))
3484  index=token.AttributeIntegerValue("id");
3485  FD_DG("vGenerator::ReadStateSet(): got idx " << index << " " << name);
3486  // reconstruct index from name if possible
3487  if(index==0) {
3488  index=StateIndex(name);
3489  }
3490  // failed to figure index
3491  if(index==0) {
3492  delete attrp;
3493  std::stringstream errstr;
3494  errstr << "Cannot figure index for state token " << token.Str() << rTr.FileLine();
3495  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3496  }
3497  // dont allow doublets
3498  if(rStateSet.Exists(index)) {
3499  delete attrp;
3500  std::stringstream errstr;
3501  errstr << "Doublet state from token " << token.Str() << rTr.FileLine();
3502  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3503  }
3504  // record state
3505  rStateSet.Insert(index);
3506  // record name if we read the core set
3507  if(&rStateSet==mpStates)
3508  if(name!="") {
3509  mpStateSymbolTable->SetEntry(index, name);
3510  }
3511  // test for attributes
3512  if(!rTr.Eos("State")) {
3513  FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): attribute ?");
3514  attrp->Read(rTr,"",this);
3515  rStateSet.Attribute(index,*attrp);
3516  }
3517  // read end
3518  rTr.ReadEnd("State");
3519  continue;
3520  }
3521 
3522  // read consecutve block of anonymous states
3523  if(token.IsBegin() && token.StringValue() == "Consecutive") {
3524  Token ctag;
3525  rTr.ReadBegin("Consecutive",ctag);
3526  Idx idx1=0;
3527  Idx idx2=0;
3528  Token token1,token2;
3529  rTr.Peek(token1);
3530  // figure range a) XML
3531  if(token1.IsEnd() && token.StringValue() == "Consecutive") {
3532  if(ctag.ExistsAttributeInteger("from"))
3533  idx1= (Idx) ctag.AttributeIntegerValue("from");
3534  if(ctag.ExistsAttributeInteger("to"))
3535  idx2= (Idx) ctag.AttributeIntegerValue("to");
3536  }
3537  // figure range a) native
3538  if(token1.IsInteger()) {
3539  rTr.Get(token1);
3540  rTr.Get(token2);
3541  if(!token1.IsInteger() || !token2.IsInteger()) {
3542  delete attrp;
3543  std::stringstream errstr;
3544  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3545  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3546  }
3547  idx1=token1.IntegerValue();
3548  idx2=token2.IntegerValue();
3549  }
3550  // validate range
3551  if(idx1==0 || idx2 < idx1) {
3552  delete attrp;
3553  std::stringstream errstr;
3554  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3555  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3556  }
3557  // perform range
3558  FD_DG("vGenerator(" << this << ")::ReadStateSet(\"" << rTr.FileName() << "\"): consecutive range " << idx1 << " to " << idx2);
3559  for(Idx index = idx1; index <= idx2; ++index) {
3560  if(!ExistsState(index)) {
3561  delete attrp;
3562  std::stringstream errstr;
3563  errstr << "range not in generator stateset" << rTr.FileLine();
3564  throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
3565  }
3566  rStateSet.Insert(index);
3567  }
3568  rTr.ReadEnd("Consecutive");
3569  continue;
3570  }
3571 
3572  // Ignore other sections
3573  if(token.IsBegin()) {
3574  rTr.ReadEnd(token.StringValue());
3575  continue;
3576  }
3577 
3578  // cannot process token
3579  delete attrp;
3580  std::stringstream errstr;
3581  errstr << "Section " << rLabel << ": Invalid token" << rTr.FileLine() << ": " << token.Str();
3582  throw Exception("vGenerator::ReadStateSet", errstr.str(), 50);
3583  }
3584  rTr.ReadEnd(rLabel);
3585  // dispose attribute
3586  delete attrp;
3587 }
3588 
3589 // XReadStateSet(tr, rLabel, rStateSet)
3590 void vGenerator::XReadStateSet(TokenReader& rTr, StateSet& rStateSet, const std::string& rLabel) const {
3591  FD_DG("vGenerator(" << this << ")::XReadStateSet(\"" << rLabel<< "\")");
3592  AttributeVoid* attrp = rStateSet.AttributeType()->New();
3593  FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name());
3594  // Clear my set
3595  rStateSet.Clear();
3596  // Figure section
3597  std::string label=rLabel;
3598  if(label=="") label=rStateSet.Name();
3599  if(label=="") label="StateSet";
3600  // Read begin
3601  Token btag;
3602  rTr.ReadBegin(label,btag);
3603  // Use name if provided (std is no name)
3604  rStateSet.Name("");
3605  if(btag.ExistsAttributeString("name"))
3606  rStateSet.Name(btag.AttributeStringValue("name"));
3607  // Scan my section
3608  while(!rTr.Eos(label)) {
3609  Token sttag;
3610  rTr.Get(sttag);
3611  // Read consecutive block of anonymous states
3612  if(sttag.IsBegin("Consecutive")) {
3613  // Get range
3614  Idx idx1=0;
3615  Idx idx2=0;
3616  if(sttag.ExistsAttributeInteger("from"))
3617  idx1= (Idx) sttag.AttributeIntegerValue("from");
3618  if(sttag.ExistsAttributeInteger("to"))
3619  idx2= (Idx) sttag.AttributeIntegerValue("to");
3620  // Insist in valid range
3621  if(idx1==0 || idx2 < idx1) {
3622  delete attrp;
3623  std::stringstream errstr;
3624  errstr << "Invalid range of consecutive states" << rTr.FileLine();
3625  throw Exception("vGenerator::XReadStates", errstr.str(), 80);
3626  }
3627  FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): consecutive range " << idx1 << " to " << idx2);
3628  for(Idx index = idx1; index <= idx2; ++index) {
3629  if(rStateSet.Exists(index)) {
3630  delete attrp;
3631  std::stringstream errstr;
3632  errstr << "Doublet state index " << index << " " << rTr.FileLine();
3633  throw Exception("vGenerator::XReadStates", errstr.str(), 80);
3634  }
3635  rStateSet.Insert(index);
3636  }
3637  // Done: consecutive
3638  rTr.ReadEnd("Consecutive");
3639  continue;
3640  }
3641  // Ignore other sections
3642  if(!sttag.IsBegin("State")) {
3643  if(sttag.IsBegin())
3644  rTr.ReadEnd(sttag.StringValue());
3645  continue;
3646  }
3647  // Its a state
3648  std::string name="";
3649  if(sttag.ExistsAttributeString("name"))
3650  name=sttag.AttributeStringValue("name");
3651  Idx index=0;
3652  if(sttag.ExistsAttributeInteger("id"))
3653  index=sttag.AttributeIntegerValue("id");
3654  FD_DG("vGenerator::XReadStateSet(): got idx " << index << " " << name);
3655  // reconstruct index from name if possible
3656  if(index==0) {
3657  index=StateIndex(name);
3658  }
3659  // failed to figure index
3660  if(index==0) {
3661  delete attrp;
3662  std::stringstream errstr;
3663  errstr << "Cannot figure index for state token " << sttag.Str() << rTr.FileLine();
3664  throw Exception("vGenerator::XReadStateSet", errstr.str(), 80);
3665  }
3666  // dont allow doublets
3667  if(rStateSet.Exists(index)) {
3668  delete attrp;
3669  std::stringstream errstr;
3670  errstr << "Doublet state from token " << sttag.Str() << rTr.FileLine();
3671  throw Exception("vGenerator::XReadStateSet", errstr.str(), 80);
3672  }
3673  // record state
3674  rStateSet.Insert(index);
3675  // record name if we read the core set
3676  if(&rStateSet==mpStates)
3677  if(name!="") {
3678  mpStateSymbolTable->SetEntry(index, name);
3679  }
3680  // test for attributes and such
3681  while(!rTr.Eos("State")) {
3682  Token token;
3683  rTr.Peek(token);
3684  // marking (if this is the main state set)
3685  Token mtag;
3686  if(token.IsBegin("Initial") && (&rStateSet==mpStates)) {
3687  rTr.ReadBegin("Initial",mtag);
3688  bool v=true;
3689  if(mtag.ExistsAttributeInteger("value"))
3690  v=mtag.AttributeIntegerValue("value");
3691  if(v) const_cast<vGenerator*>(this)->SetInitState(index);
3692  rTr.ReadEnd("Initial");
3693  continue;
3694  }
3695  if(token.IsBegin("Marked") && (&rStateSet==mpStates)) {
3696  rTr.ReadBegin("Marked",mtag);
3697  bool v=true;
3698  if(mtag.ExistsAttributeInteger("value"))
3699  v=mtag.AttributeIntegerValue("value");
3700  if(v) const_cast<vGenerator*>(this)->SetMarkedState(index);
3701  rTr.ReadEnd("Marked");
3702  continue;
3703  }
3704  // read attribute
3705  FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): attribute ?");
3706  attrp->Read(rTr,"",this);
3707  rStateSet.Attribute(index,*attrp);
3708  // break on first unknown/undigested
3709  break;
3710  }
3711  // read end
3712  rTr.ReadEnd("State");
3713  }
3714  rTr.ReadEnd(label);
3715  // dispose attribute
3716  delete attrp;
3717  FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): done");
3718 }
3719 
3720 
3721 
3722 // ReadTransRel(tr)
3724  FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\")");
3725  AttributeVoid* attrp = mpTransRel->AttributeType()->New();
3726  FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name());
3727 
3728  // sense begin
3729  std::string label="";
3730  Token token;
3731  rTr.Peek(token);
3732  if(token.IsBegin("TransRel")) label="TransRel";
3733  if(token.IsBegin("T")) label="T";
3734  if(label=="") {
3735  std::stringstream errstr;
3736  errstr << "Reading TransRel failed in " << rTr.FileLine() << ": no valid begin token";
3737  throw Exception("vGenerator::ReadTransRel", errstr.str(), 50);
3738  }
3739  rTr.ReadBegin(label);
3740 
3741  // 2.24e: allow for new states or new events if not specified so far
3742  bool isx = StateSet().Empty();
3743  bool isn = StateSet().Empty();
3744  bool ien = Alphabet().Empty();
3745 
3746  // read section
3747  try {
3748  while(!rTr.Eos(label)) {
3749 
3750  // local vars
3751  Token x1t;
3752  Token x2t;
3753  Token evt;
3754 
3755  // clear my transition
3756  Idx x1 = 0, ev = 0, x2 = 0;
3757 
3758  // 1: the x1 token
3759  rTr >> x1t;
3760  if(x1t.IsInteger()) {
3761  x1=x1t.IntegerValue();
3762  if((!ExistsState(x1)) && isx) {InsState(x1); isn=false; };
3763  } else if(x1t.IsString()) {
3764  x1=StateIndex(x1t.StringValue());
3765  if(x1==0 && isn) { x1=InsState(x1t.StringValue()); isx=false; };
3766  } else break;
3767 
3768  // 2: the event token
3769  rTr >> evt;
3770  if(evt.IsString()) {
3771  evt.StringValue();
3772  ev=EventIndex(evt.StringValue());
3773  if((!ExistsEvent(ev)) && ien) {ev = InsEvent(evt.StringValue());};
3774  } else break;
3775 
3776  // 3: the x2 token
3777  rTr >> x2t;
3778  if(x2t.IsInteger()) {
3779  x2=x2t.IntegerValue();
3780  if((!ExistsState(x2)) && isx) {InsState(x2); isn=false; };
3781  } else if(x2t.IsString()) {
3782  x2=StateIndex(x2t.StringValue());
3783  if(x2==0 && isn) { x2=InsState(x2t.StringValue()); isx=false; };
3784  } else break;
3785 
3786  // 4: attributes
3787  attrp->Read(rTr,"",this);
3788 
3789  // 5: skip unknown attributes
3790  AttributeVoid::Skip(rTr);
3791 
3792  // check values
3793  if(!ExistsState(x1)){
3794  std::stringstream errstr;
3795  errstr << "invalid state x1 " << x1t.StringValue() << " " << rTr.FileLine();
3796  throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
3797  }
3798  if(!ExistsState(x2)){
3799  std::stringstream errstr;
3800  errstr << "invalid state x2 " << x2t.StringValue() << " " << rTr.FileLine();
3801  throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
3802  }
3803  if(!ExistsEvent(ev)) {
3804  std::stringstream errstr;
3805  errstr << "invalid event " << evt.StringValue() << " " << rTr.FileLine();
3806  throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
3807  }
3808 
3809  // insert transition
3810  Transition trans=Transition(x1,ev,x2);
3811  SetTransition(trans);
3812  TransAttribute(trans,*attrp);
3813 
3814  } // end while
3815  } // end try
3816 
3817  catch (faudes::Exception& oex) {
3818  delete attrp;
3819  std::stringstream errstr;
3820  errstr << "Reading TransRel failed in " << rTr.FileLine() << " " << oex.What();
3821  throw Exception("vGenerator::ReadTransRel", errstr.str(), 50);
3822  }
3823 
3824  // read end token
3825  rTr.ReadEnd(label);
3826 
3827  // done
3828  FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\"): done");
3829 
3830  // dispose attribute
3831  delete attrp;
3832 }
3833 
3834 
3835 // XReadTransRel(tr)
3837  FD_DG("vGenerator(" << this << ")::XReadTransRel()");
3838  AttributeVoid* attrp = mpTransRel->AttributeType()->New();
3839  FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name());
3840  // Clear my set
3841  mpTransRel->Clear();
3842  mpTransRel->Name("TransRel");
3843  // Read begin
3844  Token btag;
3845  rTr.ReadBegin("TransitionRelation",btag);
3846  // Scan my section
3847  while(!rTr.Eos("TransitionRelation")) {
3848  Token trtag;
3849  rTr.Get(trtag);
3850  // Ignore other sections
3851  if(!trtag.IsBegin("Transition")) {
3852  if(trtag.IsBegin())
3853  rTr.ReadEnd(trtag.StringValue());
3854  continue;
3855  }
3856  // Its a transition
3857  Idx x1=0;
3858  Idx x2=0;
3859  Idx ev=0;
3860  std::string evname;
3861  std::string x1name;
3862  std::string x2name;
3863  if(trtag.ExistsAttributeInteger("x1"))
3864  x1=trtag.AttributeIntegerValue("x1");
3865  if(trtag.ExistsAttributeInteger("x2"))
3866  x2=trtag.AttributeIntegerValue("x2");
3867  if(trtag.ExistsAttributeString("x1"))
3868  x1name=trtag.AttributeStringValue("x1");
3869  if(trtag.ExistsAttributeString("x2"))
3870  x2name=trtag.AttributeStringValue("x2");
3871  if(trtag.ExistsAttributeString("event"))
3872  evname=trtag.AttributeStringValue("event");
3873  // Interpret names
3874  ev=EventIndex(evname);
3875  if(x1==0) x1=StateIndex(x1name);
3876  if(x2==0) x2=StateIndex(x2name);
3877  // Report
3878  FD_DG("vGenerator::XReadTransRel(): got transition " << TStr(Transition(x1,ev,x2)));
3879  // test 1: components specified
3880  if(x1==0 || x2==0 || ev==0) {
3881  delete attrp;
3882  std::stringstream errstr;
3883  errstr << "Invalid transition at token " << trtag.Str() << rTr.FileLine();
3884  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3885  }
3886  // test 2: no doublets
3887  if(ExistsTransition(x1,ev,x2)) {
3888  delete attrp;
3889  std::stringstream errstr;
3890  errstr << "Doublet transition at token " << trtag.Str() << rTr.FileLine();
3891  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3892  }
3893  // test 3: components must exist
3894  if(!ExistsState(x1)){
3895  delete attrp;
3896  std::stringstream errstr;
3897  errstr << "Invalid state x1 " << x1 << " " << rTr.FileLine();
3898  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3899  }
3900  if(!ExistsState(x2)){
3901  delete attrp;
3902  std::stringstream errstr;
3903  errstr << "Invalid state x2 " << x2 << " " << rTr.FileLine();
3904  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3905  }
3906  if(!ExistsEvent(ev)){
3907  delete attrp;
3908  std::stringstream errstr;
3909  errstr << "Invalid event " << evname << " " << rTr.FileLine();
3910  throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
3911  }
3912  // record transition
3913  SetTransition(x1,ev,x2);
3914  // test for attribute
3915  Token token;
3916  rTr.Peek(token);
3917  if(!token.IsEnd("Transition")) {
3918  // read attribute
3919  attrp->Read(rTr,"",this);
3920  TransAttribute(Transition(x1,ev,x2),*attrp);
3921  }
3922  // read end
3923  rTr.ReadEnd("Transition");
3924  }
3925  rTr.ReadEnd("TransitionRelation");
3926  // dispose attribute
3927  delete attrp;
3928  FD_DG("vGenerator(" << this << ")::XReadTransRel(\"" << rTr.FileName() << "\"): done");
3929 }
3930 
3931 // EStr(index)
3932 std::string vGenerator::EStr(Idx index) const {
3933  std::string name = EventName(index);
3934  return name+"#"+faudes::ToStringInteger(index);
3935 }
3936 
3937 // SStr(index)
3938 std::string vGenerator::SStr(Idx index) const {
3939  std::string name = StateName(index);
3940  if(name == "") name=ToStringInteger(index);
3941  return name+"#"+faudes::ToStringInteger(index);
3942 }
3943 
3944 // TStr(index)
3945 std::string vGenerator::TStr(const Transition& trans) const {
3946  return SStr(trans.X1) + "--(" + EStr(trans.Ev) + ")-->" + SStr(trans.X2);
3947 }
3948 
3949 
3950 // GraphWrite(rFileName,rOutFormat)
3951 void vGenerator::GraphWrite(const std::string& rFileName, const std::string& rOutFormat,
3952  const std::string& rDotExec) const {
3953  FD_DG("vGenerator::GraphWrite(...): " << typeid(*this).name());
3954  // generate temp dot input file
3955  std::string dotin = CreateTempFile();
3956  if(dotin == "") {
3957  std::stringstream errstr;
3958  errstr << "Exception opening temp file";
3959  throw Exception("vGenerator::GraphWrite", errstr.str(), 2);
3960  }
3961  try{
3962  DotWrite(dotin);
3963  }
3964  catch (faudes::Exception& exception) {
3965  FileDelete(dotin);
3966  std::stringstream errstr;
3967  errstr << "Exception writing dot input file";
3968  throw Exception("vGenerator::GraphWrite", errstr.str(), 2);
3969  }
3970  try{
3971  faudes::ProcessDot(dotin,rFileName,rOutFormat,rDotExec);
3972  }
3973  catch (faudes::Exception& exception) {
3974  FileDelete(dotin);
3975  std::stringstream errstr;
3976  errstr << "Exception processing dot file";
3977  throw Exception("vGenerator::GraphWrite", errstr.str(), 3);
3978  }
3979  FileDelete(dotin);
3980 }
3981 
3982 // rti wrapper
3983 bool IsAccessible(const vGenerator& rGen) {
3984  return rGen.IsAccessible();
3985 }
3986 
3987 // rti wrapper
3988 bool IsCoaccessible(const vGenerator& rGen) {
3989  return rGen.IsCoaccessible();
3990 }
3991 
3992 // rti wrapper
3993 bool IsTrim(const vGenerator& rGen) {
3994  return rGen.IsTrim();
3995 }
3996 
3997 
3998 // rti wrapper
3999 bool IsComplete(const vGenerator& rGen) {
4000  return rGen.IsComplete();
4001 }
4002 
4003 // rti wrapper
4004 bool IsComplete(const vGenerator& rGen, const StateSet& rStateSet) {
4005  return rGen.IsComplete(rStateSet);
4006 }
4007 
4008 // rti wrapper
4009 bool IsComplete(const vGenerator& rGen, const EventSet& rSigmaO) {
4010  return rGen.IsComplete(rSigmaO);
4011 }
4012 
4013 // rti wrapper
4014 bool IsDeterministic(const vGenerator& rGen) {
4015  return rGen.IsDeterministic();
4016 }
4017 
4018 
4019 // rti wrapper
4020 void Accessible(vGenerator& rGen) {
4021  rGen.Accessible();
4022 }
4023 
4024 // rti wrapper
4025 void Accessible(const vGenerator& rGen, vGenerator& rRes) {
4026  rRes=rGen;
4027  rRes.Accessible();
4028 }
4029 
4030 // rti wrapper
4032  rGen.Coaccessible();
4033 }
4034 
4035 // rti wrapper
4036 void Coaccessible(const vGenerator& rGen, vGenerator& rRes) {
4037  rRes=rGen;
4038  rRes.Coaccessible();
4039 }
4040 
4041 // rti wrapper
4042 void Complete(vGenerator& rGen) {
4043  rGen.Complete();
4044 }
4045 
4046 // rti wrapper
4047 void Complete(const vGenerator& rGen, vGenerator& rRes) {
4048  rRes=rGen;
4049  rRes.Complete();
4050 }
4051 
4052 // rti wrapper
4053 void Complete(vGenerator& rGen, const EventSet& rSigmaO) {
4054  rGen.Complete(rSigmaO);
4055 }
4056 
4057 // rti wrapper
4058 void Complete(const vGenerator& rGen, const EventSet& rSigmaO, vGenerator& rRes) {
4059  rRes=rGen;
4060  rRes.Complete(rSigmaO);
4061 }
4062 
4063 // rti wrapper
4064 void Trim(vGenerator& rGen) {
4065  rGen.Trim();
4066 }
4067 
4068 // rti wrapper
4069 void Trim(const vGenerator& rGen, vGenerator& rRes) {
4070  rRes=rGen;
4071  rRes.Trim();
4072 }
4073 
4074 
4075 // rti wrapper
4077  rGen.InjectMarkedStates(rGen.States());
4078 }
4079 
4080 // rti wrapper
4081 void AlphabetExtract(const vGenerator& rGen, EventSet& rRes) {
4082  // This function is an ideal debugging case for lbp_function.cpp.
4083  // FD_WARN("AlphabetExtract(): gen at " << &rGen << " sig at " << &rRes);
4084  // FD_WARN("AlphabetExtract(): gen id " << typeid(rGen).name() << " sig id " << typeid(rRes).name());
4085  rRes = rGen.Alphabet();
4086  // rRes.Write();
4087 }
4088 
4089 // rti convenience function
4090 void SetIntersection(const GeneratorVector& rGenVec, EventSet& rRes) {
4091  // prepare result
4092  rRes.Clear();
4093  // ignore empty
4094  if(rGenVec.Size()==0) return;
4095  // copy first
4096  rRes.Assign(rGenVec.At(0).Alphabet());
4097  // perform intersecttion
4098  for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++)
4099  SetIntersection(rGenVec.At(i).Alphabet(),rRes,rRes);
4100 }
4101 
4102 
4103 // rti convenience function
4104 void SetUnion(const GeneratorVector& rGenVec, EventSet& rRes) {
4105  // prepare result
4106  rRes.Clear();
4107  // ignore empty
4108  if(rGenVec.Size()==0) return;
4109  // copy first
4110  rRes.Assign(rGenVec.At(0).Alphabet());
4111  // perform intersecttion
4112  for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++)
4113  SetUnion(rGenVec.At(i).Alphabet(),rRes,rRes);
4114 }
4115 
4116 // rti convenience function
4117 void SetIntersection(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
4118  SetIntersection(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
4119 }
4120 
4121 // rti convenience function
4122 void SetUnion(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
4123  SetUnion(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
4124 }
4125 
4126 // rti convenience function
4127 void SetDifference(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
4128  SetDifference(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
4129 }
4130 
4131 // rti convenience function
4132 void ApplyRelabelMap(const RelabelMap& rMap, const vGenerator& rGen, vGenerator& rRes) {
4133  EventSet* alph=rGen.Alphabet().Copy();
4134  TransSet* delta=rGen.TransRel().Copy();
4135  ApplyRelabelMap(rMap,*alph,*alph);
4136  ApplyRelabelMap(rMap,*delta,*delta);
4137  rRes.Assign(rGen);
4138  rRes.InjectTransRel(*delta);
4139  rRes.InjectAlphabet(*alph);
4140  delete alph;
4141  delete delta;
4142 }
4143 
4144 
4145 } // name space
4146 
4147 
4148 /***** NOTES ****/
4149 
4150 /*
4151 class A {
4152 public:
4153  virtual A& operator=(const A& src) { std::cout << "A=A/"; return *this; };
4154  virtual A& assign(const A& src) { std::cout << "A=A/"; return *this; };
4155  int a;
4156 };
4157 class B : public A {
4158 public:
4159  virtual A& operator=(const A& src) { std::cout<<"B=A/"; return *this;};
4160  virtual A& assign(const A& src) { std::cout<<"B=A/"; return *this; };
4161  int b;
4162 };
4163 
4164 
4165 
4166 int main() {
4167 
4168  B mD1;
4169  B mD2;
4170  mD1=mD2; // << fails here, dont know why
4171  mD1.assign(mD2);
4172  A& rD1 = mD1;
4173  A& rD2 = mD2;
4174  rD1=rD2;
4175 }
4176 
4177 */
#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:1075
virtual const char * What() const
Type & operator=(const Type &rSrc)
Definition: cfl_types.cpp:104
std::string mObjectName
Definition: cfl_types.h:1231
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
virtual Type * Copy(void) const
Definition: cfl_types.cpp:60
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:2378
virtual TBaseSet & AssignWithoutAttributes(const TBaseSet &rSourceSet)
Definition: cfl_baseset.h:2444
bool Empty(void) const
Definition: cfl_baseset.h:1904
void SetDifference(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1149
bool Exists(const T &rElem) const
Definition: cfl_baseset.h:2322
virtual void Attributes(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2453
IndexSet StateSet
Definition: cfl_indexset.h:296
virtual void Clear(void)
Definition: cfl_baseset.h:2104
TTransSet< TransSort::X1EvX2 > TransSet
Iterator Find(const T &rElem) const
Definition: cfl_baseset.h:2317
Idx AttributesSize(void) const
Definition: cfl_baseset.h:2389
Iterator End(void) const
Definition: cfl_baseset.h:2098
TTransSet< TransSort::X1X2Ev > TransSetX1X2Ev
virtual void RestrictSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2271
virtual void InsertSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2194
virtual AttributeVoid * Attributep(const T &rElem)
Definition: cfl_baseset.h:2486
Iterator Begin(void) const
Definition: cfl_baseset.h:2093
NameSet EventSet
Definition: cfl_nameset.h:546
virtual const AttributeVoid & Attribute(const T &rElem) const
Definition: cfl_baseset.h:2497
virtual bool Erase(const T &rElem)
Definition: cfl_baseset.h:2226
void SetUnion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1090
void SetIntersection(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
Definition: cfl_baseset.h:1120
virtual void EraseSet(const TBaseSet &rOtherSet)
Definition: cfl_baseset.h:2249
Idx Size(void) const
Definition: cfl_baseset.h:1899
void ClearAttributes(void)
Definition: cfl_baseset.h:2394
virtual void ClrAttribute(const T &rElem)
Definition: cfl_baseset.h:2524
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 ApplyRelabelMap(const RelabelMap &rMap, const vGenerator &rGen, vGenerator &rRes)
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:248
bool FileDelete(const std::string &rFilename)
Definition: cfl_utils.cpp:433
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
AttrType AttributeVoid

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