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