cfl_generator.cpp

Go to the documentation of this file.
00001 /** @file cfl_generator.cpp Class vGenerator */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2006  Bernd Opitz
00006    Copyright (C) 2007  Thomas Moor
00007    Exclusive copyright is granted to Klaus Schmidt
00008 
00009    This library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Lesser General Public
00011    License as published by the Free Software Foundation; either
00012    version 2.1 of the License, or (at your option) any later version.
00013 
00014    This library is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE.  See the GNU
00017    Lesser General Public License for more details.
00018 
00019    You should have received a copy of the GNU Lesser General Public
00020    License along with this library; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00022 
00023 
00024 #include "cfl_generator.h"
00025 #include <stack>
00026 
00027 
00028 namespace faudes {
00029 
00030 // msObjectCount (static) 
00031 Idx vGenerator::msObjectCount = 0;
00032 
00033 // State names default (static) 
00034 bool vGenerator::msStateNamesEnabledDefault = true;
00035 
00036 // Reindex default (static) 
00037 bool vGenerator::msReindexOnWriteDefault = false;
00038 
00039 // static default prototypes (construct on first use design pattern)
00040 const EventSet& vGenerator::AlphabetVoid(void) {
00041   static EventSet* pstatic = new EventSet();
00042   return *pstatic;
00043 }
00044 const StateSet& vGenerator::StatesVoid(void) {
00045   static StateSet* pstatic = new StateSet();
00046   return *pstatic;
00047 }
00048 const TransSet& vGenerator::TransRelVoid(void) {
00049   static TransSet* pstatic = new TransSet();
00050   return *pstatic;
00051 }
00052 const AttributeVoid& vGenerator::GlobalVoid(void) {
00053   static AttributeVoid* pstatic = new AttributeVoid();
00054   return *pstatic;
00055 }
00056 
00057 
00058 
00059 // constructor
00060 vGenerator::vGenerator(void) : 
00061   // base
00062   Type(),
00063   // my name
00064   mMyName("Generator"),
00065   // have std symboltables
00066   mpStateSymbolTable(&mStateSymbolTable),
00067   mpEventSymbolTable(GlobalEventSymbolTablep()),
00068   // other members
00069   mStateNamesEnabled(msStateNamesEnabledDefault),  
00070   mReindexOnWrite(msReindexOnWriteDefault),  
00071   // initialise heap members
00072   mpAlphabet(0),
00073   mpStates(0),
00074   mpTransRel(0),
00075   mpGlobalAttribute(0),
00076   // initialise prototypes
00077   pAlphabetPrototype(&AlphabetVoid()),
00078   pStatesPrototype(&StatesVoid()),
00079   pTransRelPrototype(&TransRelVoid()),
00080   pGlobalPrototype(&GlobalVoid())
00081 {
00082   FAUDES_OBJCOUNT_INC("Generator");
00083   FD_DG("vGenerator(" << this << ")::vGenerator()");
00084   // track generator objects
00085   msObjectCount++; 
00086   mId = msObjectCount;
00087   // allocate core members
00088   NewCore();
00089   // fix std names
00090   mInitStates.Name("InitStates");
00091   mMarkedStates.Name("MarkedStates");
00092 }
00093 
00094 // copy constructor
00095 vGenerator::vGenerator(const vGenerator& rOtherGen) :
00096   // my name
00097   mMyName("Generator"),
00098   // have std symboltables
00099   mpStateSymbolTable(&mStateSymbolTable),
00100   mpEventSymbolTable(GlobalEventSymbolTablep()),
00101   // other members
00102   mStateNamesEnabled(msStateNamesEnabledDefault),  
00103   mReindexOnWrite(msReindexOnWriteDefault),  
00104   // initialise heap members
00105   mpAlphabet(0),
00106   mpStates(0),
00107   mpTransRel(0),
00108   mpGlobalAttribute(0),
00109   // initialise prototypes
00110   pAlphabetPrototype(&AlphabetVoid()),
00111   pStatesPrototype(&StatesVoid()),
00112   pTransRelPrototype(&TransRelVoid()),
00113   pGlobalPrototype(&GlobalVoid())
00114 {
00115   FAUDES_OBJCOUNT_INC("Generator");
00116   FD_DG("vGenerator(" << this << ")::vGenerator(" << &rOtherGen << ")");
00117   // track generator objects
00118   msObjectCount++; 
00119   mId = msObjectCount;
00120   // allocate core members
00121   NewCore();
00122   // perform copy
00123   Assign(rOtherGen);
00124 }
00125 
00126 // construct from file
00127 vGenerator::vGenerator(const std::string& rFileName) : 
00128   // my name
00129   mMyName("Generator"),
00130   // have std symboltables
00131   mpStateSymbolTable(&mStateSymbolTable),
00132   mpEventSymbolTable(GlobalEventSymbolTablep()),
00133   // other members
00134   mStateNamesEnabled(msStateNamesEnabledDefault),  
00135   mReindexOnWrite(msReindexOnWriteDefault),  
00136   // initialise heap members
00137   mpAlphabet(0),
00138   mpStates(0),
00139   mpTransRel(0),
00140   mpGlobalAttribute(0),
00141   // initialise prototypes
00142   pAlphabetPrototype(&AlphabetVoid()),
00143   pStatesPrototype(&StatesVoid()),
00144   pTransRelPrototype(&TransRelVoid()),
00145   pGlobalPrototype(&GlobalVoid())
00146 {
00147   FAUDES_OBJCOUNT_INC("Generator");
00148   FD_DG("vGenerator(" << this << ")::vGenerator(" << rFileName << ")");
00149   // track generator objects
00150   msObjectCount++; 
00151   mId = msObjectCount;
00152   // allocate core members
00153   NewCore();
00154   // fix std names
00155   mInitStates.Name("InitStates");
00156   mMarkedStates.Name("MarkedStates");
00157   // set defaults for file io
00158   mStateNamesEnabled=true;
00159   // do read
00160   Read(rFileName,"Generator");
00161   // restore defaults
00162   mStateNamesEnabled=msStateNamesEnabledDefault;
00163 }
00164 
00165 // construct on heap
00166 vGenerator* vGenerator::New(void) const {
00167   FD_DG("vGenerator(" << this << ")::New()");
00168   // allocate
00169   vGenerator* res = new vGenerator();
00170   // fix configuration
00171   res->EventSymbolTablep(mpEventSymbolTable);
00172   res->mStateNamesEnabled=mStateNamesEnabled;
00173   res->mReindexOnWrite=mReindexOnWrite;  
00174   return res;
00175 }
00176 
00177 // construct on heap
00178 vGenerator* vGenerator::Copy(void) const {
00179   FD_DG("vGenerator(" << this << ")::Copy()");
00180   // copy construct
00181   vGenerator* res = new vGenerator(*this);
00182   return res;
00183 }
00184 
00185 // cast
00186 const Type* vGenerator::Cast(const Type* pOther) const {
00187   return dynamic_cast< const vGenerator* > (pOther);
00188 }
00189 
00190 
00191 // destruct
00192 vGenerator::~vGenerator(void) {
00193   FAUDES_OBJCOUNT_DEC("Generator");
00194   // free my members
00195   DeleteCore();
00196 }
00197 
00198 // configure attribute types
00199 void vGenerator::ConfigureAttributeTypes(const AttributeVoid* pNewGlobalPrototype, 
00200     const StateSet* pNewStatesPrototype, const EventSet* pNewAlphabetPrototype, 
00201     const TransSet* pNewTransRelPrototype) {
00202   FD_DG("vGenerator(" << this << ")::ConfigureAtributes(..)");
00203   pGlobalPrototype= pNewGlobalPrototype;
00204   pStatesPrototype= pNewStatesPrototype;
00205   pAlphabetPrototype= pNewAlphabetPrototype;
00206   pTransRelPrototype= pNewTransRelPrototype;
00207   FD_DG("vGenerator(" << this << ")::ConfigureAtributes(): done");
00208 }
00209 
00210 // indicate new core
00211 void vGenerator::UpdateCore(void) {
00212   // fix std names
00213   if(mpAlphabet) mpAlphabet->Name("Alphabet");
00214   if(mpStates) mpStates->Name("States");
00215   if(mpTransRel) mpTransRel->Name("TransRel");
00216   // fix symbol table
00217   if(mpAlphabet) EventSymbolTablep(mpEventSymbolTable);
00218 }
00219 
00220 // protected helper: allocate core on heap
00221 void vGenerator::NewCore(void) {
00222   DeleteCore();
00223   // allocate (use prototypes, fallback to void attributes)
00224   if(pAlphabetPrototype) mpAlphabet= pAlphabetPrototype->New();
00225   else mpAlphabet = new EventSet();
00226   if(pStatesPrototype) mpStates=pStatesPrototype->New();
00227   else mpStates = new StateSet();
00228   if(pTransRelPrototype) mpTransRel= pTransRelPrototype->New();
00229   else mpTransRel = new TransSet();
00230   if(pGlobalPrototype) mpGlobalAttribute=pGlobalPrototype->New();
00231   else mpGlobalAttribute = new AttributeVoid();
00232   // update callback
00233   UpdateCore();
00234 }
00235   
00236 // protected helper: free core from heap
00237 void vGenerator::DeleteCore(void) {
00238   if(mpAlphabet) delete mpAlphabet; 
00239   if(mpStates) delete mpStates; 
00240   if(mpTransRel) delete mpTransRel; 
00241   if(mpGlobalAttribute) delete mpGlobalAttribute;   
00242   mpAlphabet=0;
00243   mpStates=0;
00244   mpTransRel=0;
00245   mpGlobalAttribute=0;
00246   // update callback
00247   UpdateCore();
00248 }
00249 
00250 
00251 
00252 // copy from other vGenerator (try to convert attributes)
00253 vGenerator& vGenerator::Assign(const vGenerator& rGen) {
00254   FD_DG("vGenerator(" << this << ")::Assign(" << &rGen << ")");
00255   // bail out on match
00256   if(&rGen==this) return *this;
00257   // prepare result (call clear for virtual stuff)
00258   Clear();
00259   // have same event symboltable
00260   EventSymbolTablep(rGen.mpEventSymbolTable);
00261   // copy state symboltable
00262   StateSymbolTable(rGen.mStateSymbolTable);
00263   // set other members
00264   Name(rGen.Name());
00265   StateNamesEnabled(rGen.StateNamesEnabled());
00266   ReindexOnWrite(rGen.ReindexOnWrite());
00267   InjectInitStates(rGen.mInitStates);
00268   InjectMarkedStates(rGen.mMarkedStates);
00269   // core members, try attributes
00270   InjectStates(*rGen.mpStates);
00271   InjectAlphabet(*rGen.mpAlphabet);
00272   InjectTransRel(*rGen.mpTransRel);
00273   GlobalAttributeTry(*rGen.mpGlobalAttribute);
00274 #ifdef FAUDES_DEBUG_CODE
00275   if(!Valid()) {
00276     FD_DG("vGenerator()::Copy(): invalid generator");
00277     DWrite(); 
00278     abort();
00279   }
00280 #endif
00281   return *this;
00282 } 
00283 
00284 // copy from other vGenerator (try to convert attributes)
00285 vGenerator& vGenerator::Assign(const Type& rSrc) {
00286   FD_DG("vGenerator(" << this << ")::Assign([type] " << &rSrc << ")");
00287   // bail out on match
00288   if(&rSrc==this) return *this;
00289   Clear();
00290   const vGenerator* vgen=dynamic_cast<const vGenerator*>(&rSrc);
00291   if(vgen) Assign(*vgen);
00292   return *this;
00293 }
00294 
00295 // copy from other vGenerator (clear attributes)
00296 vGenerator& vGenerator::AssignWithoutAttributes(const vGenerator& rGen) {
00297   FD_DG("vGenerator(" << this << ")::Assign(" << &rGen << ")");
00298   // prepare result (call clear for virtual stuff)
00299   Clear();
00300   // have same event symboltable
00301   EventSymbolTablep(rGen.mpEventSymbolTable);
00302   // copy state symboltable
00303   StateSymbolTable(rGen.mStateSymbolTable);
00304   // set other members
00305   Name(rGen.Name());
00306   StateNamesEnabled(rGen.StateNamesEnabled());
00307   ReindexOnWrite(rGen.ReindexOnWrite());
00308   InjectInitStates(rGen.mInitStates);
00309   InjectMarkedStates(rGen.mMarkedStates);
00310   // core members, ignore attributes
00311   mpStates->AssignWithoutAttributes(rGen.States());
00312   mpAlphabet->AssignWithoutAttributes(rGen.Alphabet());
00313   mpTransRel->AssignWithoutAttributes(rGen.TransRel());
00314 #ifdef FAUDES_DEBUG_CODE
00315   if(!Valid()) {
00316     FD_DG("vGenerator()::Copy(): invalid generator");
00317     DWrite(); 
00318     abort();
00319   }
00320 #endif
00321   return *this;
00322 } 
00323 
00324 
00325 // Move(gen) destructive copy 
00326 void vGenerator::Move(vGenerator& rGen) {
00327   FD_DG("vGenerator(" << this << ")::Move(" << &rGen << ")");
00328   // test types
00329   bool tmm=false;
00330   if(typeid(rGen.Alphabet())!=typeid(Alphabet())) tmm=true;
00331   if(typeid(rGen.States())!=typeid(States())) tmm=true;
00332   if(typeid(rGen.TransRel())!=typeid(TransRel())) tmm=true;
00333   if(typeid(rGen.GlobalAttribute())!=typeid(GlobalAttribute())) tmm=true;
00334   if(tmm) { 
00335     FD_DG("vGenerator(" << this << ")::Move(" << &rGen << "): using std copy");
00336     rGen.Assign(*this);
00337     Clear();
00338     return;
00339   }
00340   // prepare result (call clear for virtual stuff)
00341   rGen.Clear();
00342   // have same event symboltable
00343   rGen.EventSymbolTablep(mpEventSymbolTable);
00344   // copy state symboltable (todo: make this pointer based?)
00345   rGen.StateSymbolTable(mStateSymbolTable);
00346   // copy members
00347   rGen.Name(Name());
00348   rGen.StateNamesEnabled(StateNamesEnabled());
00349   rGen.ReindexOnWrite(ReindexOnWrite());
00350   rGen.InjectInitStates(InitStates());
00351   rGen.InjectMarkedStates(MarkedStates());
00352   // delete destination core
00353   if(rGen.mpStates) delete rGen.mpStates;
00354   if(rGen.mpAlphabet) delete rGen.mpAlphabet;
00355   if(rGen.mpTransRel) delete rGen.mpTransRel;
00356   if(rGen.mpGlobalAttribute) delete rGen.mpGlobalAttribute;
00357   // move and invalidate core members
00358   rGen.mpStates=mpStates;
00359   rGen.mpAlphabet=mpAlphabet;
00360   rGen.mpTransRel=mpTransRel;
00361   rGen.mpGlobalAttribute=mpGlobalAttribute;
00362   mpStates=0;
00363   mpAlphabet=0;
00364   mpTransRel=0;
00365   mpGlobalAttribute=0;
00366   // register core update
00367   rGen.UpdateCore();
00368   // install new empty core members
00369   NewCore();
00370   // clear myself (incl derived classes members)
00371   Clear();
00372 }
00373 
00374 // operator =
00375 vGenerator& vGenerator::operator = (const vGenerator& rOtherGen) {
00376   FD_DG("vGenerator(" << this << ")::operator = " << &rOtherGen);
00377   return Assign(rOtherGen);
00378 }
00379 
00380 // Version(idx)
00381 void vGenerator::Version(Idx version, vGenerator& rResGen) const {
00382   FD_DG("vGenerator(" << this << ")::Version(" << version << ")");
00383   std::ostringstream o;
00384   o << version;
00385   Version(o.str(),rResGen);
00386 }
00387 
00388 // Version(string)
00389 void vGenerator::Version(const std::string& rVersion, vGenerator& rResGen) const {
00390   FD_DG("vGenerator(" << this << ")::Version(" << rVersion << ")");
00391   // second arg must not be us 
00392   if(this==&rResGen) {
00393     std::stringstream errstr;
00394     errstr << "Destination must not match source.";
00395     throw Exception("vGenerator::Version(string)", errstr.str(), 96);
00396   }
00397   // prepare Empty generator
00398   rResGen.Clear();
00399   rResGen.GlobalAttribute(GlobalAttribute());
00400   EventSet::Iterator eit;
00401   StateSet::Iterator lit;
00402   TransSet::Iterator tit;
00403   std::map<Idx,Idx> eventoldnewmap;
00404   rResGen.Name(Name()+"_"+rVersion);
00405   // create versioned mAlphabet
00406   for (eit = AlphabetBegin(); eit != AlphabetEnd(); ++eit) {
00407     Idx newevent= rResGen.InsEvent(EventName(*eit)+"_"+rVersion); 
00408     eventoldnewmap[*eit] = newevent;
00409     rResGen.EventAttribute(newevent,EventAttribute(*eit));
00410   }
00411   // create new stateset
00412   for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
00413     rResGen.InsState(*lit);
00414     rResGen.StateAttribute(*lit,StateAttribute(*lit)); //would be faster if directly copied ?
00415     if (StateName(*lit) != "") rResGen.StateName(*lit,StateName(*lit));
00416   }
00417   // created versioned transrel
00418   for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
00419     Transition trans=Transition(tit->X1, eventoldnewmap[tit->Ev], tit->X2);
00420     rResGen.SetTransition(trans);
00421     rResGen.TransAttribute(trans, TransAttribute(*tit));
00422   }
00423   // set i/m states
00424   rResGen.mInitStates=mInitStates;
00425   rResGen.mMarkedStates=mMarkedStates;
00426   // behavioural flags
00427   rResGen.mStateNamesEnabled = mStateNamesEnabled;
00428   rResGen.mReindexOnWrite = mReindexOnWrite;
00429 }
00430 
00431 
00432 // Version(string,string)
00433 void vGenerator::Version(const std::string& rPattern, const std::string& rReplacement, vGenerator& rResGen) const {
00434   FD_DG("vGenerator(" << this << ")::Version(" << rPattern << ", " << rReplacement << ", ...)");
00435   // second arg must not be us 
00436   if(this==&rResGen) {
00437     std::stringstream errstr;
00438     errstr << "Destination must not match source.";
00439     throw Exception("vGenerator::Version(string,string)", errstr.str(), 96);
00440   }
00441   // ignore invalid pattern
00442   if(rPattern.empty()) {
00443     rResGen.Assign(*this);
00444     return;
00445   }
00446   // trivial case
00447   if(rPattern==rReplacement) {
00448     rResGen.Assign(*this);
00449     return;
00450   }
00451   // prepare Empty generator
00452   rResGen.Clear();
00453   rResGen.GlobalAttribute(GlobalAttribute());
00454   rResGen.Name(Name()+"_v");
00455   EventSet::Iterator eit;
00456   StateSet::Iterator lit;
00457   TransSet::Iterator tit;
00458   std::map<Idx,Idx> eventoldnewmap;
00459   // create versioned mAlphabet
00460   std::string newstring;
00461   std::string::size_type pos = 0;
00462   int patternlength=rPattern.size();
00463   int replacementlength=rReplacement.size();
00464   for (eit = AlphabetBegin(); eit != AlphabetEnd(); ++eit) {
00465     // search for all pattern occurences in event name and replace
00466     newstring=EventName(*eit);
00467     pos=0;
00468     while( (pos = newstring.find(rPattern, pos)) != std::string::npos ) {
00469         newstring.replace(pos, patternlength, rReplacement);
00470         //pos++;
00471         pos=pos+replacementlength;
00472     }
00473     Idx newevent= rResGen.InsEvent(newstring); 
00474     eventoldnewmap[*eit] = newevent;
00475     rResGen.EventAttribute(newevent,EventAttribute(*eit));
00476   }
00477   // have a nice neme too
00478   newstring=Name();
00479   pos=0;
00480   while( (pos = newstring.find(rPattern, pos)) != std::string::npos ) {
00481     newstring.replace(pos, patternlength, rReplacement);
00482     pos=pos+replacementlength;
00483   }
00484   rResGen.Name(newstring);
00485   // create new stateset
00486   for(lit = StatesBegin(); lit != StatesEnd(); ++lit) {
00487     rResGen.InsState(*lit);
00488     rResGen.StateAttribute(*lit,StateAttribute(*lit)); //would be faster if directly copied ?
00489     if(StateName(*lit) != "") rResGen.StateName(*lit,StateName(*lit));
00490   }
00491   // created versioned transrel
00492   for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
00493     Transition trans=Transition(tit->X1, eventoldnewmap[tit->Ev], tit->X2);
00494     rResGen.SetTransition(trans);
00495     rResGen.TransAttribute(trans, TransAttribute(*tit));
00496   }
00497   // set i/m states
00498   rResGen.mInitStates=mInitStates;
00499   rResGen.mMarkedStates=mMarkedStates;
00500   // behavioural flags
00501   rResGen.mStateNamesEnabled = mStateNamesEnabled;
00502   rResGen.mReindexOnWrite = mReindexOnWrite;
00503 }
00504 
00505 
00506 // Name(rName)
00507 void vGenerator::Name(const std::string& rName) {
00508   FD_DV("vGenerator(" << this << ")::Name(\"" << rName << "\")");
00509   mMyName = rName;
00510 }
00511 
00512 // Name()
00513 const std::string& vGenerator::Name(void) const {
00514   return mMyName;
00515 }
00516 
00517 // Valid()
00518 bool vGenerator::Valid(void) {
00519   FD_DG("vGenerator(" << this << ")::Valid()");
00520   // core members on heap
00521   if(mpAlphabet==0) return false;
00522   if(mpStates==0) return false;
00523   if(mpTransRel==0) return false;
00524   if(mpGlobalAttribute==0) return false;
00525   // transitions to be known
00526   TransSet::Iterator tit;
00527   StateSet::Iterator lit;
00528   for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
00529     if(! ExistsState(tit->X1)) return false;
00530     if(! ExistsEvent(tit->Ev)) return false;
00531     if(! ExistsState(tit->X2)) return false;
00532   }
00533   // init states to be known
00534   for(lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) 
00535     if(! ExistsState(static_cast<Idx>(*lit))) return false;
00536   for(lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) 
00537     if(! ExistsState(static_cast<Idx>(*lit))) return false;
00538   // sets to have proper names
00539   if(mpAlphabet->Name() != "Alphabet") return false;
00540   if(mpStates->Name() != "States") return false;
00541   if(mInitStates.Name() != "InitStates") return false;
00542   if(mMarkedStates.Name() != "MarkedStates") return false;
00543   // event symbol table
00544   NameSet::Iterator eit;
00545   for(eit = AlphabetBegin(); eit != AlphabetEnd(); eit ++) {
00546     if(EventName(*eit)=="") return false;
00547   }
00548   // done
00549   return true;
00550 }
00551 
00552 // AlphabetSize()
00553 Idx vGenerator::AlphabetSize(void) const {
00554   return mpAlphabet->Size();
00555 }
00556 
00557 // Size()
00558 Idx vGenerator::Size(void) const {
00559   return mpStates->Size();
00560 }
00561 
00562 // Clear()
00563 void vGenerator::Clear(void) {
00564   FD_DG("vGenerator(" << this << ")::Clear()");
00565   mpAlphabet->Clear();
00566   mpStates->Clear();
00567   mpStateSymbolTable->Clear();
00568   mpTransRel->Clear();
00569   mInitStates.Clear();
00570   mMarkedStates.Clear();
00571   ClearGlobalAttribute();
00572 }
00573 
00574 // ClearGlobalAttribute()
00575 void vGenerator::ClearGlobalAttribute(void) {
00576   mpGlobalAttribute->Clear(); 
00577 }
00578 
00579 // ClearStateAttributes()
00580 void vGenerator::ClearStateAttributes(void) {
00581   mpStates->ClearAttributes();
00582 }
00583 
00584 // ClearEventAttributes()
00585 void vGenerator::ClearEventAttributes(void) {
00586   mpAlphabet->ClearAttributes();
00587 }
00588 
00589 // ClearTransAttributes()
00590 void vGenerator::ClearTransAttributes(void) {
00591   mpTransRel->ClearAttributes();
00592 }
00593 
00594 // ClearAttributes()
00595 void vGenerator::ClearAttributes(void) {
00596   ClearGlobalAttribute();
00597   ClearStateAttributes();
00598   ClearEventAttributes();
00599   ClearTransAttributes();
00600 }
00601 
00602 
00603 // ClearStates()
00604 void vGenerator::ClearStates(void) {
00605   mpStates->Clear();
00606   mpTransRel->Clear();
00607   mInitStates.Clear();
00608   mMarkedStates.Clear();
00609   mpStateSymbolTable->Clear();
00610 }
00611 
00612 // TransRelSize()
00613 Idx vGenerator::TransRelSize(void) const {
00614   return mpTransRel->Size();
00615 }
00616 
00617 // InitStatesSize()
00618 Idx vGenerator::InitStatesSize(void) const {
00619   return mInitStates.Size();
00620 }
00621 
00622 // MarkedStatesSize()
00623 Idx vGenerator::MarkedStatesSize(void) const {
00624   return mMarkedStates.Size();
00625 }
00626 
00627 // AlphabetEmpty()
00628 bool vGenerator::AlphabetEmpty(void) const {
00629   return mpAlphabet->Empty();
00630 }
00631 
00632 // Empty()
00633 bool vGenerator::Empty(void) const {
00634   return mpStates->Empty();
00635 }
00636 
00637 // TransRelEmpty()
00638 bool vGenerator::TransRelEmpty(void) const {
00639   return mpTransRel->Empty();
00640 }
00641 
00642 // InitStatesEmpty()
00643 bool vGenerator::InitStatesEmpty(void) const {
00644   return mInitStates.Empty();
00645 }
00646 
00647 // MarkedStatesEmpty()
00648 bool vGenerator::MarkedStatesEmpty(void) const {
00649   return mMarkedStates.Empty();
00650 }
00651 
00652 
00653 // ClearMinStateIndexMap()
00654 void vGenerator::ClearMinStateIndexMap(void) const {
00655   FD_DG("vGenerator::ClearMinStateIndexMap()");
00656   // fake const
00657   vGenerator* fakeconst = const_cast<vGenerator*>(this);
00658   fakeconst->mMinStateIndexMap.clear();
00659 }
00660 
00661 // MinStateIndexMap()
00662 const std::map<Idx,Idx>& vGenerator::MinStateIndexMap(void) const {
00663   return mMinStateIndexMap;
00664 }
00665 
00666 
00667 // SetMinStateIndexMap()
00668 void vGenerator::SetMinStateIndexMap(void) const {
00669   FD_DG("vGenerator::SetMinStateIndexMap()");
00670   // fake const
00671   vGenerator* fakeconst = const_cast<vGenerator*>(this);
00672   // clear map
00673   fakeconst->ClearMinStateIndexMap();
00674   StateSet::Iterator it;
00675   Idx minindex = 0;
00676   // if generator states get names
00677   if(StateNamesEnabled()) {
00678     // named initial states first
00679     for(it = InitStatesBegin(); it != InitStatesEnd(); ++it) {
00680       if(StateName(static_cast<Idx>(*it)) != "") {
00681   fakeconst->mMinStateIndexMap[*it] = ++minindex;
00682       }
00683     }
00684     // then all other named states
00685     for(it = StatesBegin(); it != StatesEnd(); ++it) {
00686       if(mMinStateIndexMap.count(*it) == 0) {
00687   if(StateName(static_cast<Idx>(*it)) != "") {
00688     fakeconst->mMinStateIndexMap[*it] = ++minindex;
00689   }
00690       }
00691     }
00692     // at last all anonymous states
00693     for(it = StatesBegin(); it != StatesEnd(); ++it) {
00694       if(mMinStateIndexMap.count(*it) == 0) {
00695   fakeconst->mMinStateIndexMap[*it] = ++minindex;
00696       }
00697     }
00698   }
00699   // if generator states are all anonymous
00700   else {
00701     // all initial states first
00702     for(it = InitStatesBegin(); it != InitStatesEnd(); ++it) {
00703       fakeconst->mMinStateIndexMap[*it] = ++minindex;
00704     }
00705     // then the rest
00706     for(it = StatesBegin(); it != StatesEnd(); ++it) {
00707       if(mMinStateIndexMap.count(*it) == 0) {
00708   fakeconst->mMinStateIndexMap[*it] = ++minindex;
00709       }
00710     }
00711   }
00712 #ifdef FAUDES_DEBUG_CONTAINER
00713   std::map<Idx,Idx>::const_iterator _it;
00714   for(_it = mMinStateIndexMap.begin(); _it != mMinStateIndexMap.end(); ++_it) {
00715     FD_DC("vGenerator::MinStateIndexMap: " << _it->first
00716     << " <-- " << SStr(_it->second));
00717   }
00718 #endif
00719 }
00720 
00721 
00722 // MinStateIndex(index)
00723 Idx vGenerator::MinStateIndex(Idx index) const {
00724   std::map<Idx,Idx>::const_iterator minit;
00725   minit = mMinStateIndexMap.find(index);
00726   if(minit != mMinStateIndexMap.end()) {
00727     return minit->second;
00728   } 
00729   return index;
00730 }
00731 
00732 
00733 // Max StateIndex
00734 Idx vGenerator::MaxStateIndex(void) const {
00735   if(mpStates->Empty()) return 0;
00736   return *(--(mpStates->End()));
00737 }
00738 
00739 // Re-enumerate states to obtain a consecutive state set
00740 void vGenerator::MinStateIndex(void) {
00741   // bail out on trivial
00742   // if(MaxStateIndex()==Size()) return;  tmoor 201206: dont bail out to be consistent with token IO
00743   // prepare buffer and index map
00744   vGenerator* dst = New();
00745   dst->InsEvents(Alphabet());
00746   SetMinStateIndexMap();
00747   // doit: states
00748   StateSet::Iterator sit;
00749   Idx s;
00750   for(sit=StatesBegin(); sit!=StatesEnd(); ++sit) {
00751     s=MinStateIndex(*sit);
00752     dst->InsState(s);
00753     dst->StateAttribute(s,StateAttribute(*sit));
00754     if(StateNamesEnabled()) 
00755       dst->StateName(s,StateName(*sit));
00756   }
00757   for(sit=InitStatesBegin(); sit!=InitStatesEnd(); ++sit) {
00758     s=MinStateIndex(*sit);
00759     dst->SetInitState(s);
00760   }
00761   for(sit=MarkedStatesBegin(); sit!=MarkedStatesEnd(); ++sit) {
00762     s=MinStateIndex(*sit);
00763     dst->SetMarkedState(s);
00764   }
00765   // doit: transitions
00766   TransSet::Iterator tit;
00767   for(tit=TransRelBegin(); tit!=TransRelEnd(); tit++) {
00768     Transition dt(MinStateIndex(tit->X1),tit->Ev,MinStateIndex(tit->X2));
00769     dst->SetTransition(dt);
00770     dst->TransAttribute(dt,TransAttribute(*tit));
00771   }
00772   // move relevant core members
00773   StateSymbolTable(dst->mStateSymbolTable);
00774   delete mpStates;
00775   delete mpTransRel;
00776   mpStates=dst->mpStates;
00777   mpTransRel=dst->mpTransRel;
00778   dst->mpStates=0;
00779   dst->mpTransRel=0;
00780   // move other members
00781   mInitStates=dst->InitStates();
00782   mMarkedStates=dst->MarkedStates();
00783   // update callback
00784   UpdateCore();
00785   // delete buffer
00786   delete dst;
00787   // invalidate map
00788   ClearMinStateIndexMap();
00789 }
00790 
00791 
00792 // EventSymbolTablep() const
00793 SymbolTable* vGenerator::EventSymbolTablep(void) const {
00794   return mpEventSymbolTable;
00795 }
00796 
00797 // GlobalEventSymbolTablep() const
00798 SymbolTable* vGenerator::GlobalEventSymbolTablep(void) {
00799   return SymbolTable::GlobalEventSymbolTablep();
00800 }
00801 
00802 // EventSymbolTablep(pSymTab) 
00803 void vGenerator::EventSymbolTablep(SymbolTable* pSymTab) {
00804   mpEventSymbolTable=pSymTab;
00805   // todo: set symboltable in mpAlphabet
00806 }
00807 
00808 // EventSymbolTablep(rOtherGen) 
00809 void vGenerator::EventSymbolTablep(const vGenerator& rOtherGen) {
00810   EventSymbolTablep(rOtherGen.EventSymbolTablep());
00811 }
00812 
00813 // EventIndex(rName)
00814 Idx vGenerator::EventIndex(const std::string& rName) const {
00815   return mpEventSymbolTable->Index(rName);
00816 }
00817 
00818 // EventName(index)
00819 std::string vGenerator::EventName(Idx index) const {
00820   return mpEventSymbolTable->Symbol(index);
00821 }
00822 
00823 // EventName(index, name)
00824 void vGenerator::EventName(Idx index, const std::string& rName) {
00825   FD_DG("vGenerator(" << this << ")::EventName(" 
00826       << index << ",\"" << rName << "\")");
00827 #ifdef FAUDES_CHECKED
00828   if (! ExistsEvent(index)) {
00829     std::stringstream errstr;
00830     errstr << "event \"" << index << "\" not found in generator \""
00831      << Name() << "\"";
00832     throw Exception("vGenerator::EventName(name)", errstr.str(), 89);
00833   }
00834 #endif
00835   mpEventSymbolTable->SetEntry(index, rName);
00836 }
00837 
00838 // UniqueEventName(rName)
00839 std::string vGenerator::UniqueEventName(const std::string& rName) const {
00840   std::string name=rName;
00841   if(name=="") name="ev";
00842   return mpEventSymbolTable->UniqueSymbol(name) ;
00843 }
00844 
00845 
00846 // EventRename
00847 bool vGenerator::EventRename(Idx event, const std::string& rNewName) {
00848   // consistency
00849   FD_DG("vGenerator(" << this << ")::EventRename(" << EStr(event) << ", " << rNewName << ")");
00850 #ifdef FAUDES_CHECKED
00851   if (! ExistsEvent(event)) {
00852     std::stringstream errstr;
00853     errstr << "event \"" << event << "\" not found in generator \""
00854      << Name() << "\"";
00855     throw Exception("vGenerator::EventReame(name)", errstr.str(), 89);
00856   }
00857 #endif
00858   // prepare formal result
00859   bool res=ExistsEvent(rNewName);
00860   // insert new event
00861   Idx newidx=InsEvent(rNewName);
00862   // bail out if events are the same
00863   if(newidx==event) return true;
00864   // copy event attribute
00865   if(!res) EventAttribute(newidx,EventAttribute(event));
00866   // store new transitions (with their attributes)
00867   TransSet* newtrans= TransRel().New();
00868   // iterate over transitions
00869   TransSet::Iterator tit= TransRelBegin();
00870   while(tit != TransRelEnd()) {
00871     if(tit->Ev!=event) {++tit; continue;}
00872     Transition trans= Transition(tit->X1, newidx, tit->X2);
00873     newtrans->Insert(trans);
00874     newtrans->Attribute(trans,TransAttribute(*tit));
00875     ClrTransition(tit++);
00876   }
00877   // merge transitions
00878   for(tit=newtrans->Begin(); tit!=newtrans->End(); tit++) {
00879     SetTransition(*tit);
00880     TransAttribute(*tit,newtrans->Attribute(*tit));
00881   }
00882   // free temp
00883   delete newtrans;
00884   // remore original event
00885   DelEvent(event);
00886   // done
00887   FD_DG("vGenerator(" << this << ")::EventRename(" << EStr(event) << ", " << rNewName << "):OK");
00888   return res;
00889 }
00890 
00891 // EventRename
00892 bool vGenerator::EventRename(const std::string& rOldName, const std::string& rNewName) {
00893   Idx oev = EventIndex(rOldName);
00894   return EventRename(oev,rNewName);
00895 }
00896 
00897 // NewEventSet()
00898 EventSet vGenerator::NewEventSet(void) const {
00899   EventSet res;
00900   res.SymbolTablep(mpEventSymbolTable);
00901   return res;
00902 }
00903 
00904 // NewEventSetp()
00905 EventSet* vGenerator::NewEventSetp(void) const {
00906   EventSet* res = new EventSet();
00907   res->SymbolTablep(mpEventSymbolTable);
00908   return res;
00909 }
00910 
00911 
00912 // StateSymbolTable() const
00913 const SymbolTable& vGenerator::StateSymbolTable(void) const {
00914   return mStateSymbolTable;
00915 }
00916 
00917 // StateSymbolTable(rSymTab) 
00918 void vGenerator::StateSymbolTable(const SymbolTable& rSymTab) {
00919   mStateSymbolTable=rSymTab;
00920   mpStateSymbolTable=&mStateSymbolTable;
00921 }
00922 
00923 // StateIndex(rName)
00924 Idx vGenerator::StateIndex(const std::string& rName) const {
00925    return mpStateSymbolTable->Index(rName);
00926 }
00927 
00928 // StateName(index)
00929 std::string vGenerator::StateName(Idx index) const {
00930   return mpStateSymbolTable->Symbol(index);
00931 }
00932 
00933 // StateName(index, name)
00934 void vGenerator::StateName(Idx index, const std::string& rName) {
00935   FD_DG("vGenerator(" << this << ")::StateName(" 
00936       << index << ",\"" << rName << "\")");
00937 #ifdef FAUDES_CHECKED
00938   if (! ExistsState(index)) {
00939     std::stringstream errstr;
00940     errstr << "state name \"" << rName << "\" not found in generator \""
00941      << Name() << "\"";
00942     throw Exception("vGenerator::StateName(name)", errstr.str(), 90);
00943   }
00944 #endif
00945   mpStateSymbolTable->SetEntry(index, rName);
00946 }
00947 
00948 
00949 // ClearStateNames()
00950 void vGenerator::ClearStateNames(void) {
00951   FD_DG("vGenerator(" << this << ")::ClearStateNames()");
00952   mpStateSymbolTable->Clear();
00953 }
00954 
00955 
00956 // ClrStateName(index)
00957 void vGenerator::ClrStateName(Idx index) {
00958   FD_DG("Generator(" << this << ")::ClrStateName(\"" << index << "\")");
00959 #ifdef FAUDES_CHECKED
00960   if (! ExistsState(index)) {
00961     std::stringstream errstr;
00962     errstr << "state \"" << index << "\" not found in generator \""
00963      << Name() << "\"";
00964     throw Exception("vGenerator::ClrStateName(name)", errstr.str(), 90);
00965   }
00966 #endif
00967   mpStateSymbolTable->ClrEntry(index);
00968 }
00969 
00970 // ClrStateName(rName)
00971 void vGenerator::ClrStateName(const std::string& rName) {
00972   FD_DG("vGenerator(" << this << ")::ClrStateName(\"" << rName << "\")");
00973   Idx index = StateIndex(rName);
00974   ClrStateName(index);
00975 }
00976 
00977 
00978 // StateNamesEnabled()
00979 bool vGenerator::StateNamesEnabled(void) const {
00980   return mStateNamesEnabled;
00981 }
00982 
00983 // StateNamesEnabled(flag)
00984 void vGenerator::StateNamesEnabled(bool flag) {
00985   mStateNamesEnabled = flag;
00986   if(!flag) ClearStateNames();
00987 }
00988 
00989 // StateNamesEnabled(flag)
00990 void vGenerator::StateNamesEnabledDefault(bool flag) {
00991   msStateNamesEnabledDefault = flag;
00992 }
00993 
00994 // SetDefaultStateNames()
00995 void vGenerator::SetDefaultStateNames(void) {
00996   FD_DG("vGenerator(" << this << ")::SetDefaultStateNames()");
00997   mpStateSymbolTable->Clear();
00998   StateSet::Iterator it;
00999   for (it = StatesBegin(); it != StatesEnd(); ++it) {
01000     std::string dname;
01001     dname = std::string("S")+ToStringInteger(*it);
01002     mpStateSymbolTable->SetEntry(*it,dname);
01003   }
01004 }
01005 
01006 // EnforceStateNames(rTemplate)
01007 void vGenerator::EnforceStateNames(const std::string& rTemplate) {
01008   FD_DG("vGenerator(" << this << ")::EnforceStateNames(temp)");
01009   StateSet::Iterator it;
01010   for (it = StatesBegin(); it != StatesEnd(); ++it) {
01011     if(StateName(*it)=="") {
01012       std::string name=UniqueStateName(rTemplate + "_1");
01013       StateName(*it,name);
01014     }
01015   }
01016 }
01017 
01018 // UniqueStateName(rName)
01019 std::string vGenerator::UniqueStateName(const std::string& rName) const {
01020   std::string name=rName;
01021   if(name=="") name="st";
01022   return mpStateSymbolTable->UniqueSymbol(name) ;
01023 }
01024 
01025 
01026 // iterator AlphabetBegin() const
01027 EventSet::Iterator vGenerator::AlphabetBegin(void) const {
01028   return mpAlphabet->Begin();
01029 }
01030 
01031 // iterator AlphabetEnd() const
01032 EventSet::Iterator vGenerator::AlphabetEnd(void) const {
01033   return mpAlphabet->End();
01034 }
01035 
01036 // iterator StatesBegin() const
01037 StateSet::Iterator vGenerator::StatesBegin(void) const {
01038   return mpStates->Begin();
01039 }
01040 
01041 // iterator StatesEnd() const
01042 StateSet::Iterator vGenerator::StatesEnd(void) const {
01043   return mpStates->End();
01044 }
01045 
01046 // iterator TransRelBegin() const
01047 TransSet::Iterator vGenerator::TransRelBegin(void) const {
01048   return mpTransRel->Begin();
01049 }
01050 
01051 // iterator TransRelEnd() const
01052 TransSet::Iterator vGenerator::TransRelEnd(void) const {
01053   return mpTransRel->End();
01054 }
01055 
01056 // iterator TransRelBegin(x1) const
01057 TransSet::Iterator vGenerator::TransRelBegin(Idx x1) const {
01058   return mpTransRel->Begin(x1);
01059 }
01060 
01061 // iterator TransRelEnd(x1) const
01062 TransSet::Iterator vGenerator::TransRelEnd(Idx x1) const {
01063   return mpTransRel->End(x1);
01064 }
01065 
01066 // iterator TransRelBegin(x1, ev) const
01067 TransSet::Iterator vGenerator::TransRelBegin(Idx x1, Idx ev) const {
01068   return mpTransRel->Begin(x1, ev);
01069 }
01070 
01071 // iterator TransRelEnd(x1, ev) const
01072 TransSet::Iterator vGenerator::TransRelEnd(Idx x1, Idx ev) const {
01073   return mpTransRel->End(x1, ev);
01074 }
01075 
01076 // iterator FindTransition(trans)
01077 TransSet::Iterator vGenerator::FindTransition(const Transition& rTrans) const {
01078   return mpTransRel->Find(rTrans);
01079 }
01080 
01081 // iterator FindTransition(x1, ex x2)
01082 TransSet::Iterator vGenerator::FindTransition(Idx x1, Idx ev, Idx x2) const {
01083   return mpTransRel->Find(Transition(x1, ev, x2));
01084 }
01085 
01086 // iterator FindTransition(x1, ev, x2) 
01087 TransSet::Iterator vGenerator::FindTransition(
01088    const std::string& rX1, const std::string& rEv, const std::string& rX2) const 
01089 {
01090   return mpTransRel->Find(StateIndex(rX1), EventIndex(rEv), StateIndex(rX2));
01091 }
01092 
01093 // iterator ExistsTransition(trans)
01094 bool vGenerator::ExistsTransition(const Transition& rTrans) const {
01095   return mpTransRel->Exists(rTrans);
01096 }
01097 
01098 // iterator ExistsTransition(x1, ex x2)
01099 bool vGenerator::ExistsTransition(Idx x1, Idx ev, Idx x2) const {
01100   return mpTransRel->Exists(Transition(x1, ev, x2));
01101 }
01102 
01103 // iterator ExistsTransition(x1, ev, x2)
01104 bool vGenerator::ExistsTransition(
01105   const std::string& rX1, const std::string& rEv, const std::string& rX2) const 
01106 {
01107   return mpTransRel->Exists(StateIndex(rX1), EventIndex(rEv), StateIndex(rX2));
01108 }
01109 
01110 // iterator ExistsTransition(x1, ev)
01111 bool vGenerator::ExistsTransition(Idx x1, Idx ev) const {
01112   return mpTransRel->ExistsByX1Ev(x1, ev);
01113 }
01114 
01115 // iterator ExistsTransition(x1)
01116 bool vGenerator::ExistsTransition(Idx x1) const {
01117   return mpTransRel->ExistsByX1(x1);
01118 }
01119 
01120 
01121 // idx InitState() const
01122 Idx vGenerator::InitState(void) const {
01123   if(mInitStates.Size()!=1) return 0;
01124   return *mInitStates.Begin();
01125 }
01126 
01127 
01128 
01129 // iterator InitStatesBegin() const
01130 StateSet::Iterator vGenerator::InitStatesBegin(void) const {
01131   return mInitStates.Begin();
01132 }
01133 
01134 // iterator InitStatesEnd() const
01135 StateSet::Iterator vGenerator::InitStatesEnd(void) const {
01136   return mInitStates.End();
01137 }
01138 
01139 // iterator MarkedStatesBegin()
01140 StateSet::Iterator vGenerator::MarkedStatesBegin(void) const {
01141   return mMarkedStates.Begin();
01142 }
01143 
01144 // iterator MarkedStatesEnd() const
01145 StateSet::Iterator vGenerator::MarkedStatesEnd(void) const {
01146   return mMarkedStates.End(); 
01147 }
01148 
01149 // InjectAlphabet(newalphabet)
01150 void vGenerator::InjectAlphabet(const EventSet& rNewAlphabet) {
01151   FD_DG("vGenerator::InjectAlphabet()  " << rNewAlphabet.ToString());
01152 #ifdef FAUDES_CHECKED
01153   if(rNewAlphabet.SymbolTablep()!=mpEventSymbolTable) {
01154     std::stringstream errstr;
01155     errstr << "symboltable mismatch aka not implemented" << std::endl;
01156     throw Exception("vGenerator::InjectAlphabet", errstr.str(), 88);
01157   }
01158 #endif
01159   *mpAlphabet = rNewAlphabet;
01160   mpAlphabet->Name("Alphabet");
01161 }
01162 
01163 // RestrictAlphabet(newalphabet)
01164 void vGenerator::RestrictAlphabet(const EventSet& rNewAlphabet) {
01165   FD_DG("vGenerator::RestrictAlphabet()  " << rNewAlphabet.ToString());
01166 #ifdef FAUDES_CHECKED
01167   if(rNewAlphabet.SymbolTablep()!=mpEventSymbolTable) {
01168     std::stringstream errstr;
01169     errstr << "symboltable mismatch aka not implemented" << std::endl;
01170     throw Exception("vGenerator::RestrictAlphabet", errstr.str(), 88);
01171   }
01172 #endif
01173   mpAlphabet->RestrictSet(rNewAlphabet);
01174   mpTransRel->RestrictEvents(rNewAlphabet);
01175 }
01176 
01177 // InsEvent(index)
01178 bool vGenerator::InsEvent(Idx index) {
01179   FD_DG("vGenerator(" << this << ")::InsEvent(" << index << ")");
01180   return mpAlphabet->Insert(index);
01181 }
01182 
01183 // InsEvent(rName)
01184 Idx vGenerator::InsEvent(const std::string& rName) {
01185   FD_DG("vGenerator(" << this << ")::InsEvent(\"" << rName << "\")");
01186   return mpAlphabet->Insert(rName);
01187 }
01188 
01189 // InsEvents(events)
01190 void vGenerator::InsEvents(const EventSet& events) {
01191   mpAlphabet->InsertSet(events);
01192 }
01193 
01194 // DelEvent(index)
01195 bool vGenerator::DelEvent(Idx index) {
01196   FD_DG("vGenerator(" << this << ")::DelEvent(" << index << ")");
01197   mpTransRel->EraseByEv(index);
01198   return mpAlphabet->Erase(index);
01199 }
01200 
01201 // DelEvent(rName)
01202 bool vGenerator::DelEvent(const std::string& rName) {
01203   FD_DG("vGenerator(" << this << ")::DelEvent(\"" << rName << "\")");
01204   Idx index = mpAlphabet->Index(rName);
01205   mpTransRel->EraseByEv(index);
01206   return mpAlphabet->Erase(index);
01207 }
01208 
01209 // DelEvents(events)
01210 void vGenerator::DelEvents(const EventSet& rEvents) {
01211   FD_DG("vGenerator(" << this << ")::DelEvents(\"" 
01212   << rEvents.ToString() << "\")");
01213   EventSet::Iterator it;
01214   for (it = rEvents.Begin(); it != rEvents.End(); ++it) {
01215     DelEvent(*it);
01216   }
01217 }
01218 
01219 // DelEventFromAlphabet(index)
01220 bool vGenerator::DelEventFromAlphabet(Idx index) {
01221   FD_DG("vGenerator(" << this << ")::DelEventFromAlphabet(" 
01222   << index << ")");
01223   return mpAlphabet->Erase(index);
01224 }
01225 
01226 // InsState()
01227 Idx vGenerator::InsState(void) {
01228   FD_DG("vGenerator(" << this << ")::InsState()");
01229   return mpStates->Insert();
01230 }
01231 
01232 // InsState(index)
01233 bool vGenerator::InsState(Idx index) {
01234   FD_DG("vGenerator(" << this << ")::InsState(" << index << ")");
01235   return mpStates->Insert(index);
01236 }
01237 
01238 // InsState(rName)
01239 Idx vGenerator::InsState(const std::string& rName) {
01240   FD_DG("vGenerator(" << this << ")::InsState(\"" << rName << "\")");
01241   Idx index=mpStates->Insert();
01242   StateName(index,rName);
01243   return index;
01244 }
01245 
01246 // InsStates(states)
01247 void vGenerator::InsStates(const StateSet& states) {
01248   mpStates->InsertSet(states);
01249 }
01250 
01251 // InjectState(index)
01252 void vGenerator::InjectState(Idx index) {
01253   FD_DG("vGenerator(" << this << ")::InjectState(\"" << SStr(index) << "\")");
01254   mpStates->Insert(index);
01255 }
01256 
01257 // InjectStates(rNewStates)
01258 void vGenerator::InjectStates(const StateSet& rNewStates) {
01259   FD_DG("vGenerator(" << this << ")::InjectStates(" << rNewStates.ToString() << ")");
01260   *mpStates=rNewStates;
01261   mpStates->Name("States");
01262   mpStateSymbolTable->RestrictDomain(*mpStates);
01263   FD_DG("vGenerator(" << this << ")::InjectStates(): report " << mpStates->ToString());
01264 }
01265 
01266 // InsInitState()
01267 Idx vGenerator::InsInitState(void) {
01268   FD_DG("vGenerator(" << this << ")::InsInitState()");
01269   Idx index;
01270   index = InsState();
01271   mInitStates.Insert(index);
01272   return index;
01273 }
01274 
01275 // InsInitState(name)
01276 Idx vGenerator::InsInitState(const std::string& rName) {
01277   FD_DG("vGenerator(" << this << ")::InsInitState(\"" << rName << "\")");
01278   Idx index;
01279   index = InsState(rName);
01280   mInitStates.Insert(index);
01281   return index;
01282 }
01283 
01284 // InsInitState(name)
01285 bool vGenerator::InsInitState(Idx index) {
01286   bool res=InsState(index);
01287   mInitStates.Insert(index);
01288   return res;
01289 }
01290 
01291 // InsInitStates(states)
01292 void vGenerator::InsInitStates(const StateSet& states) {
01293   mpStates->InsertSet(states);
01294   mInitStates.InsertSet(states);
01295 }
01296 
01297 // InsMarkedState()
01298 Idx vGenerator::InsMarkedState(void) {
01299   FD_DG("vGenerator(" << this << ")::InsMarkedState()");
01300   Idx index;
01301   index = InsState();
01302   mMarkedStates.Insert(index);
01303   return index;
01304 }
01305 
01306 // InsInitState(name)
01307 bool vGenerator::InsMarkedState(Idx index) {
01308   bool res=InsState(index);
01309   mMarkedStates.Insert(index);
01310   return res;
01311 }
01312 
01313 // InsMarkedState(rName)
01314 Idx vGenerator::InsMarkedState(const std::string& rName) {
01315   FD_DG("vGenerator(" << this << ")::InsMarkedState(\"" << rName << "\")");
01316   Idx index;
01317   index = InsState(rName);
01318   mMarkedStates.Insert(index);
01319   return index;
01320 }
01321 
01322 // InsMarkedStates(states)
01323 void vGenerator::InsMarkedStates(const StateSet& states) {
01324   mpStates->InsertSet(states);
01325   mMarkedStates.InsertSet(states);
01326 }
01327 
01328 
01329 // DelState(index)
01330 bool vGenerator::DelState(Idx index) {
01331   FD_DG("vGenerator(" << this << ")::DelState(" << index << ")");
01332   // mInitStates
01333   mInitStates.Erase(index);
01334   // mstates
01335   mMarkedStates.Erase(index);
01336   // transrel 
01337   mpTransRel->EraseByX1OrX2(index);
01338   // symbolic name
01339   mpStateSymbolTable->ClrEntry(index);
01340   // finally ... remove the state
01341   return mpStates->Erase(index);
01342 }
01343 
01344 // DelState(rName)
01345 bool vGenerator::DelState(const std::string& rName) {
01346   FD_DG("vGenerator(" << this << ")::DelState(\"" << rName << "\")");
01347   Idx index;
01348   index = StateIndex(rName);
01349 #ifdef FAUDES_CHECKED
01350   if (index == 0) {
01351     std::stringstream errstr;
01352     errstr << "state name \"" << rName << "\" not found in generator \""
01353      << Name() << "\"";
01354     throw Exception("vGenerator::DelState(name)", errstr.str(), 90);
01355   }
01356 #endif
01357   return DelState(index);
01358 }
01359 
01360 // DelStates(rDelStates)
01361 void vGenerator::DelStates(const StateSet& rDelStates) {
01362   FD_DG("vGenerator(" << this << ")::DelStates(" 
01363   << rDelStates.ToString() << ")");
01364   StateSet::Iterator cit;
01365   StateSet::Iterator cit_end;
01366   // symbolic state names
01367   for (cit = rDelStates.Begin(); cit != rDelStates.End(); ++cit) {
01368     mpStateSymbolTable->ClrEntry(*cit);
01369   }
01370   // statesets
01371   mpStates->EraseSet(rDelStates);
01372   mInitStates.EraseSet(rDelStates);
01373   mMarkedStates.EraseSet(rDelStates);
01374   // mpTransRel:
01375   mpTransRel->EraseByX1OrX2(rDelStates);
01376 }
01377 
01378 // DelStateFromStates(index)
01379 bool vGenerator::DelStateFromStates(Idx index) {
01380   FD_DG("vGenerator(" << this << ")::DelStateFromStates(" << index << ")");
01381   // mStates + global
01382   return mpStates->Erase(index);
01383 }
01384 
01385 // DelStateFromStates(pos)
01386 StateSet::Iterator vGenerator::DelStateFromStates(StateSet::Iterator pos) {
01387   FD_DG("vGenerator(" << this << ")::DelState(" << *pos << ")");
01388   return mpStates->Erase(pos);
01389 }
01390 
01391 // RestrictStates(rStates)
01392 void vGenerator::RestrictStates(const StateSet& rStates) {
01393   FD_DG("vGenerator(" << this << ")::RestrictStates(" 
01394   << rStates.ToString() << ")");
01395 
01396   StateSet::Iterator cit;
01397   StateSet::Iterator cit_end;
01398   // symbolic state names
01399   for(cit = StatesBegin(); cit != StatesEnd(); ++cit) {
01400     if(!rStates.Exists(*cit)) mpStateSymbolTable->ClrEntry(*cit);
01401   }
01402   // statesets
01403   mpStates->RestrictSet(rStates);
01404   mInitStates.RestrictSet(rStates);
01405   mMarkedStates.RestrictSet(rStates);
01406   // mpTransRel:
01407   mpTransRel->RestrictStates(rStates);
01408 }
01409 
01410 
01411 // SetInitState(index)
01412 void vGenerator::SetInitState(Idx index) {
01413   FD_DG("vGenerator(" << this << ")::SetInitState(" << index << ")");
01414 #ifdef FAUDES_CHECKED
01415   if (! mpStates->Exists(index)) {
01416     std::stringstream errstr;
01417     errstr << "vGenerator::SetMarkedState: index " << index 
01418      << " not in stateset";
01419     throw Exception("vGenerator::SetInitState(..)", errstr.str(), 91);
01420   }
01421 #endif
01422   mInitStates.Insert(index);
01423 }
01424 
01425 // SetInitState(rName)
01426 void vGenerator::SetInitState(const std::string& rName) {
01427   FD_DG("vGenerator(" << this << ")::SetInitState(\"" << rName << "\")");
01428   Idx index = StateIndex(rName);
01429 #ifdef FAUDES_CHECKED
01430   if (index == 0) {
01431     std::stringstream errstr;
01432     errstr << "State name \"" << rName << "\" not known in Generator";
01433     throw Exception("vGenerator::SetInitState(..)", errstr.str(), 90);
01434   }
01435 #endif
01436   SetInitState(index);
01437 }
01438 
01439 // InjectInitStates(rNewInitStates)
01440 void vGenerator::InjectInitStates(const StateSet& rNewInitStates) {
01441   FD_DG("vGenerator(" << this << ")::InjectInitStates(" 
01442   << rNewInitStates.ToString() << ")");
01443   mInitStates = rNewInitStates;
01444   mInitStates.Name("InitStates");
01445 }
01446 
01447 // ClrInitState(index)
01448 void vGenerator::ClrInitState(Idx index) {
01449   FD_DG("vGenerator(" << this << ")::ClrInitState(" << index << ")");
01450 #ifdef FAUDES_CHECKED
01451   if (! mpStates->Exists(index)) {
01452     std::stringstream errstr;
01453     errstr << "vGenerator::SetMarkedState: index " << index 
01454      << " not in stateset";
01455     throw Exception("vGenerator::ClrInitState(..)", errstr.str(), 91);
01456   }
01457 #endif
01458   mInitStates.Erase(index);
01459 }
01460 
01461 // ClrInitState(rName)
01462 void vGenerator::ClrInitState(const std::string& rName) {
01463   FD_DG("vGenerator(" << this << ")::ClrInitState(\"" << rName << "\")");
01464   Idx index = StateIndex(rName);
01465 #ifdef FAUDES_CHECKED
01466   if (index == 0) {
01467     std::stringstream errstr;
01468     errstr << "State name \"" << rName << "\" not known in Generator";
01469     throw Exception("vGenerator::ClrInitState(..)", errstr.str(), 90);
01470   }
01471 #endif
01472   ClrInitState(index);
01473 }
01474 
01475 // ClrInitState(pos)
01476 StateSet::Iterator vGenerator::ClrInitState(StateSet::Iterator pos) {
01477   FD_DG("vGenerator(" << this << ")::ClrInitState(" << *pos << ")");
01478   return mInitStates.Erase(pos);
01479 }
01480 
01481 // ClearInitStates()
01482 void vGenerator::ClearInitStates(void) {
01483   mInitStates.Clear();
01484 }
01485 
01486 // SetMarkedState(index)
01487 void vGenerator::SetMarkedState(Idx index) {
01488   FD_DG("vGenerator(" << this << ")::SetMarkedState(" << index << ")");
01489 #ifdef FAUDES_CHECKED
01490   if (! mpStates->Exists(index)) {
01491     std::stringstream errstr;
01492     errstr << "vGenerator::SetMarkedState: index " << index 
01493      << " not in stateset";
01494     throw Exception("vGenerator::SetMarkedState(..)", errstr.str(), 91);
01495   }
01496 #endif
01497   mMarkedStates.Insert(index);
01498 }
01499 
01500 // SetMarkedState(rName)
01501 void vGenerator::SetMarkedState(const std::string& rName) {
01502   FD_DG("vGenerator(" << this << ")::SetMarkedState(\"" << rName << "\")");
01503   Idx index = StateIndex(rName);
01504 #ifdef FAUDES_CHECKED
01505   if (index == 0) {
01506     std::stringstream errstr;
01507     errstr << "State name \"" << rName << "\" not known in Generator";
01508     throw Exception("vGenerator::SetMarkedState(..)", errstr.str(), 90);
01509   }
01510 #endif
01511   SetMarkedState(index);
01512 }
01513 
01514 // InjectMarkedStates(rNewMarkedStates)
01515 void vGenerator::InjectMarkedStates(const StateSet& rNewMarkedStates) {
01516   FD_DG("vGenerator(" << this << ")::InjectMarkedStates(" 
01517   << rNewMarkedStates.ToString() << ")");
01518   mMarkedStates = rNewMarkedStates;
01519   mMarkedStates.Name("MarkedStates");
01520 }
01521 
01522 // ClrMarkedState(index)
01523 void vGenerator::ClrMarkedState(Idx index) {
01524   FD_DG("vGenerator(" << this << ")::ClrMarkedState(" << index << ")");
01525 #ifdef FAUDES_CHECKED
01526   if (! mpStates->Exists(index)) {
01527     std::stringstream errstr;
01528     errstr << "vGenerator::ClrMarkedState: index " << index 
01529      << " not in stateset";
01530     throw Exception("vGenerator::ClrMarkedState(..)", errstr.str(), 91);
01531   }
01532 #endif
01533   mMarkedStates.Erase(index);
01534 }
01535 
01536 // ClrMarkedState(rName)
01537 void vGenerator::ClrMarkedState(const std::string& rName) {
01538   FD_DG("vGenerator(" << this << ")::ClrMarkedState(\"" << rName << "\")");
01539   Idx index = StateIndex(rName);
01540 #ifdef FAUDES_CHECKED
01541   if (index == 0) {
01542     std::stringstream errstr;
01543     errstr << "State name \"" << rName << "\" not known in Generator";
01544     throw Exception("vGenerator::ClrMarkedState(..)", errstr.str(), 90);
01545   }
01546 #endif
01547   ClrMarkedState(index);
01548 }
01549 
01550 // ClrMarkedState(pos)
01551 StateSet::Iterator vGenerator::ClrMarkedState(StateSet::Iterator pos) {
01552   FD_DG("vGenerator(" << this << ")::ClrMarkedState(" << *pos << ")");
01553   return mMarkedStates.Erase(pos);
01554 }
01555 
01556 // ClearMarkedStates()
01557 void vGenerator::ClearMarkedStates(void) {
01558   mMarkedStates.Clear();
01559 }
01560 
01561 // InjectTransition(newtrans)
01562 void vGenerator::InjectTransition(const Transition& rTrans) {
01563   FD_DG("vGenerator::InjectTransition(" << TStr(rTrans) << ")");
01564   mpTransRel->Inject(rTrans);
01565 }
01566 
01567 // InjectTransRel(newtransrel)
01568 void vGenerator::InjectTransRel(const TransSet& rNewTransrel) {
01569   FD_DG("vGenerator::InjectTransRel(...)");
01570   *mpTransRel=rNewTransrel;
01571   mpTransRel->Name("TransRel");
01572 }
01573 
01574 // SetTransition(rX1, rEv, rX2)
01575 bool vGenerator::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2) {
01576   FD_DG("vGenerator(" << this << ")::SetTransition(\""
01577   << rX1 << "\", \"" << rEv << "\", \"" << rX2 << "\")");
01578   Idx x1 = StateIndex(rX1);
01579   Idx x2 = StateIndex(rX2);
01580 #ifdef FAUDES_CHECKED
01581   if (x1 == 0) {
01582     FD_ERR("vGenerator::SetTransition: state " << rX1 
01583      << " not in stateset");
01584     std::stringstream errstr;
01585     errstr << "State name " << rX1 << " not found in Generator";
01586     throw Exception("vGenerator::SetTransition(..)", errstr.str(), 90);
01587   }
01588   if (! mpAlphabet->Exists(rEv)) {
01589     FD_ERR("vGenerator::SetTransition: event " << rEv << " not in alphabet");
01590     std::stringstream errstr;
01591     errstr << "Event name " << rEv << " not found in event domain of Generator";
01592     throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
01593   }
01594   if (x2 == 0) {
01595     FD_ERR("vGenerator::SetTransition: state " << rX2 << " not in stateset");
01596     std::stringstream errstr;
01597     errstr << "State name " << rX2 << " not found in Generator";
01598     throw Exception("vGenerator::SetTransition(..)", errstr.str(), 90);
01599   }
01600 #endif
01601   return SetTransition(Transition(x1, EventIndex(rEv), x2));
01602 }
01603 
01604 
01605 // SetTransition(x1, ev, x2)
01606 bool vGenerator::SetTransition(Idx x1, Idx ev, Idx x2) {
01607   return SetTransition(Transition(x1,ev,x2));
01608 }
01609 
01610 // SetTransition(rTransition)
01611 bool vGenerator::SetTransition(const Transition& rTransition) {
01612   FD_DG("vGenerator(" << this << ")::SetTransition(" << rTransition.X1 << "," 
01613   << rTransition.Ev << "," << rTransition.X2 << ")");
01614 #ifdef FAUDES_CHECKED
01615   if (! mpStates->Exists(rTransition.X1)) {
01616     std::stringstream errstr;
01617     errstr << "vGenerator::SetTransition: state " << SStr(rTransition.X1) 
01618      << " not in stateset";
01619     throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
01620   }
01621   if (! mpAlphabet->Exists(rTransition.Ev)) {
01622     std::stringstream errstr;
01623     errstr << "vGenerator::SetTransition: event " << EStr(rTransition.Ev) 
01624      << " not in alphabet ";
01625     throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
01626   }
01627   if (! mpStates->Exists(rTransition.X2)) {
01628     std::stringstream errstr;
01629     errstr << "vGenerator::SetTransition: state " << SStr(rTransition.X2) 
01630      << " not in stateset";
01631     throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95);
01632   }
01633 #endif
01634   return mpTransRel->Insert(rTransition);
01635 }
01636 
01637 
01638 
01639 // ClrTransition.X1, ev, x2)
01640 void vGenerator::ClrTransition(Idx x1, Idx ev, Idx x2) {
01641   FD_DG("vGenerator(" << this << ")::ClrTransition(" 
01642   << x1 << "," << ev << "," << x2 << ")");
01643   mpTransRel->Erase(x1, ev, x2);
01644 }
01645 
01646 // ClrTransition(rTransition)
01647 void vGenerator::ClrTransition(const Transition& rTransition) {
01648   FD_DG("vGenerator(" << this << ")::ClrTransition(" << TStr(rTransition) << ")");
01649   mpTransRel->Erase(rTransition);
01650 }
01651 
01652 // ClrTransition(it)
01653 TransSet::Iterator vGenerator::ClrTransition(TransSet::Iterator it) {
01654   FD_DG("vGenerator(" << this << ")::ClrTransition(" << TStr(*it)<< ")" );
01655   return mpTransRel->Erase(it);
01656 }
01657 
01658 // ClrTransitions(X1, ev)
01659 void vGenerator::ClrTransitions(Idx x1, Idx ev) {
01660   FD_DG("vGenerator(" << this << ")::ClrTransition(" 
01661   << x1 << "," << ev << ")");
01662   mpTransRel->EraseByX1Ev(x1, ev);
01663 }
01664 
01665 // ClrTransitions(X1)
01666 void vGenerator::ClrTransitions(Idx x1) {
01667   FD_DG("vGenerator(" << this << ")::ClrTransition(" 
01668   << x1  << ")");
01669   mpTransRel->EraseByX1(x1);
01670 }
01671 
01672 // TransAttribute(trans, attr)
01673 void vGenerator::TransAttribute(const Transition& rTrans, const Type& rAttr) {
01674   FD_DG("vGenerator(" << this << ")::TransAttribute(" 
01675   << TStr(rTrans) << ",\"" << rAttr.ToString() << "\")");
01676   mpTransRel->Attribute(rTrans, rAttr);
01677 }
01678 
01679 // TransAttributep(trans)
01680 AttributeVoid* vGenerator::TransAttributep(const Transition& rTrans)  {
01681   return mpTransRel->Attributep(rTrans);
01682 }
01683 
01684 
01685 // TransAttribute(trans)
01686 const AttributeVoid& vGenerator::TransAttribute(const Transition& rTrans) const {
01687   return mpTransRel->Attribute(rTrans);
01688 }
01689 
01690 // ClrTransAttribute(trans)
01691 void vGenerator::ClrTransAttribute(const Transition& rTrans)  {
01692   mpTransRel->ClrAttribute(rTrans);
01693 }
01694 
01695 
01696 // ClearTransRel()
01697 void vGenerator::ClearTransRel(void) {
01698   mpTransRel->Clear();
01699 }
01700 
01701 // EventAttribute(index, attr)
01702 void vGenerator::EventAttribute(Idx index, const Type& rAttr) {
01703   FD_DG("vGenerator(" << this << ")::EventAttribute(" 
01704   << EStr(index) << ",\"" << rAttr.ToString() << "\")");
01705   mpAlphabet->Attribute(index, rAttr);
01706 }
01707 
01708 
01709 // EventAttributes(set)
01710 void vGenerator::EventAttributes(const EventSet& rEventSet) {
01711   FD_DG("vGenerator(" << this << ")::EventAttributes(" 
01712   << rEventSet.ToString() << "\")");
01713   mpAlphabet->Attributes(rEventSet);
01714 }
01715 
01716 // ClrEventAttribute(index)
01717 void vGenerator::ClrEventAttribute(Idx index) {
01718   FD_DG("vGenerator(" << this << ")::ClrEventAttribute(\"" << EStr(index) << "\")");
01719   mpAlphabet->ClrAttribute(index);
01720 }
01721 
01722 // StateAttribute(index, attr)
01723 void vGenerator::StateAttribute(Idx index, const Type& rAttr) {
01724   FD_DG("vGenerator(" << this << ")::StateAttribute(" 
01725   << SStr(index) << ",\"" << rAttr.ToString() << "\")");
01726   mpStates->Attribute(index, rAttr);
01727 }
01728 
01729 // ClrStateAttribute(index)
01730 void vGenerator::ClrStateAttribute(Idx index) {
01731   FD_DG("vGenerator(" << this << ")::ClrStateAttribute(\"" << index << "\")");
01732   mpStates->ClrAttribute(index);
01733 }
01734 
01735 // ExistsEvent(index)
01736 bool vGenerator::ExistsEvent(Idx index) const {
01737   return mpAlphabet->Exists(index);
01738 }
01739 
01740 // ExistsEvent(rName)
01741 bool vGenerator::ExistsEvent(const std::string& rName) const {
01742   return mpAlphabet->Exists(rName);
01743 }
01744 
01745 // FindEvent(index) const
01746 EventSet::Iterator vGenerator::FindEvent(Idx index) const {
01747   return mpAlphabet->Find(index);
01748 }
01749 
01750 // FindEvent(rName)
01751 EventSet::Iterator vGenerator::FindEvent(const std::string& rName) const {
01752   return mpAlphabet->Find(rName);
01753 }
01754 
01755 // ExistsState(index)
01756 bool vGenerator::ExistsState(Idx index) const {
01757   return mpStates->Exists(index);
01758 }
01759 
01760 // ExistsName(name)
01761 bool vGenerator::ExistsState(const std::string& rName) const {
01762   return ExistsState(StateIndex(rName));
01763 }
01764 
01765 // FindState(rName) const
01766 StateSet::Iterator vGenerator::FindState(const std::string& rName) const {
01767   return mpStates->Find(mpStateSymbolTable->Index(rName));
01768 }
01769 
01770 // FindState(index) const
01771 StateSet::Iterator vGenerator::FindState(Idx index) const {
01772   return mpStates->Find(index);
01773 }
01774 
01775 // ExistsInitState(index)
01776 bool vGenerator::ExistsInitState(Idx index) const {
01777   return mInitStates.Exists(index);
01778 }
01779 
01780 // FindInitState(index)
01781 StateSet::Iterator vGenerator::FindInitState(Idx index) const {
01782   return mInitStates.Find(index);
01783 }
01784 
01785 // ExistsMarkedState(index)
01786 bool vGenerator::ExistsMarkedState(Idx index) const {
01787   return mMarkedStates.Exists(index);
01788 }
01789 
01790 // FindMarkedState(index)
01791 StateSet::Iterator vGenerator::FindMarkedState(Idx index) const {
01792   return mMarkedStates.Find(index);
01793 }
01794 
01795 // EventAttribute(index)
01796 const AttributeVoid&  vGenerator::EventAttribute(Idx index) const {
01797   return mpAlphabet->Attribute(index);
01798 }
01799 
01800 // EventAttributep(index)
01801 AttributeVoid* vGenerator::EventAttributep(Idx index) {
01802   return mpAlphabet->Attributep(index);
01803 }
01804 
01805 // EventAttribute(rName)
01806 const AttributeVoid&  vGenerator::EventAttribute(const std::string& rName) const {
01807   return EventAttribute(EventIndex(rName));
01808 }
01809 
01810 // EventAttributep(rName)
01811 AttributeVoid* vGenerator::EventAttributep(const std::string& rName) {
01812   return EventAttributep(EventIndex(rName));
01813 }
01814 
01815 // StateAttribute(index)
01816 const AttributeVoid&  vGenerator::StateAttribute(Idx index) const {
01817   return mpStates->Attribute(index);
01818 }
01819 
01820 // StateAttributep(index)
01821 AttributeVoid*  vGenerator::StateAttributep(Idx index) {
01822   return mpStates->Attributep(index);
01823 }
01824 
01825 // GlobalAttribute(attr)
01826 void vGenerator::GlobalAttribute(const Type& rAttr) {
01827   FD_DG("vGenerator(" << this << ")::GlobalAttribute(" 
01828   << rAttr.ToString() << "\")");
01829   // set to void is ok for silient ignore
01830   if(typeid(rAttr)==typeid(AttributeVoid)) return;
01831   // error:
01832   std::stringstream errstr;
01833   errstr << "cannot cast global attribute " << rAttr.ToString() << " for generator " << Name();
01834   throw Exception("vGenerator::GlobalAttribute", errstr.str(), 63);
01835 }
01836 
01837 // GlobalAttributeTry(attr)
01838 void vGenerator::GlobalAttributeTry(const Type& rAttr) {
01839   FD_DG("vGenerator(" << this << ")::GlobalAttributeTry(" 
01840   << rAttr.ToString() << "\")");
01841   // ignore
01842 }
01843 
01844 // GlobalAttribute()
01845 const AttributeVoid& vGenerator::GlobalAttribute(void) const {
01846   FD_DG("vGenerator(" << this << ")::GlobalAttribute()");
01847   return *mpGlobalAttribute;
01848 }
01849 
01850 // GlobalAttributep()
01851 AttributeVoid* vGenerator::GlobalAttributep(void) {
01852   FD_DG("vGenerator(" << this << ")::GlobalAttributep()");
01853   return mpGlobalAttribute;
01854 }
01855 
01856 
01857 // Alphabet()
01858 const EventSet& vGenerator::Alphabet(void) const {
01859   return *mpAlphabet;
01860 }
01861 
01862 // States()
01863 const StateSet& vGenerator::States(void) const {
01864   return *mpStates;
01865 }
01866 
01867 // TransRel()
01868 const TransSet& vGenerator::TransRel(void) const {
01869   return *mpTransRel;
01870 }
01871 
01872 
01873 // TransRel(res)
01874 void vGenerator::TransRel(TransSetX1EvX2& res) const { mpTransRel->ReSort(res); }
01875 void vGenerator::TransRel(TransSetEvX1X2& res) const { mpTransRel->ReSort(res); }
01876 void vGenerator::TransRel(TransSetEvX2X1& res) const { mpTransRel->ReSort(res); }
01877 void vGenerator::TransRel(TransSetX2EvX1& res) const { mpTransRel->ReSort(res); }
01878 void vGenerator::TransRel(TransSetX2X1Ev& res) const { mpTransRel->ReSort(res); }
01879 void vGenerator::TransRel(TransSetX1X2Ev& res) const { mpTransRel->ReSort(res); }
01880 
01881 
01882 Transition vGenerator::TransitionByNames(
01883     const std::string& rX1, const std::string& rEv, const std::string& rX2) const {
01884   return Transition(StateIndex(rX1),EventIndex(rEv),StateIndex(rX2));
01885 }
01886 
01887 // InitStates()
01888 const StateSet& vGenerator::InitStates(void) const {
01889   return mInitStates;
01890 }
01891 
01892 // MarkedStates()
01893 const StateSet& vGenerator::MarkedStates(void) const {
01894   return mMarkedStates;
01895 }
01896 
01897 // MinimizeAlphabet()
01898 void vGenerator::MinimizeAlphabet(void) {
01899   mpAlphabet->NameSet::EraseSet(UnusedEvents());
01900 }
01901 
01902 // UsedEvents()
01903 EventSet vGenerator::UsedEvents(void) const {
01904   EventSet resultset = NewEventSet();
01905   TransSet::Iterator it;
01906   for (it = mpTransRel->Begin(); it != mpTransRel->End(); ++it) {
01907     resultset.Insert(it->Ev);
01908   }
01909   return resultset;
01910 }
01911 
01912 // UnusedEvents()
01913 EventSet vGenerator::UnusedEvents(void) const {
01914   return *mpAlphabet - UsedEvents();
01915 }
01916 
01917 // ActiveEventSet(x1)
01918 EventSet vGenerator::ActiveEventSet(Idx x1) const {
01919   EventSet result = NewEventSet();
01920   TransSet::Iterator it;
01921   for (it = TransRelBegin(x1); it != TransRelEnd(x1); ++it) {
01922     result.Insert(it->Ev);
01923   }
01924   return result;
01925 }
01926 
01927 // ActiveTransSet(x1)
01928 TransSet vGenerator::ActiveTransSet(Idx x1) const {
01929   TransSet result;
01930   TransSet::Iterator it;
01931   for (it = TransRelBegin(x1); it != TransRelEnd(x1); ++it) {
01932     result.Insert(*it);
01933   }
01934   return result;
01935 }
01936 
01937 // TransRelStates()
01938 StateSet vGenerator::TransRelStates(void) const {
01939   StateSet states;
01940   TransSet::Iterator it;
01941   for (it=mpTransRel->Begin(); it != mpTransRel->End(); ++it) {
01942     states.Insert(it->X1);
01943     states.Insert(it->X2);
01944   }
01945   return states;
01946 }
01947 
01948 // SuccessorStates(x1)
01949 StateSet vGenerator::SuccessorStates(Idx x1) const {
01950   return mpTransRel->SuccessorStates(x1);
01951 }
01952 
01953 // SuccessorStates(x1,ev)
01954 StateSet vGenerator::SuccessorStates(Idx x1, Idx ev) const {
01955   return mpTransRel->SuccessorStates(x1,ev);
01956 }
01957 
01958 
01959 // idx SuccessorState() const
01960 Idx vGenerator::SuccessorState(Idx x1, Idx ev) const {
01961   TransSet::Iterator it = mpTransRel->Begin(x1,ev);
01962   TransSet::Iterator it_end = mpTransRel->End(x1,ev);
01963   if(it==it_end) return 0;
01964   Idx res=(*it).X2;
01965 #ifdef FAUDES_CHECKED
01966   it++;
01967   if(it!=it_end) {
01968     std::stringstream errstr;
01969     errstr << "successor state does not exist uniquely" << std::endl;
01970     throw Exception("vGenerator::SuccessorState", errstr.str(), 92);
01971   }
01972 #endif
01973   return res;
01974 }
01975 
01976 
01977 // AccessibleSet()
01978 StateSet vGenerator::AccessibleSet(void) const {
01979   // initialize todo stack
01980   std::stack<Idx> todo;
01981   StateSet::Iterator sit;
01982   for(sit = InitStatesBegin(); sit != InitStatesEnd(); ++sit) 
01983     todo.push(*sit);
01984   // loop variables
01985   StateSet accessibleset;
01986   TransSet::Iterator tit;
01987   TransSet::Iterator tit_end;
01988   // loop
01989   while(!todo.empty()) {
01990     // pop
01991     Idx x1=todo.top();
01992     todo.pop();
01993     // sense known
01994     if(accessibleset.Exists(x1)) continue; 
01995     // record
01996     accessibleset.Insert(x1);
01997     // iterate/push
01998     tit=TransRelBegin(x1);
01999     tit_end=TransRelEnd(x1);
02000     for(; tit != tit_end; ++tit) 
02001       if(tit->X2 != x1) 
02002         todo.push(tit->X2);
02003   }
02004   // done
02005   accessibleset.Name("AccessibleSet");
02006   return accessibleset;
02007 }
02008 
02009 // Accessible()
02010 bool vGenerator::Accessible(void) {
02011   StateSet accessibleset = AccessibleSet();
02012   StateSet not_accessible = *mpStates - accessibleset;
02013   DelStates(not_accessible);
02014   // return true if there is an initial state
02015   if (!mInitStates.Empty()) {
02016     FD_DF("vGenerator::accessible: generator is accessible");
02017     return true;
02018   }
02019   FD_DF("vGenerator::accessible: generator is accessible but empty");
02020   return false;
02021 }
02022 
02023 // IsAccessible()
02024 bool vGenerator::IsAccessible(void) const {
02025   if(AccessibleSet() == *mpStates) {
02026     FD_DF("vGenerator::accessible: generator is accessible");
02027     return true;
02028   }
02029   FD_DF("vGenerator::accessible: generator is not accessible");
02030   return false;
02031 }
02032 
02033 // CoaccessibleSet()
02034 StateSet vGenerator::CoaccessibleSet(void) const {
02035   // build reverse transition relation
02036   TransSetX2EvX1 rtrel;
02037   TransRel(rtrel);
02038   // initialize todo stack
02039   StateSet::Iterator sit;
02040   std::stack<Idx> todo;
02041   for(sit = MarkedStatesBegin(); sit != MarkedStatesEnd(); ++sit) 
02042     todo.push(*sit);
02043   // loop variables
02044   StateSet coaccessibleset;
02045   TransSetX2EvX1::Iterator tit;
02046   TransSetX2EvX1::Iterator tit_end;
02047   // loop
02048   while(!todo.empty()) {
02049     // pop
02050     Idx x2=todo.top();
02051     todo.pop();
02052     // sense known
02053     if(coaccessibleset.Exists(x2)) continue; 
02054     // record
02055     coaccessibleset.Insert(x2);
02056     // iterate/push
02057     tit=rtrel.BeginByX2(x2);
02058     tit_end=rtrel.EndByX2(x2);
02059     for(; tit != tit_end; ++tit) 
02060       if(tit->X1 != x2) 
02061         todo.push(tit->X1);
02062   }
02063   // done
02064   coaccessibleset.Name("CoaccessibleSet");
02065   return coaccessibleset;
02066 }
02067 
02068 // Coaccessible()
02069 bool vGenerator::Coaccessible(void) {
02070   StateSet coaccessibleset = CoaccessibleSet();
02071   StateSet not_coaccessible = *mpStates - coaccessibleset;
02072   DelStates(not_coaccessible);
02073   // return true if there is a marked state
02074   if (! mMarkedStates.Empty()) {
02075     FD_DF("vGenerator::coaccessible: generator is coaccessible");
02076     return true;
02077   }
02078   FD_DF("vGenerator::coaccessible: generator is not coaccessible");
02079   return false;
02080 }
02081 
02082 // IsCoaccessible()
02083 bool vGenerator::IsCoaccessible(void) const {
02084   if(CoaccessibleSet() == *mpStates) {
02085     FD_DF("vGenerator::coaccessible: generator is coaccessible");
02086     return true;
02087   }
02088   FD_DF("vGenerator::coaccessible: generator is not coaccessible");
02089   return false;
02090 }
02091 
02092 // TrimSet()
02093 StateSet vGenerator::TrimSet(void) const {
02094   FD_DF("vGenerator::trimset: trim states: " 
02095   << StateSet(AccessibleSet() * CoaccessibleSet()).ToString());
02096   StateSet res=AccessibleSet() * CoaccessibleSet();
02097   res.Name("TrimSet");
02098   return res;
02099 }
02100 
02101 // Trim()
02102 bool vGenerator::Trim(void) {
02103   FD_DF("vGenerator::trim: generator states: " << mpStates->ToString());
02104   // better: compute sets and do one state delete
02105   bool accessiblebool = Accessible();
02106   bool coaccessiblebool = Coaccessible();
02107   FD_DF("vGenerator::trim: trim states: " << mpStates->ToString());
02108   if(accessiblebool && coaccessiblebool) {
02109     FD_DF("vGenerator::Trim(): generator is nontrivial");
02110     return true;
02111   }
02112   FD_DF("vGenerator::Trim(): generator is trivial");
02113   return false;
02114 }
02115 
02116 
02117 // IsTrim()
02118 bool vGenerator::IsTrim(void) const {
02119   bool res=true;
02120   if(!IsAccessible()) res=false;
02121   else if(!IsCoaccessible()) res=false;
02122   FD_DF("vGenerator::IsTrim(): result " << res);
02123   return res;
02124 }
02125 
02126 
02127 // BlockingStates()
02128 StateSet vGenerator::BlockingStates(void) const {
02129   FD_DF("vGenerator::BlockingSet: blocking states: " 
02130   << StateSet(AccessibleSet() - CoaccessibleSet()).ToString());
02131   return AccessibleSet() - CoaccessibleSet();
02132 }
02133 
02134 
02135 
02136 // IsComplete
02137 bool vGenerator::IsComplete(const StateSet& rStates) const {
02138   FD_DG("IsComplete(" << Name() << ")");
02139   
02140   // loop over provided states
02141   StateSet::Iterator sit=rStates.Begin();
02142   StateSet::Iterator sit_end=rStates.End();
02143   for(;sit!=sit_end;sit++){
02144     TransSet::Iterator tit=TransRelBegin(*sit);
02145     TransSet::Iterator tit_end=TransRelEnd(*sit);
02146     if(tit==tit_end) break;
02147   }
02148   // return true if no terminal state has been found
02149   return sit==sit_end;
02150 }
02151 
02152 
02153 // IsComplete w.r.t. rSigmaO
02154 bool vGenerator::IsComplete(const EventSet& rSigmaO) const {
02155   FD_DC("IsComplete(" << Name() << ")");
02156   // find good states: where some rEvent is enabled
02157   std::stack<Idx> todo;
02158   TransSet::Iterator tit=TransRelBegin();
02159   TransSet::Iterator tit_end=TransRelEnd();
02160   while(tit!=tit_end){
02161     if(!rSigmaO.Exists(tit->Ev)) { ++tit; continue; }
02162     todo.push(tit->X1);
02163     tit=TransRelEnd(tit->X1);
02164   }
02165   // build reverse transition relation
02166   TransSetX2EvX1 rtrel;
02167   TransRel(rtrel);
02168   // reverse reachability analysis for more good states
02169   StateSet good;
02170   while(!todo.empty()) {
02171     // pop
02172     Idx x2=todo.top();
02173     todo.pop();
02174     // sense known
02175     if(good.Exists(x2)) continue; 
02176     // record
02177     good.Insert(x2);
02178     // iterate/push
02179     TransSetX2EvX1::Iterator tit=rtrel.BeginByX2(x2);
02180     TransSetX2EvX1::Iterator tit_end=rtrel.EndByX2(x2);
02181     for(; tit != tit_end; ++tit) 
02182       if(tit->X1 != x2) todo.push(tit->X1);
02183   }
02184   FD_DG("IsComplete(" << Name() << "): done");
02185   // done
02186   return good == States();
02187 }
02188 
02189 
02190 // IsComplete
02191 bool vGenerator::IsComplete(void) const {
02192   return IsComplete(States());
02193 }
02194 
02195 // Complete
02196 bool vGenerator::Complete(void) {
02197   // states to remove
02198   StateSet termset = TerminalStates();
02199   // iterative search 
02200   bool done;
02201   do {
02202     // over all states (could make use of reverse transrel here)
02203     StateSet::Iterator sit = States().Begin();
02204     StateSet::Iterator sit_end = States().End();
02205     done=true;
02206     for(; sit!=sit_end; ++sit) {
02207       if(termset.Exists(*sit)) continue;
02208       TransSet::Iterator tit = TransRelBegin(*sit);
02209       TransSet::Iterator tit_end = TransRelEnd(*sit);
02210       for (; tit != tit_end; ++tit) {
02211         if(!termset.Exists(tit->X2)) break;
02212       }
02213       if(tit==tit_end) {
02214         termset.Insert(*sit);
02215   done=false;
02216       }
02217     }
02218   } while(!done);
02219   // remove those states
02220   DelStates(termset);
02221   // done
02222   return !InitStates().Empty();
02223 }
02224 
02225 // Complete w.r.t. rSigmaO 
02226 bool vGenerator::Complete(const EventSet& rSigmaO) {
02227 
02228   // prepare reverse transition relation
02229   TransSetX2EvX1 rtrel;
02230   TransRel(rtrel);
02231 
02232   // initialize nu-iteration
02233   StateSet domain=States();
02234 
02235   // nu-loop 
02236   while(true){
02237 
02238     // initialize mu-iteration
02239     StateSet target;
02240     TransSet::Iterator tit=TransRelBegin();
02241     TransSet::Iterator tit_end=TransRelEnd();
02242     while(tit!=tit_end) {
02243       if(!rSigmaO.Exists(tit->Ev)) { ++tit; continue; } 
02244       if(!domain.Exists(tit->X2)) { ++tit; continue; } 
02245       target.Insert(tit->X1);
02246       tit=TransRelEnd(tit->X1);
02247     }
02248 
02249     // mu-loop: find good states by reverse reachability
02250     StateSet good;
02251     StateSet::Iterator sit;
02252     std::stack<Idx> todo;
02253     for(sit = target.Begin(); sit != target.End(); ++sit) 
02254     todo.push(*sit);
02255     while(!todo.empty()) {
02256       // pop
02257       Idx x2=todo.top();
02258       todo.pop();
02259       // sense known
02260       if(good.Exists(x2)) continue; 
02261       // record
02262       good.Insert(x2);
02263       // iterate/push
02264       TransSetX2EvX1::Iterator tit=rtrel.BeginByX2(x2);
02265       TransSetX2EvX1::Iterator tit_end=rtrel.EndByX2(x2);
02266       for(; tit != tit_end; ++tit) 
02267         if(tit->X1 != x2) todo.push(tit->X1);
02268     }
02269 
02270     // nu-break: target will not change on update
02271     if(domain <= good) break;
02272  
02273     // nu-update: restrict target to have a successor within domain
02274     domain = domain * good;
02275 
02276   }
02277 
02278   // remove other states
02279   RestrictStates(domain);
02280 
02281   // done
02282   return !InitStates().Empty();
02283 }
02284 
02285 
02286 
02287 // TerminalStates()
02288 StateSet vGenerator::TerminalStates(const StateSet& rStates) const {
02289   FD_DG("Generator::TerminalStates(" << Name() << ")");
02290 
02291   // prepare result
02292   StateSet res;
02293   
02294   // loop states
02295   StateSet::Iterator sit=rStates.Begin();
02296   StateSet::Iterator sit_end=rStates.End();
02297   for(;sit!=sit_end;sit++){
02298     TransSet::Iterator tit=TransRelBegin(*sit);
02299     TransSet::Iterator tit_end=TransRelEnd(*sit);
02300     if(tit==tit_end) res.Insert(*sit);
02301   }
02302   // return terminal states
02303   res.Name("TerminalStates");
02304   return res;
02305 }
02306 
02307 // TerminalStates()
02308 StateSet vGenerator::TerminalStates(void) const {
02309   return TerminalStates(States());
02310 }
02311 
02312 
02313 // OmegaTrim
02314 bool vGenerator::OmegaTrim(void) {
02315 
02316   // note: this really is inefficient; at least we should
02317   // record the inverse transition relation for the coaccessile
02318   // iteration
02319 
02320   // first we make the generator accessible
02321   Accessible();
02322   // iterate coaccessible and complete until convergence in oserved
02323   while(1) {
02324     Idx osize=States().Size();
02325     Coaccessible();
02326     Complete();
02327     if(States().Size()==osize) break;
02328   }    
02329   // done
02330   return !InitStates().Empty() && !MarkedStates().Empty();
02331 }
02332 
02333 
02334 // IsOmegaTrim()
02335 bool vGenerator::IsOmegaTrim(void) const {
02336   bool res=true;
02337   if(!IsAccessible()) res=false;
02338   else if(!IsCoaccessible()) res=false;
02339   else if(!IsComplete()) res=false;
02340   FD_DF("vGenerator::IsOmegaTrim(): result " << res);
02341   return res;
02342 }
02343 
02344 
02345 
02346 // IsDeterministic()
02347 bool vGenerator::IsDeterministic(void) const {
02348   // if there is more than one initial state ... nondet
02349   if (InitStatesSize() > 1) {
02350     FD_DG("vGenerator::IsDeterministic: more than one initial state");
02351     return false;
02352   }
02353   // if there is a state/event pair with non-unique successor ... nondet
02354   if (TransRelSize() < 2) return true;
02355   TransSet::Iterator it1;
02356   TransSet::Iterator it2;
02357   for (it1 = TransRelBegin(), it2 = it1++; it1 != TransRelEnd(); it2 = it1++) {
02358     if ((it1->X1 == it2->X1) && (it1->Ev == it2->Ev)) {
02359       FD_DG("IsDeterministic(): at least one state "
02360       << "contains more than on transition with same event: " 
02361       << TStr(*it1));
02362      return false;
02363     }
02364   }
02365   // in all other cases generator is deterministic
02366   return true;
02367 }
02368 
02369 
02370 // ReindexOnWrite()
02371 bool vGenerator::ReindexOnWrite(void) const {
02372   return mReindexOnWrite;
02373 }
02374 
02375 // ReindexOnWrite(flag)
02376 void vGenerator::ReindexOnWrite(bool flag) {
02377   mReindexOnWrite = flag;
02378 }
02379 
02380 // ReindexOnWrite(flag)
02381 void vGenerator::ReindexOnWriteDefault(bool flag) {
02382   msReindexOnWriteDefault = flag;
02383 }
02384 
02385 // ReindexOnWrite(flag)
02386 bool vGenerator::ReindexOnWriteDefault(void) {
02387   return msReindexOnWriteDefault;
02388 }
02389 
02390 
02391 
02392 // DoWrite()
02393 void vGenerator::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
02394   (void) pContext;
02395   // pre 2.20 behaviour: re-index on file output
02396   /*
02397   if(rTw.FileMode()) 
02398     SetMinStateIndexMap();
02399   */
02400   // post 2.20 beaviour: re-index by configuration
02401   if(ReindexOnWrite())
02402     SetMinStateIndexMap();
02403   // figure section
02404   std::string label=rLabel;
02405   if(label=="") label="Generator"; 
02406   FD_DG("vGenerator(" << this << ")::DoWrite(): section " << label);
02407   // write generator
02408   rTw.WriteBegin(label);
02409   rTw << mMyName;
02410   rTw << "\n";
02411   rTw << "\n";
02412   SWrite(rTw);
02413   rTw << "\n";
02414   mpAlphabet->Write(rTw);
02415   rTw << "\n";
02416   WriteStates(rTw);
02417   rTw << "\n";
02418   WriteTransRel(rTw);
02419   rTw << "\n";
02420   WriteStateSet(rTw, mInitStates);
02421   rTw << "\n";
02422   WriteStateSet(rTw, mMarkedStates);
02423   rTw << "\n";
02424   mpGlobalAttribute->Write(rTw);
02425   rTw << "\n";
02426   rTw.WriteEnd(label);
02427   // end of reindex
02428   ClearMinStateIndexMap();
02429 }
02430 
02431 // DoDWrite()
02432 void vGenerator::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
02433   (void) pContext;
02434   // figure section
02435   std::string label=rLabel;
02436   if(label=="") label="Generator"; 
02437   FD_DG("vGenerator(" << this << ")::DoDWrite(): section " << label);
02438   // write generator
02439   rTw.WriteBegin(label);
02440   rTw << mMyName;
02441   rTw << "\n";
02442   rTw << "\n";
02443   SWrite(rTw);
02444   rTw << "\n";
02445   mpAlphabet->DWrite(rTw);
02446   rTw << "\n";
02447   DWriteStateSet(rTw, *mpStates);
02448   rTw << "\n";
02449   DWriteTransRel(rTw);
02450   rTw << "\n";
02451   DWriteStateSet(rTw, mInitStates);
02452   rTw << "\n";
02453   DWriteStateSet(rTw, mMarkedStates);
02454   rTw << "\n";
02455   mpGlobalAttribute->Write(rTw);
02456   rTw << "\n";
02457   rTw.WriteEnd(label);
02458   rTw << "\n";
02459 }
02460 
02461 // DoXWrite()
02462 void vGenerator::DoXWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
02463   (void) pContext;
02464   // Set up outer tag
02465   std::string label=rLabel;
02466   std::string ftype=TypeName();
02467   if(label=="") label="Generator";
02468   Token btag;
02469   btag.SetBegin(label);
02470   if(Name()!=label && Name()!="") btag.InsAttributeString("name",Name());
02471   if(ftype!=label && ftype!="") btag.InsAttributeString("ftype",ftype);
02472   FD_DG("vGenerator(" << this << ")::DoXWrite(..): section " << btag.StringValue() << " #" << Size());
02473   rTw.Write(btag);
02474   // Optional re-indexing
02475   if(mReindexOnWrite) SetMinStateIndexMap();
02476   // Write comcponents
02477   rTw << "\n";
02478   mpAlphabet->XWrite(rTw,"Alphabet");
02479   rTw << "\n";
02480   XWriteStateSet(rTw, *mpStates,"StateSet");
02481   rTw << "\n";
02482   XWriteTransRel(rTw);
02483   rTw << "\n";
02484   mpGlobalAttribute->XWrite(rTw);
02485   if(!mpGlobalAttribute->IsDefault())
02486     rTw << "\n";
02487   // Write end
02488   rTw.WriteEnd(btag.StringValue());
02489   // End of re-index
02490   ClearMinStateIndexMap();
02491 }
02492 
02493 // WriteAlphabet() 
02494 void vGenerator::WriteAlphabet(void) const {
02495   TokenWriter tw(TokenWriter::Stdout);
02496   WriteAlphabet(tw);
02497 }
02498 
02499 // AlphabetToString()
02500 std::string vGenerator::AlphabetToString(void) const {
02501   TokenWriter tw(TokenWriter::String);
02502   WriteAlphabet(tw);
02503   return tw.Str();
02504 }
02505 
02506 // WriteAlphabet(rTw&) 
02507 void vGenerator::WriteAlphabet(TokenWriter& rTw) const { 
02508   mpAlphabet->Write(rTw);
02509 }
02510 
02511 // WriteStateSet(rStateSet&) 
02512 void vGenerator::WriteStateSet(const StateSet&  rStateSet) const {
02513   TokenWriter tw(TokenWriter::Stdout);
02514   WriteStateSet(tw,rStateSet);
02515 }
02516 
02517 // StateSetToString()
02518 std::string vGenerator::StateSetToString(const StateSet&  rStateSet) const {
02519   TokenWriter tw(TokenWriter::String);
02520   WriteStateSet(tw,rStateSet);
02521   return tw.Str();
02522 }
02523 
02524 // StateSetToText()
02525 std::string vGenerator::StateSetToText(const StateSet&  rStateSet) const {
02526   TokenWriter tw(TokenWriter::String);
02527   tw.Endl(true);
02528   WriteStateSet(tw,rStateSet);
02529   return tw.Str();
02530 }
02531 
02532 
02533 // WriteStateSet(rTw&, rStateSet&) 
02534 void vGenerator::WriteStates(TokenWriter& rTw) const {
02535   // have my section
02536   rTw.WriteBegin("States");
02537   // test whether we reindex
02538   bool reindex=mMinStateIndexMap.size()>0;
02539   // if we reindex, setup reverse map to write in strategic order
02540   // to allow for consisten read (i.e. states with symbolic name first, starting
02541   // with index 1); this is the plain faudes file format from 2005
02542   if(reindex) {
02543     // reverse map
02544     std::map<Idx,Idx> reversemap;
02545     std::map<Idx,Idx>::const_iterator minit;
02546     StateSet::Iterator sit;
02547     for (sit = StatesBegin(); sit != StatesEnd(); ++sit) 
02548       reversemap[MinStateIndex(*sit)] = *sit;
02549     // iterate states to write 
02550     for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
02551       // identify anonymous block (consecutive state indices)
02552       std::map<Idx,Idx>::const_iterator conit=minit;
02553       Idx start = conit->first;
02554       Idx anoncount = 0;
02555       for(; conit != reversemap.end(); ++conit) {
02556         if(StateName(conit->second) != "") break;
02557         if(!StateAttribute(conit->second).IsDefault()) break;
02558         if(conit->first != start+anoncount) break;
02559         ++anoncount;
02560       }
02561       // write anonymous block
02562       if(anoncount > FD_CONSECUTIVE) {
02563         rTw.WriteBegin("Consecutive");
02564         rTw << start;
02565         rTw << start+anoncount-1;
02566         rTw.WriteEnd("Consecutive");
02567         minit=conit;
02568       } 
02569       // break loop
02570       if(minit == reversemap.end()) break;
02571       // write non anonymous state name/idx
02572       std::string statename = StateName(minit->second);
02573       if (statename != "") rTw << statename;
02574       else rTw << minit->first;
02575       // write state attribute
02576       const AttributeVoid& attr=StateAttribute(minit->second);
02577       attr.Write(rTw);
02578     }
02579   }
02580   // if we dont reindex, write symbolic names with index suffix to
02581   // enable a consistent read; this was introduced with libfaudes 2.20j
02582   if(!reindex) {
02583     // iterate states to write 
02584     bool symexpl = (States().MaxIndex() != States().Size());
02585     StateSet::Iterator sit;
02586     for(sit = StatesBegin(); sit != StatesEnd(); ++sit) {
02587       // identify anonymous block (consecutive state indices)
02588       StateSet::Iterator conit=sit;
02589       Idx start = *conit;
02590       Idx anoncount = 0;
02591       for(; conit != StatesEnd(); ++conit) {
02592         if(StateName(*conit) != "") break;
02593         if(!StateAttribute(*conit).IsDefault()) break;
02594         if(*conit != start+anoncount) break;
02595         ++anoncount;
02596       }
02597       // write anonymous block
02598       if(anoncount > FD_CONSECUTIVE) {
02599         rTw.WriteBegin("Consecutive");
02600         rTw << start;
02601         rTw << start+anoncount-1;
02602         rTw.WriteEnd("Consecutive");
02603         sit=conit;
02604       } 
02605       // break loop
02606       if(sit == StatesEnd()) break;
02607       // write index or name with index suffix
02608       std::string statename = StateName(*sit);
02609       if((statename != "") && symexpl) {
02610         rTw << (statename + "#"+ToStringInteger(*sit)) ;
02611       } else if(statename != "") {
02612         rTw << statename;
02613       } else {
02614         rTw << *sit;
02615       }
02616       // write attribute
02617       const AttributeVoid& attr=StateAttribute(*sit);
02618       attr.Write(rTw);
02619     }
02620   }
02621   // write end tag
02622   rTw.WriteEnd("States");
02623 }
02624 
02625 
02626 // WriteStateSet(rTw&, rStateSet&) 
02627 void vGenerator::WriteStateSet(TokenWriter& rTw, const StateSet&  rStateSet) const {
02628   rTw.WriteBegin(rStateSet.Name());
02629   // test whether we reindex
02630   bool reindex=mMinStateIndexMap.size()>0;
02631   // if we reindex, setup reverse map to write in strategic order;
02632   // reading back is no issue for external states, however, we would like
02633   // to provoke large consecutive blocks as a benefit from re-indexing
02634   if(reindex) {
02635     // reverse map
02636     std::map<Idx,Idx> reversemap;
02637     std::map<Idx,Idx>::const_iterator minit;
02638     StateSet::Iterator sit;
02639     for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) 
02640       reversemap[MinStateIndex(*sit)] = *sit;
02641     // iterate states to write 
02642     for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
02643       // identify anonymous block (consecutive state indices)
02644       std::map<Idx,Idx>::const_iterator conit=minit;
02645       Idx start = conit->first;
02646       Idx anoncount = 0;
02647       for(; conit != reversemap.end(); ++conit) {
02648         if(StateName(conit->second) != "") break;
02649         if(!StateAttribute(conit->second).IsDefault()) break;
02650         if(conit->first != start+anoncount) break;
02651         ++anoncount;
02652       }
02653       // write anonymous block
02654       if(anoncount > FD_CONSECUTIVE) {
02655         rTw.WriteBegin("Consecutive");
02656         rTw << start;
02657         rTw << start+anoncount-1;
02658         rTw.WriteEnd("Consecutive");
02659         minit=conit;
02660       } 
02661       // break loop
02662       if(minit == reversemap.end()) break;
02663       // write non anonymous state name/idx
02664       std::string statename = StateName(minit->second);
02665       if (statename != "") rTw << statename;
02666       else rTw << minit->first;
02667       // write state attribute
02668       const AttributeVoid& attr=rStateSet.Attribute(minit->second);
02669       attr.Write(rTw);
02670     }
02671   }
02672   // if we dont reindex, we dont need the reverse map; note that
02673   // external stateset will never have an explicit symbol table
02674   if(!reindex) {
02675     // iterate states to write 
02676     StateSet::Iterator sit;
02677     for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
02678       // identify anonymous block (consecutive state indices)
02679       StateSet::Iterator conit=sit;
02680       Idx start = *conit;
02681       Idx anoncount = 0;
02682       for(; conit != rStateSet.End(); ++conit) {
02683         if(StateName(*conit) != "") break;
02684         if(!StateAttribute(*conit).IsDefault()) break;
02685         if(*conit != start+anoncount) break;
02686         ++anoncount;
02687       }
02688       // write anonymous block
02689       if(anoncount > FD_CONSECUTIVE) {
02690         rTw.WriteBegin("Consecutive");
02691         rTw << start;
02692         rTw << start+anoncount-1;
02693         rTw.WriteEnd("Consecutive");
02694         sit=conit;
02695       } 
02696       // break loop
02697       if(sit == rStateSet.End()) break;
02698       // write non anonymous state name/idx
02699       std::string statename = StateName(*sit);
02700       if (statename != "") rTw << statename;
02701       else rTw << *sit;
02702       // write attribute
02703       const AttributeVoid& attr=rStateSet.Attribute(*sit);
02704       attr.Write(rTw);
02705     }
02706   }
02707   // write end tag
02708   rTw.WriteEnd(rStateSet.Name());
02709 }
02710 
02711 
02712 // DWriteStateSet(rTw&, rStateSet&) 
02713 void vGenerator::DWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet) const {
02714   rTw.WriteBegin(rStateSet.Name());
02715   StateSet::Iterator sit;
02716   for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
02717     rTw << SStr(*sit);
02718     const AttributeVoid& attr=rStateSet.Attribute(*sit);
02719     attr.Write(rTw);
02720   }
02721   rTw.WriteEnd(rStateSet.Name());
02722 }
02723 
02724 
02725 // XWriteStateSet(rTw&, rStateSet&) 
02726 void vGenerator::XWriteStateSet(TokenWriter& rTw, const StateSet&  rStateSet, const std::string& rLabel) const {
02727   // figure label
02728   std::string label=rLabel;
02729   if(label=="") label=rStateSet.Name();
02730   if(label=="") label="StateSet";
02731   rTw.WriteBegin(label);
02732   // build reverse index map of states to write ( fileidx->idx )
02733   // -- this ensures named states to be written first; see SetMinStateIndexMap()
02734   // -- this is required to figure consecutive blocks
02735   std::map<Idx,Idx> reversemap;
02736   std::map<Idx,Idx>::const_iterator minit;
02737   StateSet::Iterator sit;
02738   for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) {
02739     reversemap[MinStateIndex(*sit)] = *sit;
02740   }
02741   // iterate states to write 
02742   for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) {
02743     // identify anonymous block (consecutive state indices, no names, no attributes)
02744     std::map<Idx,Idx>::const_iterator conit=minit;
02745     Idx start = conit->first;
02746     Idx anoncount = 0;
02747     for(; conit != reversemap.end(); ++conit) {
02748       if(StateName(conit->second) != "") break;
02749       if(!StateAttribute(conit->second).IsDefault()) break;
02750       if(ExistsInitState(conit->second)) break;
02751       if(ExistsMarkedState(conit->second)) break;
02752       if(conit->first != start+anoncount) break;
02753       ++anoncount;
02754     }
02755     // write anonymous block
02756     if(anoncount > FD_CONSECUTIVE) {
02757       Token contag;
02758       contag.SetEmpty("Consecutive");
02759       contag.InsAttributeInteger("from",start);
02760       contag.InsAttributeInteger("to",start+anoncount-1);
02761       rTw.Write(contag);
02762       minit=conit;
02763     } 
02764     // break loop
02765     if(minit == reversemap.end() )
02766       break;
02767     // prepare state token
02768     Token sttag;    
02769     std::string statename = StateName(minit->second);
02770     Idx index=minit->first;
02771     sttag.SetBegin("State");
02772     sttag.InsAttributeInteger("id",index);
02773     if(statename!="")
02774     if(&rStateSet==mpStates) 
02775       sttag.InsAttributeString("name",statename);
02776     rTw.Write(sttag);
02777     // marking
02778     if(ExistsInitState(minit->second))   { sttag.SetEmpty("Initial"); rTw.Write(sttag);}; 
02779     if(ExistsMarkedState(minit->second)) { sttag.SetEmpty("Marked");  rTw.Write(sttag);}; 
02780     // attribute
02781     const AttributeVoid& attr=rStateSet.Attribute(minit->second);
02782     if(!attr.IsDefault()) attr.XWrite(rTw);
02783     // done
02784     rTw.WriteEnd("State");
02785   }
02786   rTw.WriteEnd(label);
02787 }
02788 
02789 
02790 // StatesToString()
02791 std::string vGenerator::StatesToString(void) const {
02792   return StateSetToString(*mpStates);
02793 }
02794 
02795 // StatesToText()
02796 std::string vGenerator::StatesToText(void) const {
02797   return StateSetToText(*mpStates);
02798 }
02799 
02800 // MarkedStatesToString()
02801 std::string vGenerator::MarkedStatesToString(void) const {
02802   return StateSetToString(mMarkedStates);
02803 }
02804 
02805 // InitStatesToString()
02806 std::string vGenerator::InitStatesToString(void) const {
02807   return StateSetToString(mInitStates);
02808 }
02809 
02810 
02811 // WriteTransRel() 
02812 void vGenerator::WriteTransRel(void) const {
02813   TokenWriter tw(TokenWriter::Stdout);
02814   WriteTransRel(tw);
02815 }
02816 
02817 // TransRelToString()
02818 std::string vGenerator::TransRelToString(void) const {
02819   TokenWriter tw(TokenWriter::String);
02820   WriteTransRel(tw);
02821   return tw.Str();
02822 }
02823 
02824 // TransRelToText()
02825 std::string vGenerator::TransRelToText(void) const {
02826   TokenWriter tw(TokenWriter::String);
02827   tw.Endl(true);
02828   WriteTransRel(tw);
02829   return tw.Str();
02830 }
02831 
02832 // WriteTransRel(rTw&)
02833 void vGenerator::WriteTransRel(TokenWriter& rTw) const {
02834   TransSet::Iterator tit;
02835   int oldcolumns = rTw.Columns();
02836   rTw.Columns(3);
02837   rTw.WriteBegin("TransRel");
02838   bool smalltransrel = (Size() < FD_SMALLTRANSREL);
02839 
02840   // loop all transitions
02841   for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
02842 
02843     // write x1
02844     Idx x1=MinStateIndex(tit->X1);
02845     if (smalltransrel) {
02846       std::string x1name = StateName(tit->X1);
02847       if (x1name != "") {
02848   rTw << x1name;
02849       } else {
02850   rTw << x1;
02851       }
02852     } else {
02853       rTw << x1;
02854     }
02855 
02856     // write ev
02857     rTw << EventName(tit->Ev);
02858 
02859     // write x2
02860     Idx x2=MinStateIndex(tit->X2);
02861     if (smalltransrel) {
02862       std::string x2name = StateName(tit->X2);
02863       if (x2name != "") {
02864   rTw << x2name;
02865       } else {
02866   rTw << x2;
02867       }
02868     } else {
02869       rTw << x2;
02870     }
02871 
02872     // write attributes
02873     TransAttribute(*tit).Write(rTw);
02874 
02875   }
02876   rTw.WriteEnd("TransRel");
02877   rTw.Columns(oldcolumns);
02878 }
02879 
02880 // DWriteTransRel(rTw&)
02881 void vGenerator::DWriteTransRel(TokenWriter& rTw) const {
02882   TransSet::Iterator tit;
02883   int oldcolumns = rTw.Columns();
02884   rTw.Columns(3);
02885   rTw.WriteBegin("TransRel");
02886   // iterate all transitions
02887   for (tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
02888     // write x1
02889     std::ostringstream ox1;
02890     Idx x1= tit->X1;
02891     std::string x1name = StateName(x1);
02892     if (x1name != "") {
02893       ox1 << x1name << "[" << x1 << "]";
02894     } else {
02895       ox1 << x1;
02896     }
02897     rTw << ox1.str();
02898     // write ev
02899     std::ostringstream oev;
02900     Idx ev= tit->Ev;
02901     std::string evname = EventName(ev);
02902     oev << evname << "[" << ev << "]";
02903     rTw << oev.str();
02904     // write x2
02905     std::ostringstream ox2;
02906     Idx x2= tit->X2;
02907     std::string x2name = StateName(x2);
02908     if (x2name != "") {
02909       ox2 << x2name << "[" << x2 << "]";
02910     } else {
02911       ox2 << x2;
02912     }
02913     rTw << ox2.str();
02914     // attribute
02915     mpTransRel->Attribute(*tit).Write(rTw);
02916   }
02917   rTw.WriteEnd("TransRel");
02918   rTw.Columns(oldcolumns);
02919 }
02920 
02921 
02922 // XWriteTransRel(rTw&)
02923 void vGenerator::XWriteTransRel(TokenWriter& rTw) const {
02924   TransSet::Iterator tit;
02925   rTw.WriteBegin("TransitionRelation");
02926 
02927   // loop all transitions
02928   for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) {
02929 
02930     // retrieve values x1
02931     Idx x1=MinStateIndex(tit->X1);
02932     Idx x2=MinStateIndex(tit->X2);
02933     std::string ev=EventName(tit->Ev);
02934 
02935     // prepare tag
02936     Token trtag;
02937     trtag.SetEmpty("Transition");
02938     trtag.InsAttributeInteger("x1",x1);
02939     trtag.InsAttributeString("event",ev);
02940     trtag.InsAttributeInteger("x2",x2);
02941 
02942     // consider attribute
02943     const AttributeVoid& attr=TransAttribute(*tit);
02944     // case a: indeed no attribute value
02945     if(attr.IsDefault()) {
02946       rTw.Write(trtag);
02947     } 
02948     // calse b: with attribute
02949     else {
02950       trtag.ClrEnd();
02951       rTw.Write(trtag);
02952       attr.XWrite(rTw);
02953       rTw.WriteEnd(trtag.StringValue());
02954     }
02955 
02956   }
02957   rTw.WriteEnd("TransitionRelation");
02958 }
02959 
02960 // DoSWrite(rTw&)
02961 void vGenerator::DoSWrite(TokenWriter& rTw) const
02962 {
02963   Type::DoSWrite(rTw);
02964   rTw.WriteComment(" States:        " + ToStringInteger(Size()) );
02965   rTw.WriteComment(" Init/Marked:   " + ToStringInteger(mInitStates.Size()) 
02966         + "/" + ToStringInteger(mMarkedStates.Size()));
02967   rTw.WriteComment(" Events:        " + ToStringInteger(mpAlphabet->Size()) );
02968   rTw.WriteComment(" Transitions:   " + ToStringInteger(mpTransRel->Size()) );
02969   rTw.WriteComment(" StateSymbols:  " + ToStringInteger(mpStateSymbolTable->Size()) );
02970   rTw.WriteComment(" Attrib. E/S/T: " + ToStringInteger(mpAlphabet->AttributesSize()) 
02971         + "/" + ToStringInteger(mpStates->AttributesSize())
02972         + "/" + ToStringInteger(mpTransRel->AttributesSize()) );
02973   rTw.WriteComment("");
02974 }
02975 
02976 // DotWrite(rFileName)
02977 void vGenerator::DotWrite(const std::string& rFileName) const {
02978   FD_DG("vGenerator(" << this << ")::DotWrite(" << rFileName << ")");
02979   SetMinStateIndexMap();
02980   StateSet::Iterator lit;
02981   TransSet::Iterator tit;
02982   try {
02983     std::ofstream stream;
02984     stream.exceptions(std::ios::badbit|std::ios::failbit);
02985     stream.open(rFileName.c_str());
02986     stream << "// dot output generated by libFAUDES vGenerator" << std::endl;
02987     stream << "digraph \"" << Name() << "\" {" << std::endl;
02988     stream << "  rankdir=LR" << std::endl;
02989     stream << "  node [shape=circle];" << std::endl;
02990     stream << std::endl;
02991     stream << "  // initial states" << std::endl;
02992     int i = 1;
02993     for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
02994       std::string xname= StateName(*lit);
02995       if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
02996       stream << "  dot_dummyinit_" << i << " [shape=none, label=\"\", width=\"0.0\", height=\"0.0\" ];" << std::endl;
02997       stream << "  dot_dummyinit_" << i << " -> \"" << xname << "\";" << std::endl; 
02998       i++;
02999     }
03000     stream << std::endl;
03001     stream << "  // mstates" << std::endl;
03002     for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
03003       std::string xname= StateName(*lit);
03004       if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
03005       stream << "  \"" << xname << "\" [shape=doublecircle];" << std::endl;
03006     }
03007     stream << std::endl;
03008     stream << "  // rest of stateset" << std::endl;
03009     for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
03010       if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) {
03011   std::string xname= StateName(*lit);
03012   if(xname=="") xname=ToStringInteger(MinStateIndex(*lit));
03013   stream << "  \"" << xname << "\";" << std::endl;
03014       }
03015     }
03016     stream << std::endl;
03017     stream << "  // transition relation" << std::endl;
03018     for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
03019       std::string x1name= StateName(tit->X1);
03020       if(x1name=="") x1name=ToStringInteger(MinStateIndex(tit->X1));
03021       std::string x2name= StateName(tit->X2);
03022       if(x2name=="") x2name=ToStringInteger(MinStateIndex(tit->X2));
03023       stream << "  \"" << x1name  << "\" -> \"" << x2name
03024        << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl;
03025     }
03026     stream << "};" << std::endl;
03027     stream.close();
03028   }
03029   catch (std::ios::failure&) {
03030     throw Exception("vGenerator::DotWrite", 
03031         "Exception opening/writing dotfile \""+rFileName+"\"", 2);
03032   }
03033   ClearMinStateIndexMap();
03034 }
03035 
03036 // DDotWrite(rFileName)
03037 void vGenerator::DDotWrite(const std::string& rFileName) const {
03038   FD_DG("vGenerator(" << this << ")::DDotWrite(" << rFileName << ")");
03039   StateSet::Iterator lit;
03040   TransSet::Iterator tit;
03041   try {
03042     std::ofstream stream;
03043     stream.exceptions(std::ios::badbit|std::ios::failbit);
03044     stream.open(rFileName.c_str());
03045     stream << "digraph \"" << Name() << "\" {" << std::endl;
03046     stream << "  rankdir=LR" << std::endl;
03047     stream << "  node [shape=circle];" << std::endl;
03048     stream << std::endl;
03049     stream << "  // istates" << std::endl;
03050     int i = 1;
03051     for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
03052       stream << "  dot_dummyinit_" << i << " [shape=none, label=\"\" ];" << std::endl;
03053       stream << "  dot_dummyinit_" << i << " -> \"" 
03054        << SStr(*lit)  << "\";" << std::endl; 
03055       i++;
03056     }
03057     stream << std::endl;
03058     stream << "  // mstates" << std::endl;
03059     for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
03060       stream << "  \"" << SStr(*lit) << "\" [shape=doublecircle];" << std::endl;
03061     }
03062     stream << std::endl;
03063     stream << "  // rest of stateset" << std::endl;
03064     for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
03065       // if not in mInitStates or mMarkedStates
03066       if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) {
03067   stream << "  \"" << SStr(*lit) << "\";" << std::endl;
03068       }
03069     }
03070     stream << std::endl;
03071     stream << "  // transition relation" << std::endl;
03072     for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
03073       stream << "  \"" << SStr(tit->X1) 
03074        << "\" -> \"" << SStr(tit->X2)
03075        << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl;
03076     }
03077     stream << "};" << std::endl;
03078     stream.close();
03079   }
03080   catch (std::ios::failure&) {
03081     throw Exception("vGenerator::DotWrite", 
03082         "Exception opening/writing dotfile \""+rFileName+"\"", 2);
03083   }
03084 }
03085 
03086 
03087 // XDotWrite(rFileName)
03088 void vGenerator::XDotWrite(const std::string& rFileName) const {
03089   FD_DG("vGenerator(" << this << ")::XDotWrite(" << rFileName << ")");
03090   StateSet::Iterator lit;
03091   TransSet::Iterator tit;
03092   try {
03093     std::ofstream stream;
03094     stream.exceptions(std::ios::badbit|std::ios::failbit);
03095     stream.open(rFileName.c_str());
03096     stream << "digraph \"___" << Name() << "___\" {" << std::endl;
03097     stream << "  rankdir=LR" << std::endl;
03098     stream << "  node [shape=circle];" << std::endl;
03099     stream << std::endl;
03100     stream << "  // stateset" << std::endl;
03101     for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) {
03102       stream << "  \"s" << *lit << "\";" << std::endl;
03103     }
03104     for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) {
03105       stream << "  \"s" << *lit << "\";" << std::endl;
03106     }
03107     for (lit = StatesBegin(); lit != StatesEnd(); ++lit) {
03108       if(ExistsInitState(*lit)) continue;
03109       if(ExistsMarkedState(*lit)) continue;
03110       stream << "  \"s" << *lit << "\";" << std::endl;
03111     }
03112     stream << std::endl;
03113     stream << "  // transition relation" << std::endl;
03114     for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) {
03115       stream << "  \"s" << tit->X1 
03116        << "\" -> \"s" << tit->X2
03117        << "\" [label=\"e" << tit->Ev << "\" " << "polyline" << "];" << std::endl;
03118     }
03119     stream << "};" << std::endl;
03120     stream.close();
03121   }
03122   catch (std::ios::failure&) {
03123     throw Exception("vGenerator::XDotWrite", 
03124         "Exception opening/writing dotfile \""+rFileName+"\"", 2);
03125   }
03126 }
03127 
03128 // DoRead(tr)
03129 void vGenerator::DoRead(TokenReader& rTr,  const std::string& rLabel, const Type* pContext) {
03130   (void) pContext;
03131   std::string label=rLabel;
03132   if(label=="") label="Generator"; 
03133   FD_DG("vGenerator(" << this << ")::DoRead(): file " << rTr.FileName() << "  section " << label);
03134   // Clear old stuff
03135   Clear();
03136   // find Generator in any of our current file formats
03137   Token btag;
03138   rTr.ReadBegin(label, btag);
03139   // sense native format
03140   Token token;
03141   rTr.Peek(token);
03142   // explcit name token: native libFAUDES file
03143   if(token.IsString()) {
03144     // get the Generator "name" token
03145     ReadGeneratorName(rTr);
03146     // read mAlphabet
03147     ReadAlphabet(rTr);
03148     // read stateset
03149     ReadStates(rTr);
03150     // read transrel
03151     ReadTransRel(rTr);
03152     // read istates
03153     ReadStateSet(rTr, "InitStates", mInitStates);
03154     // read mstates
03155     ReadStateSet(rTr, "MarkedStates", mMarkedStates);
03156     // read attribute
03157     mpGlobalAttribute->Read(rTr);
03158   }
03159   // else: try XML format
03160   else {
03161     // figure generator name
03162     std::string name="generator";
03163     if(btag.ExistsAttributeString("name")) 
03164       name=btag.AttributeStringValue("name");
03165     Name(name);
03166     // read alphabet 
03167     mpAlphabet->Read(rTr,"Alphabet");
03168     // read state set
03169     XReadStateSet(rTr, *mpStates, "StateSet");
03170     mpStates->Name("States");
03171     // read trans rel
03172     XReadTransRel(rTr);
03173     // read attribute
03174     mpGlobalAttribute->Read(rTr);
03175     // fix labels
03176     mInitStates.Name("InitStates");
03177     mMarkedStates.Name("MarkedStates");
03178   }
03179   // read end 
03180   rTr.ReadEnd(label);
03181   FD_DG("vGenerator(" << this << ")::DoRead(): done");
03182 }
03183 
03184 // ReadGeneratorName(rFileName)
03185 void vGenerator::ReadGeneratorName(const std::string& rFileName) {
03186   TokenReader tr(rFileName);
03187   tr.ReadBegin("Generator");  // mimique old behaviour .. use "ReadBegin" instead   
03188   ReadGeneratorName(tr);
03189 }
03190 
03191 // ReadGeneratorName(tr)
03192 void vGenerator::ReadGeneratorName(TokenReader& rTr) {
03193   FD_DG("vGenerator(" << this << ")::ReadGeneratorName(\"" 
03194   << rTr.FileName() << "\")");
03195    mMyName=rTr.ReadString();
03196 }
03197 
03198 // ReadAlphabet(rFileName)
03199 void vGenerator::ReadAlphabet(const std::string& rFileName) {
03200   FD_DG("vGenerator(" << this << ")::ReadAlphabet(\"" << rFileName << "\")");
03201   mpAlphabet->Read(rFileName,"Alphabet");
03202 }
03203 
03204 // ReadAlphabet(rTr) 
03205 void vGenerator::ReadAlphabet(TokenReader& rTr) {
03206   FD_DG("vGenerator(" << this << ")::ReadAlphabet(\"" 
03207   << rTr.FileName() << "\")");
03208   mpAlphabet->Read(rTr,"Alphabet");
03209 }
03210 
03211 // ReadStates(rFileName) 
03212 void vGenerator::ReadStates(const std::string& rFileName) {
03213   TokenReader tr(rFileName);
03214   ReadStates(tr);
03215 }
03216 
03217 // ReadStates(tr) 
03218 void vGenerator::ReadStates(TokenReader& rTr) {
03219   FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\")");
03220   // HELPERS:
03221   Token token;
03222   AttributeVoid* attrp = mpStates->Attribute().New();
03223   FD_DG("vGenerator(" << this << ")::ReadStates(..): attribute type " << typeid(*attrp).name());
03224   // ALGORITHM:
03225   mpStates->Clear();
03226   mpStates->Name("States");
03227   mStateSymbolTable.Clear();
03228   // track occurence of explicit symboltable
03229   bool symimpl=false;
03230   bool symexpl=false;
03231   Idx  symnext=1;
03232   // loop section
03233   rTr.ReadBegin("States");  
03234   while(!rTr.Eos("States")) {
03235     // peek
03236     rTr.Peek(token);
03237     // read state by index
03238     if(token.IsInteger()) {
03239       rTr.Get(token);
03240       Idx index = token.IntegerValue();
03241       FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by index " << index);
03242       if(mpStates->Exists(index)) {
03243         delete attrp;
03244   std::stringstream errstr;
03245   errstr << "Token " << token.IntegerValue() << " appears twice in stateset"
03246          << rTr.FileLine();
03247   throw Exception("vGenerator::ReadStates", errstr.str(), 80);
03248       }
03249       // read attribute
03250       attrp->Read(rTr,"",this);
03251       // skip unknown attributes
03252       AttributeVoid::Skip(rTr);
03253       // insert element with attribute
03254       InsState(index); 
03255       StateAttribute(index,*attrp);
03256       symnext++;
03257       continue;
03258     } 
03259     // read state by name
03260     if(token.IsString()) {
03261       rTr.Get(token);
03262       FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by name " << token.StringValue());
03263       // interpret name, sense index suffx if present
03264       std::string statename=token.StringValue();
03265       Idx index=symnext;
03266       std::size_t pos= statename.find_first_of('#');
03267       if(pos==std::string::npos) symimpl=true;
03268       if(pos!=std::string::npos) symexpl=true;
03269       if(pos!=std::string::npos && pos < statename.size()-1) {
03270   std::string suffix=statename.substr(pos+1);
03271         index=ToIdx(suffix);
03272         statename=statename.substr(0,pos);
03273         FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): extracted suffix from  " << token.StringValue() << ": " << statename << " idx " << index);
03274       }      
03275       // no doublets
03276       if(ExistsState(statename) || ExistsState(index)) {
03277         delete attrp;
03278   std::stringstream errstr;
03279   errstr << "State " << statename << "(idx " << index <<") appears twice in stateset"
03280          << rTr.FileLine();
03281   throw Exception("vGenerator::ReadStates", errstr.str(), 80);
03282       }
03283       // read attribute
03284       attrp->Read(rTr,"",this);
03285       // skip unknown attributes
03286       AttributeVoid::Skip(rTr);
03287       // insert element with attribute
03288       InsState(index); 
03289       StateName(index,statename);
03290       StateAttribute(index,*attrp);
03291       symnext++;
03292       continue;
03293     } 
03294     // read consecutive block of anonymous states
03295     if(token.IsBegin("Consecutive")) {
03296       rTr.ReadBegin("Consecutive");
03297       Token token1,token2;
03298       rTr.Get(token1);
03299       rTr.Get(token2);
03300       FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): consecutive range");
03301       if ((!token1.IsInteger()) || (!token2.IsInteger())) {
03302         delete attrp;
03303   std::stringstream errstr;
03304   errstr << "Invalid range of consecutive states"  << rTr.FileLine();
03305   throw Exception("vGenerator::ReadStates", errstr.str(), 80);
03306       }
03307       for(Idx index = (Idx) token1.IntegerValue(); index <= (Idx) token2.IntegerValue(); ++index) {
03308   if(mpStates->Exists(index)) {
03309           delete attrp;
03310     std::stringstream errstr;
03311     errstr << "Index " << index << " appears twice in stateset"
03312      << rTr.FileLine();
03313     throw Exception("vGenerator::ReadStates", errstr.str(), 80);
03314   }
03315   InsState(index);
03316         symnext++;
03317       }
03318       rTr.ReadEnd("Consecutive");
03319       continue;
03320     }
03321     // cannot process token
03322     delete attrp;
03323     std::stringstream errstr;
03324     errstr << "Invalid token" << rTr.FileLine();
03325     throw Exception("vGenerator::ReadStates", errstr.str(), 80);
03326   }
03327   rTr.ReadEnd("States");
03328   // test consistent explicit symboltable
03329   if(symimpl && symexpl) {
03330     delete attrp;
03331     std::stringstream errstr;
03332     errstr << "StateSet with inconsitent explicit symboltable" << rTr.FileLine();
03333     throw Exception("vGenerator::ReadStates", errstr.str(), 80);
03334   }
03335   // dispose attribute
03336   delete attrp;
03337   FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): done");
03338 }
03339 
03340 
03341 // ReadStateSet(tr, rLabel, rStateSet) 
03342 void vGenerator::ReadStateSet(TokenReader& rTr, const std::string& rLabel, StateSet& rStateSet)  const {
03343   FD_DG("vGenerator(" << this << ")::ReadStateSet(\"" << rLabel<< "\")");
03344   // HELPERS:
03345   Token token;
03346   AttributeVoid* attrp = rStateSet.Attribute().New();
03347   FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name());
03348   // ALGORITHM:
03349   rStateSet.Clear();
03350   rTr.ReadBegin(rLabel);  
03351   rStateSet.Name(rLabel);
03352   // loop section
03353   while(!rTr.Eos(rLabel)) {
03354     // peek
03355     rTr.Peek(token);
03356     // read state by index
03357     if(token.IsInteger()) {
03358       rTr.Get(token);
03359       Idx index = token.IntegerValue();
03360       if(!ExistsState(index)) {
03361         delete attrp;
03362   std::stringstream errstr;
03363   errstr << "Token " << token.IntegerValue() << " not in stateset"
03364          << rTr.FileLine();
03365   throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
03366       }
03367       // read attribute
03368       attrp->Read(rTr,"",this);
03369       // skip unknown attributes
03370       AttributeVoid::Skip(rTr);
03371       // insert element with attribute
03372       rStateSet.Insert(index); 
03373       rStateSet.Attribute(index,*attrp);
03374       continue;
03375     } 
03376     // read state by name
03377     if(token.IsString()) {
03378       rTr.Get(token);
03379       // test validity of symbolic name (no suffixes allowed here ... simply ignore)
03380       std::string statename=token.StringValue();
03381       std::size_t pos= statename.find_first_of('#');
03382       if(pos!=std::string::npos) {
03383         delete attrp;
03384   std::stringstream errstr;
03385   errstr << "invalid symbolic name: " << token.StringValue() 
03386            << " (no suffix allowed in external state sets)" << rTr.FileLine();
03387   throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
03388       }
03389       Idx index =StateIndex(statename);
03390       if(index==0) {
03391         delete attrp;
03392   std::stringstream errstr;
03393   errstr << "Symbolic name " << token.StringValue() << " not in stateset"
03394          << rTr.FileLine();
03395   throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
03396       }
03397       // read attribute
03398       attrp->Read(rTr,"",this);
03399       // skip unknown attributes
03400       AttributeVoid::Skip(rTr);
03401       // insert element with attribute
03402       rStateSet.Insert(index); 
03403       rStateSet.Attribute(index,*attrp);
03404       continue;
03405     } 
03406     // read consecutve block of anonymous states
03407     if(token.IsBegin() && token.StringValue() == "Consecutive") {
03408       rTr.ReadBegin("Consecutive");
03409       Token token1,token2;
03410       rTr.Get(token1);
03411       rTr.Get(token2);
03412       if(!token1.IsInteger() || !token2.IsInteger()) {
03413         delete attrp;
03414   std::stringstream errstr;
03415   errstr << "Invalid range of consecutive states"  << rTr.FileLine();
03416   throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
03417       }
03418       for(Idx index = (Idx) token1.IntegerValue(); index <= (Idx) token2.IntegerValue(); ++index) {
03419   if(!ExistsState(index)) {
03420     std::stringstream errstr;
03421     errstr << "Token " << token.IntegerValue() << " not in stateset"
03422      << rTr.FileLine();
03423     throw Exception("vGenerator::ReadStateSet", errstr.str(), 80);
03424   }
03425   rStateSet.Insert(index);
03426       }
03427       rTr.ReadEnd("Consecutive");
03428       continue;
03429     }
03430     // cannot process token
03431     delete attrp;
03432     std::stringstream errstr;
03433     errstr << "Invalid token" << rTr.FileLine();
03434     throw Exception("vGenerator::ReadStateSet", errstr.str(), 50);
03435   }
03436   rTr.ReadEnd(rLabel);
03437   // dispose attribute
03438   delete attrp;
03439 }
03440 
03441 // XReadStateSet(tr, rLabel, rStateSet) 
03442 void vGenerator::XReadStateSet(TokenReader& rTr, StateSet& rStateSet, const std::string& rLabel)  const {
03443   FD_DG("vGenerator(" << this << ")::XReadStateSet(\"" << rLabel<< "\")");
03444   AttributeVoid* attrp = rStateSet.Attribute().New();
03445   FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name());
03446   // Clear my set
03447   rStateSet.Clear();
03448   // Figure section
03449   std::string label=rLabel;
03450   if(label=="") label=rStateSet.Name();
03451   if(label=="") label="StateSet";
03452   // Read begin
03453   Token btag;
03454   rTr.ReadBegin(label,btag);  
03455   // Use name if provided (std is no name)
03456   rStateSet.Name("");
03457   if(btag.ExistsAttributeString("name"))
03458     rStateSet.Name(btag.AttributeStringValue("name"));
03459   // Scan my section
03460   while(!rTr.Eos(label)) {
03461     Token sttag;
03462     rTr.Get(sttag);
03463     // Read consecutive block of anonymous states
03464     if(sttag.IsBegin("Consecutive")) {
03465       // Get range
03466       Idx idx1=0;
03467       Idx idx2=0;
03468       if(sttag.ExistsAttributeInteger("from"))
03469         idx1= (Idx) sttag.AttributeIntegerValue("from");
03470       if(sttag.ExistsAttributeInteger("to"))
03471         idx2= (Idx) sttag.AttributeIntegerValue("to");
03472       // Insist in valid range
03473       if(idx1==0 || idx2 < idx1) {
03474         delete attrp;
03475   std::stringstream errstr;
03476   errstr << "Invalid range of consecutive states"  << rTr.FileLine();
03477   throw Exception("vGenerator::XReadStates", errstr.str(), 80);
03478       }
03479       FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): consecutive range " << idx1 << " to " << idx2);
03480       for(Idx index = idx1; index <= idx2; ++index) {
03481   if(rStateSet.Exists(index)) {
03482           delete attrp;
03483     std::stringstream errstr;
03484     errstr << "Doublet state index " << index << " " << rTr.FileLine();
03485     throw Exception("vGenerator::XReadStates", errstr.str(), 80);
03486   }
03487   rStateSet.Insert(index);
03488       }
03489       // Done: consecutive
03490       rTr.ReadEnd("Consecutive");
03491       continue;
03492     }
03493     // Ignore other sections
03494     if(!sttag.IsBegin("State")) {
03495       if(sttag.IsBegin()) 
03496         rTr.ReadEnd(sttag.StringValue());
03497       continue;
03498     }
03499     // Its a state
03500     std::string name="";
03501     if(sttag.ExistsAttributeString("name"))
03502       name=sttag.AttributeStringValue("name");
03503     Idx index=0;
03504     if(sttag.ExistsAttributeInteger("id"))
03505       index=sttag.AttributeIntegerValue("id");
03506     FD_DG("vGenerator::XReadStateSet(): got idx " << index << " " << name);
03507     // reconstruct index from name if possible
03508     if(index==0) {
03509       index=StateIndex(name);
03510     }
03511     // failed to figure index
03512     if(index==0) {
03513       delete attrp;
03514       std::stringstream errstr;
03515       errstr << "Cannot figure index for state token " << sttag.Str() << rTr.FileLine();
03516       throw Exception("vGenerator::XReadStateSet", errstr.str(), 80);
03517     }
03518     // dont allow doublets
03519     if(rStateSet.Exists(index)) {
03520       delete attrp;
03521       std::stringstream errstr;
03522       errstr << "Doublet state from token " << sttag.Str() << rTr.FileLine();
03523       throw Exception("vGenerator::XReadStateSet", errstr.str(), 80);
03524     }
03525     // record state
03526     rStateSet.Insert(index);
03527     // record name if we read the core set
03528     if(&rStateSet==mpStates) 
03529     if(name!="") {
03530        mpStateSymbolTable->SetEntry(index, name);
03531     }
03532     // test for attributes and such
03533     while(!rTr.Eos("State")) {
03534       Token token;
03535       rTr.Peek(token);
03536       // marking (if this is the main state set)
03537       Token mtag; 
03538       if(token.IsBegin("Initial") && (&rStateSet==mpStates)) { 
03539         rTr.ReadBegin("Initial",mtag);  
03540         bool v=true;
03541         if(mtag.ExistsAttributeInteger("value"))
03542           v=mtag.AttributeIntegerValue("value");
03543         if(v) const_cast<vGenerator*>(this)->SetInitState(index);
03544         rTr.ReadEnd("Initial");
03545         continue;
03546       }
03547       if(token.IsBegin("Marked") && (&rStateSet==mpStates)) { 
03548         rTr.ReadBegin("Marked",mtag);  
03549         bool v=true;
03550         if(mtag.ExistsAttributeInteger("value"))
03551           v=mtag.AttributeIntegerValue("value");
03552         if(v) const_cast<vGenerator*>(this)->SetMarkedState(index);
03553         rTr.ReadEnd("Marked");
03554         continue;
03555       }
03556       // read attribute
03557       FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): attribute ?");
03558       attrp->Read(rTr,"",this);
03559       rStateSet.Attribute(index,*attrp);
03560       // break on first unknown/undigested
03561       break;
03562     } 
03563     // read end
03564     rTr.ReadEnd("State");
03565   }
03566   rTr.ReadEnd(label);
03567   // dispose attribute
03568   delete attrp;
03569   FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): done");
03570 }
03571 
03572 
03573 // ReadTransRel(rFileName)
03574 void vGenerator::ReadTransRel(const std::string& rFileName) {
03575   TokenReader tr(rFileName);
03576   ReadTransRel(tr);
03577 }
03578 
03579 // ReadTransRel(tr) 
03580 void vGenerator::ReadTransRel(TokenReader& rTr) {
03581   FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\")");
03582   AttributeVoid* attrp = mpTransRel->Attribute().New();
03583   FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name());
03584   try {
03585     Token token;
03586     Token x1t;
03587     Token x2t;
03588     Token evt;
03589     rTr.ReadBegin("TransRel");
03590     // Read tokens
03591     while (rTr.Peek(token)) {
03592 
03593       // clear my transition
03594       Idx x1 = 0, ev = 0, x2 = 0;
03595 
03596       // 0: end of transition relation
03597       if(token.IsEnd()) break;
03598 
03599 
03600       // 1: the x1 token
03601       rTr >> x1t;
03602       if(x1t.IsInteger()) {
03603   x1=x1t.IntegerValue();
03604       } else if (x1t.IsString()) {
03605   x1t.StringValue();
03606   x1=StateIndex(x1t.StringValue());
03607       } else break;
03608 
03609       // 2: the event token
03610       rTr >> evt;
03611       if(evt.IsString()) {
03612   evt.StringValue();
03613   ev=EventIndex(evt.StringValue());
03614       } else break;
03615 
03616       // 3: the x2 evt
03617       rTr >> x2t;
03618       if(x2t.IsInteger()) {
03619   x2=x2t.IntegerValue();
03620       } else if(x2t.IsString()) {
03621   x2t.StringValue();
03622   x2=StateIndex(x2t.StringValue());
03623       } else break;
03624 
03625       // 4: attributes
03626       attrp->Read(rTr,"",this);
03627 
03628       // 5: skip unknown attributes
03629       AttributeVoid::Skip(rTr);
03630 
03631       // check values
03632       if(!ExistsState(x1)){
03633   std::stringstream errstr;
03634   errstr << "invalid state x1 " << x1t.StringValue() << " " << rTr.FileLine();
03635   throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
03636       } 
03637       if(!ExistsState(x2)){
03638   std::stringstream errstr;
03639   errstr << "invalid state x2 " << x2t.StringValue() << " " << rTr.FileLine();
03640   throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
03641       } 
03642       if(!ExistsEvent(ev)) {
03643   std::stringstream errstr;
03644   errstr << "invalid event " << evt.StringValue() << " " << rTr.FileLine();
03645   throw Exception("vGenerator::ReadTransRel", errstr.str(), 85);
03646       } 
03647 
03648       // insert transition
03649       Transition trans=Transition(x1,ev,x2);
03650       SetTransition(trans);
03651       TransAttribute(trans,*attrp);
03652 
03653     } // end while
03654     rTr.ReadEnd("TransRel");   
03655   }
03656 
03657   catch (faudes::Exception& oex) {
03658     delete attrp;
03659     std::stringstream errstr;
03660     errstr << "Reading TransRel failed in " << rTr.FileLine() << oex.What();
03661     throw Exception("vGenerator::ReadTransRel", errstr.str(), 50); 
03662   }
03663   FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\"): sone");
03664 
03665   // dispose attribute
03666   delete attrp;
03667 }
03668 
03669 
03670 // XReadTransRel(tr) 
03671 void vGenerator::XReadTransRel(TokenReader& rTr) {
03672   FD_DG("vGenerator(" << this << ")::XReadTransRel()");
03673   AttributeVoid* attrp = mpTransRel->Attribute().New();
03674   FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name());
03675   // Clear my set
03676   mpTransRel->Clear();
03677   mpTransRel->Name("TransRel");
03678   // Read begin
03679   Token btag;
03680   rTr.ReadBegin("TransitionRelation",btag);  
03681   // Scan my section
03682   while(!rTr.Eos("TransitionRelation")) {
03683     Token trtag;
03684     rTr.Get(trtag);
03685     // Ignore other sections
03686     if(!trtag.IsBegin("Transition")) {
03687       if(trtag.IsBegin()) 
03688         rTr.ReadEnd(trtag.StringValue());
03689       continue;
03690     }
03691     // Its a transition
03692     Idx x1=0;
03693     Idx x2=0;
03694     Idx ev=0;
03695     std::string evname;
03696     std::string x1name;
03697     std::string x2name;
03698     if(trtag.ExistsAttributeInteger("x1"))
03699       x1=trtag.AttributeIntegerValue("x1");
03700     if(trtag.ExistsAttributeInteger("x2"))
03701       x2=trtag.AttributeIntegerValue("x2");
03702     if(trtag.ExistsAttributeString("x1"))
03703       x1name=trtag.AttributeStringValue("x1");
03704     if(trtag.ExistsAttributeString("x2"))
03705       x2name=trtag.AttributeStringValue("x2");
03706     if(trtag.ExistsAttributeString("event"))
03707       evname=trtag.AttributeStringValue("event");
03708     // Interpret names
03709     ev=EventIndex(evname);
03710     if(x1==0) x1=StateIndex(x1name);
03711     if(x2==0) x2=StateIndex(x2name);
03712     // Report
03713     FD_DG("vGenerator::XReadTransRel(): got transition " << TStr(Transition(x1,ev,x2)));
03714     // test 1: components specified
03715     if(x1==0 || x2==0 || ev==0) {
03716       delete attrp;
03717       std::stringstream errstr;
03718       errstr << "Invalid transition at token " << trtag.Str() << rTr.FileLine();
03719       throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
03720     }
03721     // test 2: no doublets
03722     if(ExistsTransition(x1,ev,x2)) {
03723       delete attrp;
03724       std::stringstream errstr;
03725       errstr << "Doublet transition at token " << trtag.Str() << rTr.FileLine();
03726       throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
03727     }
03728     // test 3: components must exist
03729     if(!ExistsState(x1)){
03730       delete attrp;
03731       std::stringstream errstr;
03732       errstr << "Invalid state x1 " << x1 << " " << rTr.FileLine();
03733       throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
03734     } 
03735     if(!ExistsState(x2)){
03736       delete attrp;
03737       std::stringstream errstr;
03738       errstr << "Invalid state x2 " << x2 << " " << rTr.FileLine();
03739       throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
03740     } 
03741     if(!ExistsEvent(ev)){
03742       delete attrp;
03743       std::stringstream errstr;
03744       errstr << "Invalid event  " << evname << " " << rTr.FileLine();
03745       throw Exception("vGenerator::XReadTransRel", errstr.str(), 80);
03746     } 
03747     // record transition
03748     SetTransition(x1,ev,x2);
03749     // test for attribute
03750     Token token;
03751     rTr.Peek(token);
03752     if(!token.IsEnd("Transition")) {
03753       // read attribute
03754       attrp->Read(rTr,"",this);
03755       TransAttribute(Transition(x1,ev,x2),*attrp);
03756     } 
03757     // read end
03758     rTr.ReadEnd("Transition");
03759   }
03760   rTr.ReadEnd("TransitionRelation");
03761   // dispose attribute
03762   delete attrp;
03763   FD_DG("vGenerator(" << this << ")::XReadTransRel(\"" << rTr.FileName() << "\"): done");
03764 }
03765 
03766 // EStr(index)
03767 std::string vGenerator::EStr(Idx index) const {
03768   std::string name = EventName(index);
03769   return name+"#"+faudes::ToStringInteger(index);
03770 }
03771 
03772 // SStr(index)
03773 std::string vGenerator::SStr(Idx index) const {
03774   std::string name = StateName(index);
03775   if(name == "") name=ToStringInteger(index);
03776   return name+"#"+faudes::ToStringInteger(index);
03777 }
03778 
03779 // TStr(index)
03780 std::string vGenerator::TStr(const Transition& trans) const {
03781   return SStr(trans.X1) + "--(" + EStr(trans.Ev) + ")-->" + SStr(trans.X2);
03782 }
03783 
03784 
03785 // GraphWrite(rFileName,rOutFormat)
03786 void vGenerator::GraphWrite(const std::string& rFileName, const std::string& rOutFormat,
03787    const std::string& rDotExec) const {
03788   FD_DG("vGenerator::GraphWrite(...): " << typeid(*this).name());
03789   // generate temp dot ibput file
03790   std::string dotin = CreateTempFile();
03791   if(dotin == "") {
03792     std::stringstream errstr;
03793     errstr << "Exception opening temp file";
03794     throw Exception("vGenerator::GraphWrite", errstr.str(), 2);
03795   }
03796   try{
03797     DotWrite(dotin);
03798   } 
03799   catch (faudes::Exception& exception) {  
03800     RemoveFile(dotin);
03801     std::stringstream errstr;
03802     errstr << "Exception writing dot input file";
03803     throw Exception("vGenerator::GraphWrite", errstr.str(), 2);
03804   }
03805   try{
03806     faudes::ProcessDot(dotin,rFileName,rOutFormat,rDotExec);
03807   } 
03808   catch (faudes::Exception& exception) {  
03809     RemoveFile(dotin);
03810     std::stringstream errstr;
03811     errstr << "Exception processing dot file";
03812     throw Exception("vGenerator::GraphWrite", errstr.str(), 3);
03813   }
03814   RemoveFile(dotin);
03815 }
03816 
03817 // rti wrapper
03818 bool IsAccessible(const vGenerator& rGen) {
03819   return rGen.IsAccessible();
03820 }
03821 
03822 // rti wrapper
03823 bool IsCoaccessible(const vGenerator& rGen) {
03824   return rGen.IsCoaccessible();
03825 }
03826 
03827 // rti wrapper
03828 bool IsTrim(const vGenerator& rGen) {
03829   return rGen.IsTrim();
03830 }
03831 
03832 // rti wrapper
03833 bool IsOmegaTrim(const vGenerator& rGen) {
03834   return rGen.IsOmegaTrim();
03835 }
03836 
03837 // rti wrapper
03838 bool IsComplete(const vGenerator& rGen) {
03839   return rGen.IsComplete();
03840 }
03841 
03842 // rti wrapper
03843 bool IsComplete(const vGenerator& rGen, const StateSet& rStateSet) {
03844   return rGen.IsComplete(rStateSet);
03845 }
03846 
03847 // rti wrapper
03848 bool IsComplete(const vGenerator& rGen, const EventSet& rSigmaO) {
03849   return rGen.IsComplete(rSigmaO);
03850 }
03851 
03852 // rti wrapper
03853 bool IsDeterministic(const vGenerator& rGen) {
03854   return rGen.IsDeterministic();
03855 }
03856 
03857 
03858 // rti wrapper
03859 void Accessible(vGenerator& rGen) {
03860   rGen.Accessible();
03861 }
03862 
03863 // rti wrapper
03864 void Accessible(const vGenerator& rGen, vGenerator& rRes) {
03865   rRes=rGen;
03866   rRes.Accessible();
03867 }  
03868 
03869 // rti wrapper
03870 void Coaccessible(vGenerator& rGen) {
03871   rGen.Coaccessible();
03872 }
03873 
03874 // rti wrapper
03875 void Coaccessible(const vGenerator& rGen, vGenerator& rRes) {
03876   rRes=rGen;
03877   rRes.Coaccessible();
03878 }  
03879 
03880 // rti wrapper
03881 void Complete(vGenerator& rGen) {
03882   rGen.Complete();
03883 }
03884 
03885 // rti wrapper
03886 void Complete(const vGenerator& rGen, vGenerator& rRes) {
03887   rRes=rGen;
03888   rRes.Complete();
03889 }  
03890 
03891 // rti wrapper
03892 void Complete(vGenerator& rGen, const EventSet& rSigmaO) {
03893   rGen.Complete(rSigmaO);
03894 }
03895 
03896 // rti wrapper
03897 void Complete(const vGenerator& rGen, const EventSet& rSigmaO, vGenerator& rRes) {
03898   rRes=rGen;
03899   rRes.Complete(rSigmaO);
03900 }  
03901 
03902 // rti wrapper
03903 void Trim(vGenerator& rGen) {
03904   rGen.Trim();
03905 }
03906 
03907 // rti wrapper
03908 void Trim(const vGenerator& rGen, vGenerator& rRes) {
03909   rRes=rGen;
03910   rRes.Trim();
03911 }  
03912 
03913 // rti wrapper
03914 void OmegaTrim(vGenerator& rGen) {
03915   rGen.OmegaTrim();
03916 }
03917 
03918 // rti wrapper
03919 void OmegaTrim(const vGenerator& rGen, vGenerator& rRes) {
03920   rRes=rGen;
03921   rRes.OmegaTrim();
03922 }  
03923 
03924 // rti wrapper
03925 void MarkAllStates(vGenerator& rGen) {
03926   rGen.InjectMarkedStates(rGen.States());
03927 }
03928 
03929 
03930 // rti wrapper
03931 void AlphabetExtract(const vGenerator& rGen, EventSet& rRes) {
03932   // This function is an ideal debugging case for lbp_function.cpp.
03933   // FD_WARN("AlphabetExtract(): gen at " << &rGen << " sig at " << &rRes);
03934   // FD_WARN("AlphabetExtract(): gen id " << typeid(rGen).name() << " sig id " << typeid(rRes).name());
03935   rRes = rGen.Alphabet();
03936   // rRes.Write();
03937 }
03938 
03939 // rti convenience function
03940 void SetIntersection(const GeneratorVector& rGenVec, EventSet& rRes) {
03941   // prepare result
03942   rRes.Clear();
03943   // ignore empty
03944   if(rGenVec.Size()==0) return;
03945   // copy first
03946   rRes.Assign(rGenVec.At(0).Alphabet());
03947   // perform intersecttion 
03948   for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) 
03949     SetIntersection(rGenVec.At(i).Alphabet(),rRes,rRes);
03950 }
03951 
03952 
03953 // rti convenience function
03954 void SetUnion(const GeneratorVector& rGenVec, EventSet& rRes) {
03955   // prepare result
03956   rRes.Clear();
03957   // ignore empty
03958   if(rGenVec.Size()==0) return;
03959   // copy first
03960   rRes.Assign(rGenVec.At(0).Alphabet());
03961   // perform intersecttion 
03962   for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) 
03963     SetUnion(rGenVec.At(i).Alphabet(),rRes,rRes);
03964 }
03965 
03966 // rti convenience function
03967 void SetIntersection(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
03968   SetIntersection(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
03969 }
03970 
03971 // rti convenience function
03972 void SetUnion(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
03973   SetUnion(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
03974 }
03975 
03976 // rti convenience function
03977 void SetDifference(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) {
03978   SetDifference(rGenA.Alphabet(),rGenB.Alphabet(),rRes);
03979 }
03980 
03981 
03982 } // name space
03983 
03984 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen