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

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