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

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