libFAUDES
Sections
Index
|
cfl_generator.cppGo 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 } 01175 01176 // InsEvent(index) 01177 bool vGenerator::InsEvent(Idx index) { 01178 FD_DG("vGenerator(" << this << ")::InsEvent(" << index << ")"); 01179 return mpAlphabet->Insert(index); 01180 } 01181 01182 // InsEvent(rName) 01183 Idx vGenerator::InsEvent(const std::string& rName) { 01184 FD_DG("vGenerator(" << this << ")::InsEvent(\"" << rName << "\")"); 01185 return mpAlphabet->Insert(rName); 01186 } 01187 01188 // InsEvents(events) 01189 void vGenerator::InsEvents(const EventSet& events) { 01190 mpAlphabet->InsertSet(events); 01191 } 01192 01193 // DelEvent(index) 01194 bool vGenerator::DelEvent(Idx index) { 01195 FD_DG("vGenerator(" << this << ")::DelEvent(" << index << ")"); 01196 mpTransRel->EraseByEv(index); 01197 return mpAlphabet->Erase(index); 01198 } 01199 01200 // DelEvent(rName) 01201 bool vGenerator::DelEvent(const std::string& rName) { 01202 FD_DG("vGenerator(" << this << ")::DelEvent(\"" << rName << "\")"); 01203 Idx index = mpAlphabet->Index(rName); 01204 mpTransRel->EraseByEv(index); 01205 return mpAlphabet->Erase(index); 01206 } 01207 01208 // DelEvents(events) 01209 void vGenerator::DelEvents(const EventSet& rEvents) { 01210 FD_DG("vGenerator(" << this << ")::DelEvents(\"" 01211 << rEvents.ToString() << "\")"); 01212 EventSet::Iterator it; 01213 for (it = rEvents.Begin(); it != rEvents.End(); ++it) { 01214 DelEvent(*it); 01215 } 01216 } 01217 01218 // DelEventFromAlphabet(index) 01219 bool vGenerator::DelEventFromAlphabet(Idx index) { 01220 FD_DG("vGenerator(" << this << ")::DelEventFromAlphabet(" 01221 << index << ")"); 01222 return mpAlphabet->Erase(index); 01223 } 01224 01225 // InsState() 01226 Idx vGenerator::InsState(void) { 01227 FD_DG("vGenerator(" << this << ")::InsState()"); 01228 return mpStates->Insert(); 01229 } 01230 01231 // InsState(index) 01232 bool vGenerator::InsState(Idx index) { 01233 FD_DG("vGenerator(" << this << ")::InsState(" << index << ")"); 01234 return mpStates->Insert(index); 01235 } 01236 01237 // InsState(rName) 01238 Idx vGenerator::InsState(const std::string& rName) { 01239 FD_DG("vGenerator(" << this << ")::InsState(\"" << rName << "\")"); 01240 Idx index=mpStates->Insert(); 01241 StateName(index,rName); 01242 return index; 01243 } 01244 01245 // InsStates(states) 01246 void vGenerator::InsStates(const StateSet& states) { 01247 mpStates->InsertSet(states); 01248 } 01249 01250 // InjectState(index) 01251 void vGenerator::InjectState(Idx index) { 01252 FD_DG("vGenerator(" << this << ")::InjectState(\"" << SStr(index) << "\")"); 01253 mpStates->Insert(index); 01254 } 01255 01256 // InjectStates(rNewStates) 01257 void vGenerator::InjectStates(const StateSet& rNewStates) { 01258 FD_DG("vGenerator(" << this << ")::InjectStates(" << rNewStates.ToString() << ")"); 01259 *mpStates=rNewStates; 01260 mpStates->Name("States"); 01261 mpStateSymbolTable->RestrictDomain(*mpStates); 01262 FD_DG("vGenerator(" << this << ")::InjectStates(): report " << mpStates->ToString()); 01263 } 01264 01265 // InsInitState() 01266 Idx vGenerator::InsInitState(void) { 01267 FD_DG("vGenerator(" << this << ")::InsInitState()"); 01268 Idx index; 01269 index = InsState(); 01270 mInitStates.Insert(index); 01271 return index; 01272 } 01273 01274 // InsInitState(name) 01275 Idx vGenerator::InsInitState(const std::string& rName) { 01276 FD_DG("vGenerator(" << this << ")::InsInitState(\"" << rName << "\")"); 01277 Idx index; 01278 index = InsState(rName); 01279 mInitStates.Insert(index); 01280 return index; 01281 } 01282 01283 // InsInitState(name) 01284 bool vGenerator::InsInitState(Idx index) { 01285 bool res=InsState(index); 01286 mInitStates.Insert(index); 01287 return res; 01288 } 01289 01290 // InsInitStates(states) 01291 void vGenerator::InsInitStates(const StateSet& states) { 01292 mpStates->InsertSet(states); 01293 mInitStates.InsertSet(states); 01294 } 01295 01296 // InsMarkedState() 01297 Idx vGenerator::InsMarkedState(void) { 01298 FD_DG("vGenerator(" << this << ")::InsMarkedState()"); 01299 Idx index; 01300 index = InsState(); 01301 mMarkedStates.Insert(index); 01302 return index; 01303 } 01304 01305 // InsInitState(name) 01306 bool vGenerator::InsMarkedState(Idx index) { 01307 bool res=InsState(index); 01308 mMarkedStates.Insert(index); 01309 return res; 01310 } 01311 01312 // InsMarkedState(rName) 01313 Idx vGenerator::InsMarkedState(const std::string& rName) { 01314 FD_DG("vGenerator(" << this << ")::InsMarkedState(\"" << rName << "\")"); 01315 Idx index; 01316 index = InsState(rName); 01317 mMarkedStates.Insert(index); 01318 return index; 01319 } 01320 01321 // InsMarkedStates(states) 01322 void vGenerator::InsMarkedStates(const StateSet& states) { 01323 mpStates->InsertSet(states); 01324 mMarkedStates.InsertSet(states); 01325 } 01326 01327 01328 // DelState(index) 01329 bool vGenerator::DelState(Idx index) { 01330 FD_DG("vGenerator(" << this << ")::DelState(" << index << ")"); 01331 // mInitStates 01332 mInitStates.Erase(index); 01333 // mstates 01334 mMarkedStates.Erase(index); 01335 // transrel 01336 mpTransRel->EraseByX1OrX2(index); 01337 // symbolic name 01338 mpStateSymbolTable->ClrEntry(index); 01339 // finally ... remove the state 01340 return mpStates->Erase(index); 01341 } 01342 01343 // DelState(rName) 01344 bool vGenerator::DelState(const std::string& rName) { 01345 FD_DG("vGenerator(" << this << ")::DelState(\"" << rName << "\")"); 01346 Idx index; 01347 index = StateIndex(rName); 01348 #ifdef FAUDES_CHECKED 01349 if (index == 0) { 01350 std::stringstream errstr; 01351 errstr << "state name \"" << rName << "\" not found in generator \"" 01352 << Name() << "\""; 01353 throw Exception("vGenerator::DelState(name)", errstr.str(), 90); 01354 } 01355 #endif 01356 return DelState(index); 01357 } 01358 01359 // DelStates(rDelStates) 01360 void vGenerator::DelStates(const StateSet& rDelStates) { 01361 FD_DG("vGenerator(" << this << ")::DelStates(" 01362 << rDelStates.ToString() << ")"); 01363 StateSet::Iterator cit; 01364 StateSet::Iterator cit_end; 01365 // symbolic state names 01366 for (cit = rDelStates.Begin(); cit != rDelStates.End(); ++cit) { 01367 mpStateSymbolTable->ClrEntry(*cit); 01368 } 01369 // statesets 01370 mpStates->EraseSet(rDelStates); 01371 mInitStates.EraseSet(rDelStates); 01372 mMarkedStates.EraseSet(rDelStates); 01373 // mpTransRel: 01374 mpTransRel->EraseByX1OrX2(rDelStates); 01375 } 01376 01377 // DelStateFromStates(index) 01378 bool vGenerator::DelStateFromStates(Idx index) { 01379 FD_DG("vGenerator(" << this << ")::DelStateFromStates(" << index << ")"); 01380 // mStates + global 01381 return mpStates->Erase(index); 01382 } 01383 01384 // DelStateFromStates(pos) 01385 StateSet::Iterator vGenerator::DelStateFromStates(StateSet::Iterator pos) { 01386 FD_DG("vGenerator(" << this << ")::DelState(" << *pos << ")"); 01387 return mpStates->Erase(pos); 01388 } 01389 01390 // SetInitState(index) 01391 void vGenerator::SetInitState(Idx index) { 01392 FD_DG("vGenerator(" << this << ")::SetInitState(" << index << ")"); 01393 #ifdef FAUDES_CHECKED 01394 if (! mpStates->Exists(index)) { 01395 std::stringstream errstr; 01396 errstr << "vGenerator::SetMarkedState: index " << index 01397 << " not in stateset"; 01398 throw Exception("vGenerator::SetInitState(..)", errstr.str(), 91); 01399 } 01400 #endif 01401 mInitStates.Insert(index); 01402 } 01403 01404 // SetInitState(rName) 01405 void vGenerator::SetInitState(const std::string& rName) { 01406 FD_DG("vGenerator(" << this << ")::SetInitState(\"" << rName << "\")"); 01407 Idx index = StateIndex(rName); 01408 #ifdef FAUDES_CHECKED 01409 if (index == 0) { 01410 std::stringstream errstr; 01411 errstr << "State name \"" << rName << "\" not known in Generator"; 01412 throw Exception("vGenerator::SetInitState(..)", errstr.str(), 90); 01413 } 01414 #endif 01415 SetInitState(index); 01416 } 01417 01418 // InjectInitStates(rNewInitStates) 01419 void vGenerator::InjectInitStates(const StateSet& rNewInitStates) { 01420 FD_DG("vGenerator(" << this << ")::InjectInitStates(" 01421 << rNewInitStates.ToString() << ")"); 01422 mInitStates = rNewInitStates; 01423 mInitStates.Name("InitStates"); 01424 } 01425 01426 // ClrInitState(index) 01427 void vGenerator::ClrInitState(Idx index) { 01428 FD_DG("vGenerator(" << this << ")::ClrInitState(" << index << ")"); 01429 #ifdef FAUDES_CHECKED 01430 if (! mpStates->Exists(index)) { 01431 std::stringstream errstr; 01432 errstr << "vGenerator::SetMarkedState: index " << index 01433 << " not in stateset"; 01434 throw Exception("vGenerator::ClrInitState(..)", errstr.str(), 91); 01435 } 01436 #endif 01437 mInitStates.Erase(index); 01438 } 01439 01440 // ClrInitState(rName) 01441 void vGenerator::ClrInitState(const std::string& rName) { 01442 FD_DG("vGenerator(" << this << ")::ClrInitState(\"" << rName << "\")"); 01443 Idx index = StateIndex(rName); 01444 #ifdef FAUDES_CHECKED 01445 if (index == 0) { 01446 std::stringstream errstr; 01447 errstr << "State name \"" << rName << "\" not known in Generator"; 01448 throw Exception("vGenerator::ClrInitState(..)", errstr.str(), 90); 01449 } 01450 #endif 01451 ClrInitState(index); 01452 } 01453 01454 // ClrInitState(pos) 01455 StateSet::Iterator vGenerator::ClrInitState(StateSet::Iterator pos) { 01456 FD_DG("vGenerator(" << this << ")::ClrInitState(" << *pos << ")"); 01457 return mInitStates.Erase(pos); 01458 } 01459 01460 // ClearInitStates() 01461 void vGenerator::ClearInitStates(void) { 01462 mInitStates.Clear(); 01463 } 01464 01465 // SetMarkedState(index) 01466 void vGenerator::SetMarkedState(Idx index) { 01467 FD_DG("vGenerator(" << this << ")::SetMarkedState(" << index << ")"); 01468 #ifdef FAUDES_CHECKED 01469 if (! mpStates->Exists(index)) { 01470 std::stringstream errstr; 01471 errstr << "vGenerator::SetMarkedState: index " << index 01472 << " not in stateset"; 01473 throw Exception("vGenerator::SetMarkedState(..)", errstr.str(), 91); 01474 } 01475 #endif 01476 mMarkedStates.Insert(index); 01477 } 01478 01479 // SetMarkedState(rName) 01480 void vGenerator::SetMarkedState(const std::string& rName) { 01481 FD_DG("vGenerator(" << this << ")::SetMarkedState(\"" << rName << "\")"); 01482 Idx index = StateIndex(rName); 01483 #ifdef FAUDES_CHECKED 01484 if (index == 0) { 01485 std::stringstream errstr; 01486 errstr << "State name \"" << rName << "\" not known in Generator"; 01487 throw Exception("vGenerator::SetMarkedState(..)", errstr.str(), 90); 01488 } 01489 #endif 01490 SetMarkedState(index); 01491 } 01492 01493 // InjectMarkedStates(rNewMarkedStates) 01494 void vGenerator::InjectMarkedStates(const StateSet& rNewMarkedStates) { 01495 FD_DG("vGenerator(" << this << ")::InjectMarkedStates(" 01496 << rNewMarkedStates.ToString() << ")"); 01497 mMarkedStates = rNewMarkedStates; 01498 mMarkedStates.Name("MarkedStates"); 01499 } 01500 01501 // ClrMarkedState(index) 01502 void vGenerator::ClrMarkedState(Idx index) { 01503 FD_DG("vGenerator(" << this << ")::ClrMarkedState(" << index << ")"); 01504 #ifdef FAUDES_CHECKED 01505 if (! mpStates->Exists(index)) { 01506 std::stringstream errstr; 01507 errstr << "vGenerator::ClrMarkedState: index " << index 01508 << " not in stateset"; 01509 throw Exception("vGenerator::ClrMarkedState(..)", errstr.str(), 91); 01510 } 01511 #endif 01512 mMarkedStates.Erase(index); 01513 } 01514 01515 // ClrMarkedState(rName) 01516 void vGenerator::ClrMarkedState(const std::string& rName) { 01517 FD_DG("vGenerator(" << this << ")::ClrMarkedState(\"" << rName << "\")"); 01518 Idx index = StateIndex(rName); 01519 #ifdef FAUDES_CHECKED 01520 if (index == 0) { 01521 std::stringstream errstr; 01522 errstr << "State name \"" << rName << "\" not known in Generator"; 01523 throw Exception("vGenerator::ClrMarkedState(..)", errstr.str(), 90); 01524 } 01525 #endif 01526 ClrMarkedState(index); 01527 } 01528 01529 // ClrMarkedState(pos) 01530 StateSet::Iterator vGenerator::ClrMarkedState(StateSet::Iterator pos) { 01531 FD_DG("vGenerator(" << this << ")::ClrMarkedState(" << *pos << ")"); 01532 return mMarkedStates.Erase(pos); 01533 } 01534 01535 // ClearMarkedStates() 01536 void vGenerator::ClearMarkedStates(void) { 01537 mMarkedStates.Clear(); 01538 } 01539 01540 // InjectTransition(newtrans) 01541 void vGenerator::InjectTransition(const Transition& rTrans) { 01542 FD_DG("vGenerator::InjectTransition(" << TStr(rTrans) << ")"); 01543 mpTransRel->Insert(rTrans); 01544 } 01545 01546 // InjectTransRel(newtransrel) 01547 void vGenerator::InjectTransRel(const TransSet& rNewTransrel) { 01548 FD_DG("vGenerator::InjectTransRel(...)"); 01549 *mpTransRel=rNewTransrel; 01550 mpTransRel->Name("TransRel"); 01551 } 01552 01553 // SetTransition(rX1, rEv, rX2) 01554 bool vGenerator::SetTransition(const std::string& rX1, const std::string& rEv, const std::string& rX2) { 01555 FD_DG("vGenerator(" << this << ")::SetTransition(\"" 01556 << rX1 << "\", \"" << rEv << "\", \"" << rX2 << "\")"); 01557 Idx x1 = StateIndex(rX1); 01558 Idx x2 = StateIndex(rX2); 01559 #ifdef FAUDES_CHECKED 01560 if (x1 == 0) { 01561 FD_ERR("vGenerator::SetTransition: state " << rX1 01562 << " not in stateset"); 01563 std::stringstream errstr; 01564 errstr << "State name " << rX1 << " not found in Generator"; 01565 throw Exception("vGenerator::SetTransition(..)", errstr.str(), 90); 01566 } 01567 if (! mpAlphabet->Exists(rEv)) { 01568 FD_ERR("vGenerator::SetTransition: event " << rEv << " not in alphabet"); 01569 std::stringstream errstr; 01570 errstr << "Event name " << rEv << " not found in event domain of Generator"; 01571 throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95); 01572 } 01573 if (x2 == 0) { 01574 FD_ERR("vGenerator::SetTransition: state " << rX2 << " not in stateset"); 01575 std::stringstream errstr; 01576 errstr << "State name " << rX2 << " not found in Generator"; 01577 throw Exception("vGenerator::SetTransition(..)", errstr.str(), 90); 01578 } 01579 #endif 01580 return SetTransition(Transition(x1, EventIndex(rEv), x2)); 01581 } 01582 01583 01584 // SetTransition(x1, ev, x2) 01585 bool vGenerator::SetTransition(Idx x1, Idx ev, Idx x2) { 01586 return SetTransition(Transition(x1,ev,x2)); 01587 } 01588 01589 // SetTransition(rTransition) 01590 bool vGenerator::SetTransition(const Transition& rTransition) { 01591 FD_DG("vGenerator(" << this << ")::SetTransition(" << rTransition.X1 << "," 01592 << rTransition.Ev << "," << rTransition.X2 << ")"); 01593 #ifdef FAUDES_CHECKED 01594 if (! mpStates->Exists(rTransition.X1)) { 01595 std::stringstream errstr; 01596 errstr << "vGenerator::SetTransition: state " << SStr(rTransition.X1) 01597 << " not in stateset"; 01598 throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95); 01599 } 01600 if (! mpAlphabet->Exists(rTransition.Ev)) { 01601 std::stringstream errstr; 01602 errstr << "vGenerator::SetTransition: event " << EStr(rTransition.Ev) 01603 << " not in alphabet "; 01604 throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95); 01605 } 01606 if (! mpStates->Exists(rTransition.X2)) { 01607 std::stringstream errstr; 01608 errstr << "vGenerator::SetTransition: state " << SStr(rTransition.X2) 01609 << " not in stateset"; 01610 throw Exception("vGenerator::SetTransition(..)", errstr.str(), 95); 01611 } 01612 #endif 01613 return mpTransRel->Insert(rTransition); 01614 } 01615 01616 // ClrTransition.X1, ev, x2) 01617 void vGenerator::ClrTransition(Idx x1, Idx ev, Idx x2) { 01618 FD_DG("vGenerator(" << this << ")::ClrTransition(" 01619 << x1 << "," << ev << "," << x2 << ")"); 01620 mpTransRel->Erase(x1, ev, x2); 01621 } 01622 01623 // ClrTransition(rTransition) 01624 void vGenerator::ClrTransition(const Transition& rTransition) { 01625 FD_DG("vGenerator(" << this << ")::ClrTransition(" << TStr(rTransition) << ")"); 01626 mpTransRel->Erase(rTransition); 01627 } 01628 01629 // ClrTransition(it) 01630 TransSet::Iterator vGenerator::ClrTransition(TransSet::Iterator it) { 01631 FD_DG("vGenerator(" << this << ")::ClrTransition(" << TStr(*it)<< ")" ); 01632 return mpTransRel->Erase(it); 01633 } 01634 01635 // ClrTransitions(X1, ev) 01636 void vGenerator::ClrTransitions(Idx x1, Idx ev) { 01637 FD_DG("vGenerator(" << this << ")::ClrTransition(" 01638 << x1 << "," << ev << ")"); 01639 mpTransRel->EraseByX1Ev(x1, ev); 01640 } 01641 01642 // ClrTransitions(X1) 01643 void vGenerator::ClrTransitions(Idx x1) { 01644 FD_DG("vGenerator(" << this << ")::ClrTransition(" 01645 << x1 << ")"); 01646 mpTransRel->EraseByX1(x1); 01647 } 01648 01649 // TransAttribute(trans, attr) 01650 void vGenerator::TransAttribute(const Transition& rTrans, const Type& rAttr) { 01651 FD_DG("vGenerator(" << this << ")::TransAttribute(" 01652 << TStr(rTrans) << ",\"" << rAttr.ToString() << "\")"); 01653 mpTransRel->Attribute(rTrans, rAttr); 01654 } 01655 01656 // TransAttributep(trans) 01657 AttributeVoid* vGenerator::TransAttributep(const Transition& rTrans) { 01658 return mpTransRel->Attributep(rTrans); 01659 } 01660 01661 01662 // TransAttribute(trans) 01663 const AttributeVoid& vGenerator::TransAttribute(const Transition& rTrans) const { 01664 return mpTransRel->Attribute(rTrans); 01665 } 01666 01667 // ClrTransAttribute(trans) 01668 void vGenerator::ClrTransAttribute(const Transition& rTrans) { 01669 mpTransRel->ClrAttribute(rTrans); 01670 } 01671 01672 01673 // ClearTransRel() 01674 void vGenerator::ClearTransRel(void) { 01675 mpTransRel->Clear(); 01676 } 01677 01678 // EventAttribute(index, attr) 01679 void vGenerator::EventAttribute(Idx index, const Type& rAttr) { 01680 FD_DG("vGenerator(" << this << ")::EventAttribute(" 01681 << EStr(index) << ",\"" << rAttr.ToString() << "\")"); 01682 mpAlphabet->Attribute(index, rAttr); 01683 } 01684 01685 01686 // EventAttributes(set) 01687 void vGenerator::EventAttributes(const EventSet& rEventSet) { 01688 FD_DG("vGenerator(" << this << ")::EventAttributes(" 01689 << rEventSet.ToString() << "\")"); 01690 mpAlphabet->Attributes(rEventSet); 01691 } 01692 01693 // ClrEventAttribute(index) 01694 void vGenerator::ClrEventAttribute(Idx index) { 01695 FD_DG("vGenerator(" << this << ")::ClrEventAttribute(\"" << EStr(index) << "\")"); 01696 mpAlphabet->ClrAttribute(index); 01697 } 01698 01699 // StateAttribute(index, attr) 01700 void vGenerator::StateAttribute(Idx index, const Type& rAttr) { 01701 FD_DG("vGenerator(" << this << ")::StateAttribute(" 01702 << SStr(index) << ",\"" << rAttr.ToString() << "\")"); 01703 mpStates->Attribute(index, rAttr); 01704 } 01705 01706 // ClrStateAttribute(index) 01707 void vGenerator::ClrStateAttribute(Idx index) { 01708 FD_DG("vGenerator(" << this << ")::ClrStateAttribute(\"" << index << "\")"); 01709 mpStates->ClrAttribute(index); 01710 } 01711 01712 // ExistsEvent(index) 01713 bool vGenerator::ExistsEvent(Idx index) const { 01714 return mpAlphabet->Exists(index); 01715 } 01716 01717 // ExistsEvent(rName) 01718 bool vGenerator::ExistsEvent(const std::string& rName) const { 01719 return mpAlphabet->Exists(rName); 01720 } 01721 01722 // FindEvent(index) const 01723 EventSet::Iterator vGenerator::FindEvent(Idx index) const { 01724 return mpAlphabet->Find(index); 01725 } 01726 01727 // FindEvent(rName) 01728 EventSet::Iterator vGenerator::FindEvent(const std::string& rName) const { 01729 return mpAlphabet->Find(rName); 01730 } 01731 01732 // ExistsState(index) 01733 bool vGenerator::ExistsState(Idx index) const { 01734 return mpStates->Exists(index); 01735 } 01736 01737 // ExistsName(name) 01738 bool vGenerator::ExistsState(const std::string& rName) const { 01739 return ExistsState(StateIndex(rName)); 01740 } 01741 01742 // FindState(rName) const 01743 StateSet::Iterator vGenerator::FindState(const std::string& rName) const { 01744 return mpStates->Find(mpStateSymbolTable->Index(rName)); 01745 } 01746 01747 // FindState(index) const 01748 StateSet::Iterator vGenerator::FindState(Idx index) const { 01749 return mpStates->Find(index); 01750 } 01751 01752 // ExistsInitState(index) 01753 bool vGenerator::ExistsInitState(Idx index) const { 01754 return mInitStates.Exists(index); 01755 } 01756 01757 // FindInitState(index) 01758 StateSet::Iterator vGenerator::FindInitState(Idx index) const { 01759 return mInitStates.Find(index); 01760 } 01761 01762 // ExistsMarkedState(index) 01763 bool vGenerator::ExistsMarkedState(Idx index) const { 01764 return mMarkedStates.Exists(index); 01765 } 01766 01767 // FindMarkedState(index) 01768 StateSet::Iterator vGenerator::FindMarkedState(Idx index) const { 01769 return mMarkedStates.Find(index); 01770 } 01771 01772 // EventAttribute(index) 01773 const AttributeVoid& vGenerator::EventAttribute(Idx index) const { 01774 return mpAlphabet->Attribute(index); 01775 } 01776 01777 // EventAttributep(index) 01778 AttributeVoid* vGenerator::EventAttributep(Idx index) { 01779 return mpAlphabet->Attributep(index); 01780 } 01781 01782 // EventAttribute(rName) 01783 const AttributeVoid& vGenerator::EventAttribute(const std::string& rName) const { 01784 return EventAttribute(EventIndex(rName)); 01785 } 01786 01787 // EventAttributep(rName) 01788 AttributeVoid* vGenerator::EventAttributep(const std::string& rName) { 01789 return EventAttributep(EventIndex(rName)); 01790 } 01791 01792 // StateAttribute(index) 01793 const AttributeVoid& vGenerator::StateAttribute(Idx index) const { 01794 return mpStates->Attribute(index); 01795 } 01796 01797 // StateAttributep(index) 01798 AttributeVoid* vGenerator::StateAttributep(Idx index) { 01799 return mpStates->Attributep(index); 01800 } 01801 01802 // GlobalAttribute(attr) 01803 void vGenerator::GlobalAttribute(const Type& rAttr) { 01804 FD_DG("vGenerator(" << this << ")::GlobalAttribute(" 01805 << rAttr.ToString() << "\")"); 01806 // set to void is ok for silient ignore 01807 if(typeid(rAttr)==typeid(AttributeVoid)) return; 01808 // error: 01809 std::stringstream errstr; 01810 errstr << "cannot cast global attribute " << rAttr.ToString() << " for generator " << Name(); 01811 throw Exception("vGenerator::GlobalAttribute", errstr.str(), 63); 01812 } 01813 01814 // GlobalAttributeTry(attr) 01815 void vGenerator::GlobalAttributeTry(const Type& rAttr) { 01816 FD_DG("vGenerator(" << this << ")::GlobalAttributeTry(" 01817 << rAttr.ToString() << "\")"); 01818 // ignore 01819 } 01820 01821 // GlobalAttribute() 01822 const AttributeVoid& vGenerator::GlobalAttribute(void) const { 01823 FD_DG("vGenerator(" << this << ")::GlobalAttribute()"); 01824 return *mpGlobalAttribute; 01825 } 01826 01827 // GlobalAttributep() 01828 AttributeVoid* vGenerator::GlobalAttributep(void) { 01829 FD_DG("vGenerator(" << this << ")::GlobalAttributep()"); 01830 return mpGlobalAttribute; 01831 } 01832 01833 01834 // Alphabet() 01835 const EventSet& vGenerator::Alphabet(void) const { 01836 return *mpAlphabet; 01837 } 01838 01839 // States() 01840 const StateSet& vGenerator::States(void) const { 01841 return *mpStates; 01842 } 01843 01844 // TransRel() 01845 const TransSet& vGenerator::TransRel(void) const { 01846 return *mpTransRel; 01847 } 01848 01849 01850 // TransRel(res) 01851 void vGenerator::TransRel(TransSetX1EvX2& res) const { mpTransRel->ReSort(res); } 01852 void vGenerator::TransRel(TransSetEvX1X2& res) const { mpTransRel->ReSort(res); } 01853 void vGenerator::TransRel(TransSetEvX2X1& res) const { mpTransRel->ReSort(res); } 01854 void vGenerator::TransRel(TransSetX2EvX1& res) const { mpTransRel->ReSort(res); } 01855 void vGenerator::TransRel(TransSetX2X1Ev& res) const { mpTransRel->ReSort(res); } 01856 void vGenerator::TransRel(TransSetX1X2Ev& res) const { mpTransRel->ReSort(res); } 01857 01858 01859 Transition vGenerator::TransitionByNames( 01860 const std::string& rX1, const std::string& rEv, const std::string& rX2) const { 01861 return Transition(StateIndex(rX1),EventIndex(rEv),StateIndex(rX2)); 01862 } 01863 01864 // InitStates() 01865 const StateSet& vGenerator::InitStates(void) const { 01866 return mInitStates; 01867 } 01868 01869 // MarkedStates() 01870 const StateSet& vGenerator::MarkedStates(void) const { 01871 return mMarkedStates; 01872 } 01873 01874 // MinimizeAlphabet() 01875 void vGenerator::MinimizeAlphabet(void) { 01876 mpAlphabet->NameSet::EraseSet(UnusedEvents()); 01877 } 01878 01879 // UsedEvents() 01880 EventSet vGenerator::UsedEvents(void) const { 01881 EventSet resultset = NewEventSet(); 01882 TransSet::Iterator it; 01883 for (it = mpTransRel->Begin(); it != mpTransRel->End(); ++it) { 01884 resultset.Insert(it->Ev); 01885 } 01886 return resultset; 01887 } 01888 01889 // UnusedEvents() 01890 EventSet vGenerator::UnusedEvents(void) const { 01891 return *mpAlphabet - UsedEvents(); 01892 } 01893 01894 // ActiveEventSet(x1) 01895 EventSet vGenerator::ActiveEventSet(Idx x1) const { 01896 EventSet result = NewEventSet(); 01897 TransSet::Iterator it; 01898 for (it = TransRelBegin(x1); it != TransRelEnd(x1); ++it) { 01899 result.Insert(it->Ev); 01900 } 01901 return result; 01902 } 01903 01904 // ActiveTransSet(x1) 01905 TransSet vGenerator::ActiveTransSet(Idx x1) const { 01906 TransSet result; 01907 TransSet::Iterator it; 01908 for (it = TransRelBegin(x1); it != TransRelEnd(x1); ++it) { 01909 result.Insert(*it); 01910 } 01911 return result; 01912 } 01913 01914 // TransRelStateSpace() 01915 StateSet vGenerator::TransRelStateSpace(void) const { 01916 StateSet states; 01917 TransSet::Iterator it; 01918 for (it=mpTransRel->Begin(); it != mpTransRel->End(); ++it) { 01919 states.Insert(it->X1); 01920 states.Insert(it->X2); 01921 } 01922 return states; 01923 } 01924 01925 // TransRelStateSpace(x1) 01926 StateSet vGenerator::TransRelStateSpace(Idx x1) const { 01927 StateSet states; 01928 TransSet::Iterator it = mpTransRel->Begin(x1); 01929 TransSet::Iterator it_end = mpTransRel->End(x1); 01930 for (; it != it_end; ++it) { 01931 states.Insert(it->X2); 01932 } 01933 return states; 01934 } 01935 01936 // TransRelStateSpace(x1,ev) 01937 StateSet vGenerator::TransRelStateSpace(Idx x1, Idx ev) const { 01938 StateSet states; 01939 TransSet::Iterator it = mpTransRel->Begin(x1,ev); 01940 TransSet::Iterator it_end = mpTransRel->End(x1,ev); 01941 for (; it != it_end; ++it) { 01942 states.Insert(it->X2); 01943 } 01944 return states; 01945 } 01946 01947 01948 // idx SuccessorState() const 01949 Idx vGenerator::SuccessorState(Idx x1, Idx ev) const { 01950 TransSet::Iterator it = mpTransRel->Begin(x1,ev); 01951 TransSet::Iterator it_end = mpTransRel->End(x1,ev); 01952 if(it==it_end) return 0; 01953 Idx res=(*it).X2; 01954 #ifdef FAUDES_CHECKED 01955 it++; 01956 if(it!=it_end) { 01957 std::stringstream errstr; 01958 errstr << "successor state does not exist uniquely" << std::endl; 01959 throw Exception("vGenerator::SuccessorState", errstr.str(), 92); 01960 } 01961 #endif 01962 return res; 01963 } 01964 01965 01966 // AccessibleSet() 01967 StateSet vGenerator::AccessibleSet(void) const { 01968 // initialize todo stack 01969 std::stack<Idx> todo; 01970 StateSet::Iterator sit; 01971 for(sit = InitStatesBegin(); sit != InitStatesEnd(); ++sit) 01972 todo.push(*sit); 01973 // loop variables 01974 StateSet accessibleset; 01975 TransSet::Iterator tit; 01976 TransSet::Iterator tit_end; 01977 // loop 01978 while(!todo.empty()) { 01979 // pop 01980 Idx x1=todo.top(); 01981 todo.pop(); 01982 // sense known 01983 if(accessibleset.Exists(x1)) continue; 01984 // record 01985 accessibleset.Insert(x1); 01986 // iterate/push 01987 tit=TransRelBegin(x1); 01988 tit_end=TransRelEnd(x1); 01989 for(; tit != tit_end; ++tit) 01990 if(tit->X2 != x1) 01991 todo.push(tit->X2); 01992 } 01993 // done 01994 accessibleset.Name("AccessibleSet"); 01995 return accessibleset; 01996 } 01997 01998 // Accessible() 01999 bool vGenerator::Accessible(void) { 02000 StateSet accessibleset = AccessibleSet(); 02001 StateSet not_accessible = *mpStates - accessibleset; 02002 DelStates(not_accessible); 02003 // return true if there is an initial state 02004 if (!mInitStates.Empty()) { 02005 FD_DF("vGenerator::accessible: generator is accessible"); 02006 return true; 02007 } 02008 FD_DF("vGenerator::accessible: generator is accessible but empty"); 02009 return false; 02010 } 02011 02012 // IsAccessible() 02013 bool vGenerator::IsAccessible(void) const { 02014 if(AccessibleSet() == *mpStates) { 02015 FD_DF("vGenerator::accessible: generator is accessible"); 02016 return true; 02017 } 02018 FD_DF("vGenerator::accessible: generator is not accessible"); 02019 return false; 02020 } 02021 02022 // CoaccessibleSet() 02023 StateSet vGenerator::CoaccessibleSet(void) const { 02024 // build reverse transition relation 02025 TransSetX2EvX1 rtrel; 02026 TransRel(rtrel); 02027 // initialize todo stack 02028 StateSet::Iterator sit; 02029 std::stack<Idx> todo; 02030 for(sit = MarkedStatesBegin(); sit != MarkedStatesEnd(); ++sit) 02031 todo.push(*sit); 02032 // loop variables 02033 StateSet coaccessibleset; 02034 TransSetX2EvX1::Iterator tit; 02035 TransSetX2EvX1::Iterator tit_end; 02036 // loop 02037 while(!todo.empty()) { 02038 // pop 02039 Idx x2=todo.top(); 02040 todo.pop(); 02041 // sense known 02042 if(coaccessibleset.Exists(x2)) continue; 02043 // record 02044 coaccessibleset.Insert(x2); 02045 // iterate/push 02046 tit=rtrel.BeginByX2(x2); 02047 tit_end=rtrel.EndByX2(x2); 02048 for(; tit != tit_end; ++tit) 02049 if(tit->X1 != x2) 02050 todo.push(tit->X1); 02051 } 02052 // done 02053 coaccessibleset.Name("CoaccessibleSet"); 02054 return coaccessibleset; 02055 } 02056 02057 // Coaccessible() 02058 bool vGenerator::Coaccessible(void) { 02059 StateSet coaccessibleset = CoaccessibleSet(); 02060 StateSet not_coaccessible = *mpStates - coaccessibleset; 02061 DelStates(not_coaccessible); 02062 // return true if there is a marked state 02063 if (! mMarkedStates.Empty()) { 02064 FD_DF("vGenerator::coaccessible: generator is coaccessible"); 02065 return true; 02066 } 02067 FD_DF("vGenerator::coaccessible: generator is not coaccessible"); 02068 return false; 02069 } 02070 02071 // IsCoaccessible() 02072 bool vGenerator::IsCoaccessible(void) const { 02073 if(CoaccessibleSet() == *mpStates) { 02074 FD_DF("vGenerator::coaccessible: generator is coaccessible"); 02075 return true; 02076 } 02077 FD_DF("vGenerator::coaccessible: generator is not coaccessible"); 02078 return false; 02079 } 02080 02081 // TrimSet() 02082 StateSet vGenerator::TrimSet(void) const { 02083 FD_DF("vGenerator::trimset: trim states: " 02084 << StateSet(AccessibleSet() * CoaccessibleSet()).ToString()); 02085 StateSet res=AccessibleSet() * CoaccessibleSet(); 02086 res.Name("TrimSet"); 02087 return res; 02088 } 02089 02090 // Trim() 02091 bool vGenerator::Trim(void) { 02092 FD_DF("vGenerator::trim: generator states: " << mpStates->ToString()); 02093 // better: compute sets and do one state delete 02094 bool accessiblebool = Accessible(); 02095 bool coaccessiblebool = Coaccessible(); 02096 FD_DF("vGenerator::trim: trim states: " << mpStates->ToString()); 02097 if(accessiblebool && coaccessiblebool) { 02098 FD_DF("vGenerator::Trim(): generator is nontrivial"); 02099 return true; 02100 } 02101 FD_DF("vGenerator::Trim(): generator is trivial"); 02102 return false; 02103 } 02104 02105 02106 // IsTrim() 02107 bool vGenerator::IsTrim(void) const { 02108 bool res=true; 02109 if(!IsAccessible()) res=false; 02110 else if(!IsCoaccessible()) res=false; 02111 FD_DF("vGenerator::IsTrim(): result " << res); 02112 return res; 02113 } 02114 02115 02116 // BlockingStates() 02117 StateSet vGenerator::BlockingStates(void) const { 02118 FD_DF("vGenerator::BlockingSet: blocking states: " 02119 << StateSet(AccessibleSet() - CoaccessibleSet()).ToString()); 02120 return AccessibleSet() - CoaccessibleSet(); 02121 } 02122 02123 02124 02125 // IsComplete 02126 bool vGenerator::IsComplete(const StateSet& rStates) const { 02127 FD_DG("IsComplete(" << Name() << ")"); 02128 02129 // loop over provided states 02130 StateSet::Iterator sit=rStates.Begin(); 02131 StateSet::Iterator sit_end=rStates.End(); 02132 for(;sit!=sit_end;sit++){ 02133 TransSet::Iterator tit=TransRelBegin(*sit); 02134 TransSet::Iterator tit_end=TransRelEnd(*sit); 02135 if(tit==tit_end) break; 02136 } 02137 // return true if no terminal state has been found 02138 return sit==sit_end; 02139 } 02140 02141 // IsComplete 02142 bool vGenerator::IsComplete(void) const { 02143 return IsComplete(States()); 02144 } 02145 02146 // Complete 02147 bool vGenerator::Complete(void) { 02148 // states to remove 02149 StateSet termset = TerminalStates(); 02150 // iterative search ... 02151 bool done; 02152 do { 02153 // ... over all states 02154 StateSet::Iterator sit = States().Begin(); 02155 StateSet::Iterator sit_end = States().End(); 02156 done=true; 02157 for(; sit!=sit_end; ++sit) { 02158 if(termset.Exists(*sit)) continue; 02159 TransSet::Iterator tit = TransRelBegin(*sit); 02160 TransSet::Iterator tit_end = TransRelEnd(*sit); 02161 for (; tit != tit_end; ++tit) { 02162 if(!termset.Exists(tit->X2)) break; 02163 } 02164 if(tit==tit_end) { 02165 termset.Insert(*sit); 02166 done=false; 02167 } 02168 } 02169 } while(!done); 02170 // remove those states 02171 DelStates(termset); 02172 // done 02173 return !InitStates().Empty(); 02174 } 02175 02176 02177 // TerminalStates() 02178 StateSet vGenerator::TerminalStates(const StateSet& rStates) const { 02179 FD_DG("Generator::TerminalStates(" << Name() << ")"); 02180 02181 // prepare result 02182 StateSet res; 02183 02184 // loop states 02185 StateSet::Iterator sit=rStates.Begin(); 02186 StateSet::Iterator sit_end=rStates.End(); 02187 for(;sit!=sit_end;sit++){ 02188 TransSet::Iterator tit=TransRelBegin(*sit); 02189 TransSet::Iterator tit_end=TransRelEnd(*sit); 02190 if(tit==tit_end) res.Insert(*sit); 02191 } 02192 // return terminal states 02193 res.Name("TerminalStates"); 02194 return res; 02195 } 02196 02197 // TerminalStates() 02198 StateSet vGenerator::TerminalStates(void) const { 02199 return TerminalStates(States()); 02200 } 02201 02202 02203 // OmegaTrim 02204 bool vGenerator::OmegaTrim(void) { 02205 02206 // note: this really is inefficient; at least we should 02207 // record the inverse transition relation for the coaccessile 02208 // iteration 02209 02210 // first we make the generator accessible 02211 Accessible(); 02212 // iterate coaccessible and complete until convergence in oserved 02213 while(1) { 02214 Idx osize=States().Size(); 02215 Coaccessible(); 02216 Complete(); 02217 if(States().Size()==osize) break; 02218 } 02219 // done 02220 return !InitStates().Empty() && !MarkedStates().Empty(); 02221 } 02222 02223 02224 // IsOmegaTrim() 02225 bool vGenerator::IsOmegaTrim(void) const { 02226 bool res=true; 02227 if(!IsAccessible()) res=false; 02228 else if(!IsCoaccessible()) res=false; 02229 else if(!IsComplete()) res=false; 02230 FD_DF("vGenerator::IsOmegaTrim(): result " << res); 02231 return res; 02232 } 02233 02234 02235 02236 // IsDeterministic() 02237 bool vGenerator::IsDeterministic(void) const { 02238 // if there is more than one initial state ... nondet 02239 if (InitStatesSize() > 1) { 02240 FD_DG("vGenerator::IsDeterministic: more than one initial state"); 02241 return false; 02242 } 02243 // if there is a state/event pair with non-unique successor ... nondet 02244 if (TransRelSize() < 2) return true; 02245 TransSet::Iterator it1; 02246 TransSet::Iterator it2; 02247 for (it1 = TransRelBegin(), it2 = it1++; it1 != TransRelEnd(); it2 = it1++) { 02248 if ((it1->X1 == it2->X1) && (it1->Ev == it2->Ev)) { 02249 FD_DG("IsDeterministic(): at least one state " 02250 << "contains more than on transition with same event: " 02251 << TStr(*it1)); 02252 return false; 02253 } 02254 } 02255 // in all other cases generator is deterministic 02256 return true; 02257 } 02258 02259 02260 // ReindexOnWrite() 02261 bool vGenerator::ReindexOnWrite(void) const { 02262 return mReindexOnWrite; 02263 } 02264 02265 // ReindexOnWrite(flag) 02266 void vGenerator::ReindexOnWrite(bool flag) { 02267 mReindexOnWrite = flag; 02268 } 02269 02270 // ReindexOnWrite(flag) 02271 void vGenerator::ReindexOnWriteDefault(bool flag) { 02272 msReindexOnWriteDefault = flag; 02273 } 02274 02275 // ReindexOnWrite(flag) 02276 bool vGenerator::ReindexOnWriteDefault(void) { 02277 return msReindexOnWriteDefault; 02278 } 02279 02280 02281 02282 // DoWrite() 02283 void vGenerator::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 02284 (void) pContext; 02285 // pre 2.20 behaviour: re-index on file output 02286 /* 02287 if(rTw.FileMode()) 02288 SetMinStateIndexMap(); 02289 */ 02290 // post 2.20 beaviour: re-index by configuration 02291 if(ReindexOnWrite()) 02292 SetMinStateIndexMap(); 02293 // figure section 02294 std::string label=rLabel; 02295 if(label=="") label="Generator"; 02296 FD_DG("vGenerator(" << this << ")::DoWrite(): section " << label); 02297 // write generator 02298 rTw.WriteBegin(label); 02299 rTw << mMyName; 02300 rTw << "\n"; 02301 rTw << "\n"; 02302 SWrite(rTw); 02303 rTw << "\n"; 02304 mpAlphabet->Write(rTw); 02305 rTw << "\n"; 02306 WriteStates(rTw); 02307 rTw << "\n"; 02308 WriteTransRel(rTw); 02309 rTw << "\n"; 02310 WriteStateSet(rTw, mInitStates); 02311 rTw << "\n"; 02312 WriteStateSet(rTw, mMarkedStates); 02313 rTw << "\n"; 02314 mpGlobalAttribute->Write(rTw); 02315 rTw << "\n"; 02316 rTw.WriteEnd(label); 02317 // end of reindex 02318 ClearMinStateIndexMap(); 02319 } 02320 02321 // DoDWrite() 02322 void vGenerator::DoDWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 02323 (void) pContext; 02324 // figure section 02325 std::string label=rLabel; 02326 if(label=="") label="Generator"; 02327 FD_DG("vGenerator(" << this << ")::DoDWrite(): section " << label); 02328 // write generator 02329 rTw.WriteBegin(label); 02330 rTw << mMyName; 02331 rTw << "\n"; 02332 rTw << "\n"; 02333 SWrite(rTw); 02334 rTw << "\n"; 02335 mpAlphabet->DWrite(rTw); 02336 rTw << "\n"; 02337 DWriteStateSet(rTw, *mpStates); 02338 rTw << "\n"; 02339 DWriteTransRel(rTw); 02340 rTw << "\n"; 02341 DWriteStateSet(rTw, mInitStates); 02342 rTw << "\n"; 02343 DWriteStateSet(rTw, mMarkedStates); 02344 rTw << "\n"; 02345 mpGlobalAttribute->Write(rTw); 02346 rTw << "\n"; 02347 rTw.WriteEnd(label); 02348 rTw << "\n"; 02349 } 02350 02351 // DoXWrite() 02352 void vGenerator::DoXWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 02353 (void) pContext; 02354 // Set up outer tag 02355 std::string label=rLabel; 02356 std::string ftype=TypeName(); 02357 if(label=="") label="Generator"; 02358 Token btag; 02359 btag.SetBegin(label); 02360 if(Name()!=label && Name()!="") btag.InsAttributeString("name",Name()); 02361 if(ftype!=label && ftype!="") btag.InsAttributeString("ftype",ftype); 02362 FD_DG("vGenerator(" << this << ")::DoXWrite(..): section " << btag.StringValue() << " #" << Size()); 02363 rTw.Write(btag); 02364 // Optional re-indexing 02365 if(mReindexOnWrite) SetMinStateIndexMap(); 02366 // Write comcponents 02367 rTw << "\n"; 02368 mpAlphabet->XWrite(rTw,"Alphabet"); 02369 rTw << "\n"; 02370 XWriteStateSet(rTw, *mpStates,"StateSet"); 02371 rTw << "\n"; 02372 XWriteTransRel(rTw); 02373 rTw << "\n"; 02374 mpGlobalAttribute->XWrite(rTw); 02375 if(!mpGlobalAttribute->IsDefault()) 02376 rTw << "\n"; 02377 // Write end 02378 rTw.WriteEnd(btag.StringValue()); 02379 // End of re-index 02380 ClearMinStateIndexMap(); 02381 } 02382 02383 // WriteAlphabet() 02384 void vGenerator::WriteAlphabet(void) const { 02385 TokenWriter tw(TokenWriter::Stdout); 02386 WriteAlphabet(tw); 02387 } 02388 02389 // AlphabetToString() 02390 std::string vGenerator::AlphabetToString(void) const { 02391 TokenWriter tw(TokenWriter::String); 02392 WriteAlphabet(tw); 02393 return tw.Str(); 02394 } 02395 02396 // WriteAlphabet(rTw&) 02397 void vGenerator::WriteAlphabet(TokenWriter& rTw) const { 02398 mpAlphabet->Write(rTw); 02399 } 02400 02401 // WriteStateSet(rStateSet&) 02402 void vGenerator::WriteStateSet(const StateSet& rStateSet) const { 02403 TokenWriter tw(TokenWriter::Stdout); 02404 WriteStateSet(tw,rStateSet); 02405 } 02406 02407 // StateSetToString() 02408 std::string vGenerator::StateSetToString(const StateSet& rStateSet) const { 02409 TokenWriter tw(TokenWriter::String); 02410 WriteStateSet(tw,rStateSet); 02411 return tw.Str(); 02412 } 02413 02414 // StateSetToText() 02415 std::string vGenerator::StateSetToText(const StateSet& rStateSet) const { 02416 TokenWriter tw(TokenWriter::String); 02417 tw.Endl(true); 02418 WriteStateSet(tw,rStateSet); 02419 return tw.Str(); 02420 } 02421 02422 02423 // WriteStateSet(rTw&, rStateSet&) 02424 void vGenerator::WriteStates(TokenWriter& rTw) const { 02425 // have my section 02426 rTw.WriteBegin("States"); 02427 // test whether we reindex 02428 bool reindex=mMinStateIndexMap.size()>0; 02429 // if we reindex, setup reverse map to write in strategic order 02430 // to allow for consisten read (i.e. states with symbolic name first, starting 02431 // with index 1); this is the plain faudes file format from 2005 02432 if(reindex) { 02433 // reverse map 02434 std::map<Idx,Idx> reversemap; 02435 std::map<Idx,Idx>::const_iterator minit; 02436 StateSet::Iterator sit; 02437 for (sit = StatesBegin(); sit != StatesEnd(); ++sit) 02438 reversemap[MinStateIndex(*sit)] = *sit; 02439 // iterate states to write 02440 for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) { 02441 // identify anonymous block (consecutive state indices) 02442 std::map<Idx,Idx>::const_iterator conit=minit; 02443 Idx start = conit->first; 02444 Idx anoncount = 0; 02445 for(; conit != reversemap.end(); ++conit) { 02446 if(StateName(conit->second) != "") break; 02447 if(!StateAttribute(conit->second).IsDefault()) break; 02448 if(conit->first != start+anoncount) break; 02449 ++anoncount; 02450 } 02451 // write anonymous block 02452 if(anoncount > FD_CONSECUTIVE) { 02453 rTw.WriteBegin("Consecutive"); 02454 rTw << start; 02455 rTw << start+anoncount-1; 02456 rTw.WriteEnd("Consecutive"); 02457 minit=conit; 02458 } 02459 // break loop 02460 if(minit == reversemap.end()) break; 02461 // write non anonymous state name/idx 02462 std::string statename = StateName(minit->second); 02463 if (statename != "") rTw << statename; 02464 else rTw << minit->first; 02465 // write state attribute 02466 const AttributeVoid& attr=StateAttribute(minit->second); 02467 attr.Write(rTw); 02468 } 02469 } 02470 // if we dont reindex, write symbolic names with index suffix to 02471 // enable a consistent read; this was introduced with libfaudes 2.20j 02472 if(!reindex) { 02473 // iterate states to write 02474 bool symexpl = (States().MaxIndex() != States().Size()); 02475 StateSet::Iterator sit; 02476 for(sit = StatesBegin(); sit != StatesEnd(); ++sit) { 02477 // identify anonymous block (consecutive state indices) 02478 StateSet::Iterator conit=sit; 02479 Idx start = *conit; 02480 Idx anoncount = 0; 02481 for(; conit != StatesEnd(); ++conit) { 02482 if(StateName(*conit) != "") break; 02483 if(!StateAttribute(*conit).IsDefault()) break; 02484 if(*conit != start+anoncount) break; 02485 ++anoncount; 02486 } 02487 // write anonymous block 02488 if(anoncount > FD_CONSECUTIVE) { 02489 rTw.WriteBegin("Consecutive"); 02490 rTw << start; 02491 rTw << start+anoncount-1; 02492 rTw.WriteEnd("Consecutive"); 02493 sit=conit; 02494 } 02495 // break loop 02496 if(sit == StatesEnd()) break; 02497 // write index or name with index suffix 02498 std::string statename = StateName(*sit); 02499 if((statename != "") && symexpl) { 02500 rTw << (statename + "#"+ToStringInteger(*sit)) ; 02501 } else if(statename != "") { 02502 rTw << statename; 02503 } else { 02504 rTw << *sit; 02505 } 02506 // write attribute 02507 const AttributeVoid& attr=StateAttribute(*sit); 02508 attr.Write(rTw); 02509 } 02510 } 02511 // write end tag 02512 rTw.WriteEnd("States"); 02513 } 02514 02515 02516 // WriteStateSet(rTw&, rStateSet&) 02517 void vGenerator::WriteStateSet(TokenWriter& rTw, const StateSet& rStateSet) const { 02518 rTw.WriteBegin(rStateSet.Name()); 02519 // test whether we reindex 02520 bool reindex=mMinStateIndexMap.size()>0; 02521 // if we reindex, setup reverse map to write in strategic order; 02522 // reading back is no issue for external states, however, we would like 02523 // to provoke large consecutive blocks as a benefit from re-indexing 02524 if(reindex) { 02525 // reverse map 02526 std::map<Idx,Idx> reversemap; 02527 std::map<Idx,Idx>::const_iterator minit; 02528 StateSet::Iterator sit; 02529 for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) 02530 reversemap[MinStateIndex(*sit)] = *sit; 02531 // iterate states to write 02532 for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) { 02533 // identify anonymous block (consecutive state indices) 02534 std::map<Idx,Idx>::const_iterator conit=minit; 02535 Idx start = conit->first; 02536 Idx anoncount = 0; 02537 for(; conit != reversemap.end(); ++conit) { 02538 if(StateName(conit->second) != "") break; 02539 if(!StateAttribute(conit->second).IsDefault()) break; 02540 if(conit->first != start+anoncount) break; 02541 ++anoncount; 02542 } 02543 // write anonymous block 02544 if(anoncount > FD_CONSECUTIVE) { 02545 rTw.WriteBegin("Consecutive"); 02546 rTw << start; 02547 rTw << start+anoncount-1; 02548 rTw.WriteEnd("Consecutive"); 02549 minit=conit; 02550 } 02551 // break loop 02552 if(minit == reversemap.end()) break; 02553 // write non anonymous state name/idx 02554 std::string statename = StateName(minit->second); 02555 if (statename != "") rTw << statename; 02556 else rTw << minit->first; 02557 // write state attribute 02558 const AttributeVoid& attr=rStateSet.Attribute(minit->second); 02559 attr.Write(rTw); 02560 } 02561 } 02562 // if we dont reindex, we dont need the reverse map; note that 02563 // external stateset will never have an explicit symbol table 02564 if(!reindex) { 02565 // iterate states to write 02566 StateSet::Iterator sit; 02567 for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) { 02568 // identify anonymous block (consecutive state indices) 02569 StateSet::Iterator conit=sit; 02570 Idx start = *conit; 02571 Idx anoncount = 0; 02572 for(; conit != rStateSet.End(); ++conit) { 02573 if(StateName(*conit) != "") break; 02574 if(!StateAttribute(*conit).IsDefault()) break; 02575 if(*conit != start+anoncount) break; 02576 ++anoncount; 02577 } 02578 // write anonymous block 02579 if(anoncount > FD_CONSECUTIVE) { 02580 rTw.WriteBegin("Consecutive"); 02581 rTw << start; 02582 rTw << start+anoncount-1; 02583 rTw.WriteEnd("Consecutive"); 02584 sit=conit; 02585 } 02586 // break loop 02587 if(sit == rStateSet.End()) break; 02588 // write non anonymous state name/idx 02589 std::string statename = StateName(*sit); 02590 if (statename != "") rTw << statename; 02591 else rTw << *sit; 02592 // write attribute 02593 const AttributeVoid& attr=rStateSet.Attribute(*sit); 02594 attr.Write(rTw); 02595 } 02596 } 02597 // write end tag 02598 rTw.WriteEnd(rStateSet.Name()); 02599 } 02600 02601 02602 // DWriteStateSet(rTw&, rStateSet&) 02603 void vGenerator::DWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet) const { 02604 rTw.WriteBegin(rStateSet.Name()); 02605 StateSet::Iterator sit; 02606 for(sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) { 02607 rTw << SStr(*sit); 02608 const AttributeVoid& attr=rStateSet.Attribute(*sit); 02609 attr.Write(rTw); 02610 } 02611 rTw.WriteEnd(rStateSet.Name()); 02612 } 02613 02614 02615 // XWriteStateSet(rTw&, rStateSet&) 02616 void vGenerator::XWriteStateSet(TokenWriter& rTw, const StateSet& rStateSet, const std::string& rLabel) const { 02617 // figure label 02618 std::string label=rLabel; 02619 if(label=="") label=rStateSet.Name(); 02620 if(label=="") label="StateSet"; 02621 rTw.WriteBegin(label); 02622 // build reverse index map of states to write ( fileidx->idx ) 02623 // -- this ensures named states to be written first; see SetMinStateIndexMap() 02624 // -- this is required to figure consecutive blocks 02625 std::map<Idx,Idx> reversemap; 02626 std::map<Idx,Idx>::const_iterator minit; 02627 StateSet::Iterator sit; 02628 for (sit = rStateSet.Begin(); sit != rStateSet.End(); ++sit) { 02629 reversemap[MinStateIndex(*sit)] = *sit; 02630 } 02631 // iterate states to write 02632 for(minit = reversemap.begin(); minit != reversemap.end(); ++minit) { 02633 // identify anonymous block (consecutive state indices, no names, no attributes) 02634 std::map<Idx,Idx>::const_iterator conit=minit; 02635 Idx start = conit->first; 02636 Idx anoncount = 0; 02637 for(; conit != reversemap.end(); ++conit) { 02638 if(StateName(conit->second) != "") break; 02639 if(!StateAttribute(conit->second).IsDefault()) break; 02640 if(ExistsInitState(conit->second)) break; 02641 if(ExistsMarkedState(conit->second)) break; 02642 if(conit->first != start+anoncount) break; 02643 ++anoncount; 02644 } 02645 // write anonymous block 02646 if(anoncount > FD_CONSECUTIVE) { 02647 Token contag; 02648 contag.SetEmpty("Consecutive"); 02649 contag.InsAttributeInteger("from",start); 02650 contag.InsAttributeInteger("to",start+anoncount-1); 02651 rTw.Write(contag); 02652 minit=conit; 02653 } 02654 // break loop 02655 if(minit == reversemap.end() ) 02656 break; 02657 // prepare state token 02658 Token sttag; 02659 std::string statename = StateName(minit->second); 02660 Idx index=minit->first; 02661 sttag.SetBegin("State"); 02662 sttag.InsAttributeInteger("id",index); 02663 if(statename!="") 02664 if(&rStateSet==mpStates) 02665 sttag.InsAttributeString("name",statename); 02666 rTw.Write(sttag); 02667 // marking 02668 if(ExistsInitState(minit->second)) { sttag.SetEmpty("Initial"); rTw.Write(sttag);}; 02669 if(ExistsMarkedState(minit->second)) { sttag.SetEmpty("Marked"); rTw.Write(sttag);}; 02670 // attribute 02671 const AttributeVoid& attr=rStateSet.Attribute(minit->second); 02672 if(!attr.IsDefault()) attr.XWrite(rTw); 02673 // done 02674 rTw.WriteEnd("State"); 02675 } 02676 rTw.WriteEnd(label); 02677 } 02678 02679 02680 // StatesToString() 02681 std::string vGenerator::StatesToString(void) const { 02682 return StateSetToString(*mpStates); 02683 } 02684 02685 // StatesToText() 02686 std::string vGenerator::StatesToText(void) const { 02687 return StateSetToText(*mpStates); 02688 } 02689 02690 // MarkedStatesToString() 02691 std::string vGenerator::MarkedStatesToString(void) const { 02692 return StateSetToString(mMarkedStates); 02693 } 02694 02695 // InitStatesToString() 02696 std::string vGenerator::InitStatesToString(void) const { 02697 return StateSetToString(mInitStates); 02698 } 02699 02700 02701 // WriteTransRel() 02702 void vGenerator::WriteTransRel(void) const { 02703 TokenWriter tw(TokenWriter::Stdout); 02704 WriteTransRel(tw); 02705 } 02706 02707 // TransRelToString() 02708 std::string vGenerator::TransRelToString(void) const { 02709 TokenWriter tw(TokenWriter::String); 02710 WriteTransRel(tw); 02711 return tw.Str(); 02712 } 02713 02714 // TransRelToText() 02715 std::string vGenerator::TransRelToText(void) const { 02716 TokenWriter tw(TokenWriter::String); 02717 tw.Endl(true); 02718 WriteTransRel(tw); 02719 return tw.Str(); 02720 } 02721 02722 // WriteTransRel(rTw&) 02723 void vGenerator::WriteTransRel(TokenWriter& rTw) const { 02724 TransSet::Iterator tit; 02725 int oldcolumns = rTw.Columns(); 02726 rTw.Columns(3); 02727 rTw.WriteBegin("TransRel"); 02728 bool smalltransrel = (Size() < FD_SMALLTRANSREL); 02729 02730 // loop all transitions 02731 for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) { 02732 02733 // write x1 02734 Idx x1=MinStateIndex(tit->X1); 02735 if (smalltransrel) { 02736 std::string x1name = StateName(tit->X1); 02737 if (x1name != "") { 02738 rTw << x1name; 02739 } else { 02740 rTw << x1; 02741 } 02742 } else { 02743 rTw << x1; 02744 } 02745 02746 // write ev 02747 rTw << EventName(tit->Ev); 02748 02749 // write x2 02750 Idx x2=MinStateIndex(tit->X2); 02751 if (smalltransrel) { 02752 std::string x2name = StateName(tit->X2); 02753 if (x2name != "") { 02754 rTw << x2name; 02755 } else { 02756 rTw << x2; 02757 } 02758 } else { 02759 rTw << x2; 02760 } 02761 02762 // write attributes 02763 TransAttribute(*tit).Write(rTw); 02764 02765 } 02766 rTw.WriteEnd("TransRel"); 02767 rTw.Columns(oldcolumns); 02768 } 02769 02770 // DWriteTransRel(rTw&) 02771 void vGenerator::DWriteTransRel(TokenWriter& rTw) const { 02772 TransSet::Iterator tit; 02773 int oldcolumns = rTw.Columns(); 02774 rTw.Columns(3); 02775 rTw.WriteBegin("TransRel"); 02776 // iterate all transitions 02777 for (tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) { 02778 // write x1 02779 std::ostringstream ox1; 02780 Idx x1= tit->X1; 02781 std::string x1name = StateName(x1); 02782 if (x1name != "") { 02783 ox1 << x1name << "[" << x1 << "]"; 02784 } else { 02785 ox1 << x1; 02786 } 02787 rTw << ox1.str(); 02788 // write ev 02789 std::ostringstream oev; 02790 Idx ev= tit->Ev; 02791 std::string evname = EventName(ev); 02792 oev << evname << "[" << ev << "]"; 02793 rTw << oev.str(); 02794 // write x2 02795 std::ostringstream ox2; 02796 Idx x2= tit->X2; 02797 std::string x2name = StateName(x2); 02798 if (x2name != "") { 02799 ox2 << x2name << "[" << x2 << "]"; 02800 } else { 02801 ox2 << x2; 02802 } 02803 rTw << ox2.str(); 02804 // attribute 02805 mpTransRel->Attribute(*tit).Write(rTw); 02806 } 02807 rTw.WriteEnd("TransRel"); 02808 rTw.Columns(oldcolumns); 02809 } 02810 02811 02812 // XWriteTransRel(rTw&) 02813 void vGenerator::XWriteTransRel(TokenWriter& rTw) const { 02814 TransSet::Iterator tit; 02815 rTw.WriteBegin("TransitionRelation"); 02816 02817 // loop all transitions 02818 for(tit = mpTransRel->Begin(); tit != mpTransRel->End(); ++tit) { 02819 02820 // retrieve values x1 02821 Idx x1=MinStateIndex(tit->X1); 02822 Idx x2=MinStateIndex(tit->X2); 02823 std::string ev=EventName(tit->Ev); 02824 02825 // prepare tag 02826 Token trtag; 02827 trtag.SetEmpty("Transition"); 02828 trtag.InsAttributeInteger("x1",x1); 02829 trtag.InsAttributeString("event",ev); 02830 trtag.InsAttributeInteger("x2",x2); 02831 02832 // consider attribute 02833 const AttributeVoid& attr=TransAttribute(*tit); 02834 // case a: indeed no attribute value 02835 if(attr.IsDefault()) { 02836 rTw.Write(trtag); 02837 } 02838 // calse b: with attribute 02839 else { 02840 trtag.ClrEnd(); 02841 rTw.Write(trtag); 02842 attr.XWrite(rTw); 02843 rTw.WriteEnd(trtag.StringValue()); 02844 } 02845 02846 } 02847 rTw.WriteEnd("TransitionRelation"); 02848 } 02849 02850 // DoSWrite(rTw&) 02851 void vGenerator::DoSWrite(TokenWriter& rTw) const 02852 { 02853 Type::DoSWrite(rTw); 02854 rTw.WriteComment(" States: " + ToStringInteger(Size()) ); 02855 rTw.WriteComment(" Init/Marked: " + ToStringInteger(mInitStates.Size()) 02856 + "/" + ToStringInteger(mMarkedStates.Size())); 02857 rTw.WriteComment(" Events: " + ToStringInteger(mpAlphabet->Size()) ); 02858 rTw.WriteComment(" Transitions: " + ToStringInteger(mpTransRel->Size()) ); 02859 rTw.WriteComment(" StateSymbols: " + ToStringInteger(mpStateSymbolTable->Size()) ); 02860 rTw.WriteComment(" Attrib. E/S/T: " + ToStringInteger(mpAlphabet->AttributesSize()) 02861 + "/" + ToStringInteger(mpStates->AttributesSize()) 02862 + "/" + ToStringInteger(mpTransRel->AttributesSize()) ); 02863 rTw.WriteComment(""); 02864 } 02865 02866 // DotWrite(rFileName) 02867 void vGenerator::DotWrite(const std::string& rFileName) const { 02868 FD_DG("vGenerator(" << this << ")::DotWrite(" << rFileName << ")"); 02869 SetMinStateIndexMap(); 02870 StateSet::Iterator lit; 02871 TransSet::Iterator tit; 02872 try { 02873 std::ofstream stream; 02874 stream.exceptions(std::ios::badbit|std::ios::failbit); 02875 stream.open(rFileName.c_str()); 02876 stream << "// dot output generated by libFAUDES vGenerator" << std::endl; 02877 stream << "digraph \"" << Name() << "\" {" << std::endl; 02878 stream << " rankdir=LR" << std::endl; 02879 stream << " node [shape=circle];" << std::endl; 02880 stream << std::endl; 02881 stream << " // initial states" << std::endl; 02882 int i = 1; 02883 for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) { 02884 std::string xname= StateName(*lit); 02885 if(xname=="") xname=ToStringInteger(MinStateIndex(*lit)); 02886 stream << " dot_dummyinit_" << i << " [shape=none, label=\"\", width=\"0.0\", height=\"0.0\" ];" << std::endl; 02887 stream << " dot_dummyinit_" << i << " -> \"" << xname << "\";" << std::endl; 02888 i++; 02889 } 02890 stream << std::endl; 02891 stream << " // mstates" << std::endl; 02892 for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) { 02893 std::string xname= StateName(*lit); 02894 if(xname=="") xname=ToStringInteger(MinStateIndex(*lit)); 02895 stream << " \"" << xname << "\" [shape=doublecircle];" << std::endl; 02896 } 02897 stream << std::endl; 02898 stream << " // rest of stateset" << std::endl; 02899 for (lit = StatesBegin(); lit != StatesEnd(); ++lit) { 02900 if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) { 02901 std::string xname= StateName(*lit); 02902 if(xname=="") xname=ToStringInteger(MinStateIndex(*lit)); 02903 stream << " \"" << xname << "\";" << std::endl; 02904 } 02905 } 02906 stream << std::endl; 02907 stream << " // transition relation" << std::endl; 02908 for(tit = TransRelBegin(); tit != TransRelEnd(); ++tit) { 02909 std::string x1name= StateName(tit->X1); 02910 if(x1name=="") x1name=ToStringInteger(MinStateIndex(tit->X1)); 02911 std::string x2name= StateName(tit->X2); 02912 if(x2name=="") x2name=ToStringInteger(MinStateIndex(tit->X2)); 02913 stream << " \"" << x1name << "\" -> \"" << x2name 02914 << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl; 02915 } 02916 stream << "};" << std::endl; 02917 stream.close(); 02918 } 02919 catch (std::ios::failure&) { 02920 throw Exception("vGenerator::DotWrite", 02921 "Exception opening/writing dotfile \""+rFileName+"\"", 2); 02922 } 02923 ClearMinStateIndexMap(); 02924 } 02925 02926 // DDotWrite(rFileName) 02927 void vGenerator::DDotWrite(const std::string& rFileName) const { 02928 FD_DG("vGenerator(" << this << ")::DDotWrite(" << rFileName << ")"); 02929 StateSet::Iterator lit; 02930 TransSet::Iterator tit; 02931 try { 02932 std::ofstream stream; 02933 stream.exceptions(std::ios::badbit|std::ios::failbit); 02934 stream.open(rFileName.c_str()); 02935 stream << "digraph \"" << Name() << "\" {" << std::endl; 02936 stream << " rankdir=LR" << std::endl; 02937 stream << " node [shape=circle];" << std::endl; 02938 stream << std::endl; 02939 stream << " // istates" << std::endl; 02940 int i = 1; 02941 for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) { 02942 stream << " dot_dummyinit_" << i << " [shape=none, label=\"\" ];" << std::endl; 02943 stream << " dot_dummyinit_" << i << " -> \"" 02944 << SStr(*lit) << "\";" << std::endl; 02945 i++; 02946 } 02947 stream << std::endl; 02948 stream << " // mstates" << std::endl; 02949 for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) { 02950 stream << " \"" << SStr(*lit) << "\" [shape=doublecircle];" << std::endl; 02951 } 02952 stream << std::endl; 02953 stream << " // rest of stateset" << std::endl; 02954 for (lit = StatesBegin(); lit != StatesEnd(); ++lit) { 02955 // if not in mInitStates or mMarkedStates 02956 if (! (ExistsInitState(*lit) || ExistsMarkedState(*lit)) ) { 02957 stream << " \"" << SStr(*lit) << "\";" << std::endl; 02958 } 02959 } 02960 stream << std::endl; 02961 stream << " // transition relation" << std::endl; 02962 for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) { 02963 stream << " \"" << SStr(tit->X1) 02964 << "\" -> \"" << SStr(tit->X2) 02965 << "\" [label=\"" << EventName(tit->Ev) << "\"];" << std::endl; 02966 } 02967 stream << "};" << std::endl; 02968 stream.close(); 02969 } 02970 catch (std::ios::failure&) { 02971 throw Exception("vGenerator::DotWrite", 02972 "Exception opening/writing dotfile \""+rFileName+"\"", 2); 02973 } 02974 } 02975 02976 02977 // XDotWrite(rFileName) 02978 void vGenerator::XDotWrite(const std::string& rFileName) const { 02979 FD_DG("vGenerator(" << this << ")::XDotWrite(" << rFileName << ")"); 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 << "digraph \"___" << Name() << "___\" {" << std::endl; 02987 stream << " rankdir=LR" << std::endl; 02988 stream << " node [shape=circle];" << std::endl; 02989 stream << std::endl; 02990 stream << " // stateset" << std::endl; 02991 for (lit = InitStatesBegin(); lit != InitStatesEnd(); ++lit) { 02992 stream << " \"s" << *lit << "\";" << std::endl; 02993 } 02994 for (lit = MarkedStatesBegin(); lit != MarkedStatesEnd(); ++lit) { 02995 stream << " \"s" << *lit << "\";" << std::endl; 02996 } 02997 for (lit = StatesBegin(); lit != StatesEnd(); ++lit) { 02998 if(ExistsInitState(*lit)) continue; 02999 if(ExistsMarkedState(*lit)) continue; 03000 stream << " \"s" << *lit << "\";" << std::endl; 03001 } 03002 stream << std::endl; 03003 stream << " // transition relation" << std::endl; 03004 for (tit = TransRelBegin(); tit != TransRelEnd(); ++tit) { 03005 stream << " \"s" << tit->X1 03006 << "\" -> \"s" << tit->X2 03007 << "\" [label=\"e" << tit->Ev << "\" " << "polyline" << "];" << std::endl; 03008 } 03009 stream << "};" << std::endl; 03010 stream.close(); 03011 } 03012 catch (std::ios::failure&) { 03013 throw Exception("vGenerator::XDotWrite", 03014 "Exception opening/writing dotfile \""+rFileName+"\"", 2); 03015 } 03016 } 03017 03018 // DoRead(tr) 03019 void vGenerator::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 03020 (void) pContext; 03021 std::string label=rLabel; 03022 if(label=="") label="Generator"; 03023 FD_DG("vGenerator(" << this << ")::DoRead(): file " << rTr.FileName() << " section " << label); 03024 // Clear old stuff 03025 Clear(); 03026 // find Generator in any of our current file formats 03027 Token btag; 03028 rTr.ReadBegin(label, btag); 03029 // sense native format 03030 Token token; 03031 rTr.Peek(token); 03032 // explcit name token: native libFAUDES file 03033 if(token.IsString()) { 03034 // get the Generator "name" token 03035 ReadGeneratorName(rTr); 03036 // read mAlphabet 03037 ReadAlphabet(rTr); 03038 // read stateset 03039 ReadStates(rTr); 03040 // read transrel 03041 ReadTransRel(rTr); 03042 // read istates 03043 ReadStateSet(rTr, "InitStates", mInitStates); 03044 // read mstates 03045 ReadStateSet(rTr, "MarkedStates", mMarkedStates); 03046 // read attribute 03047 mpGlobalAttribute->Read(rTr); 03048 } 03049 // else: try XML format 03050 else { 03051 // figure generator name 03052 std::string name="generator"; 03053 if(btag.ExistsAttributeString("name")) 03054 name=btag.AttributeStringValue("name"); 03055 Name(name); 03056 // read alphabet 03057 mpAlphabet->Read(rTr,"Alphabet"); 03058 // read state set 03059 XReadStateSet(rTr, *mpStates, "StateSet"); 03060 mpStates->Name("States"); 03061 // read trans rel 03062 XReadTransRel(rTr); 03063 // read attribute 03064 mpGlobalAttribute->Read(rTr); 03065 // fix labels 03066 mInitStates.Name("InitStates"); 03067 mMarkedStates.Name("MarkedStates"); 03068 } 03069 // read end 03070 rTr.ReadEnd(label); 03071 FD_DG("vGenerator(" << this << ")::DoRead(): done"); 03072 } 03073 03074 // ReadGeneratorName(rFileName) 03075 void vGenerator::ReadGeneratorName(const std::string& rFileName) { 03076 TokenReader tr(rFileName); 03077 tr.ReadBegin("Generator"); // mimique old behaviour .. use "ReadBegin" instead 03078 ReadGeneratorName(tr); 03079 } 03080 03081 // ReadGeneratorName(tr) 03082 void vGenerator::ReadGeneratorName(TokenReader& rTr) { 03083 FD_DG("vGenerator(" << this << ")::ReadGeneratorName(\"" 03084 << rTr.FileName() << "\")"); 03085 mMyName=rTr.ReadString(); 03086 } 03087 03088 // ReadAlphabet(rFileName) 03089 void vGenerator::ReadAlphabet(const std::string& rFileName) { 03090 FD_DG("vGenerator(" << this << ")::ReadAlphabet(\"" << rFileName << "\")"); 03091 mpAlphabet->Read(rFileName,"Alphabet"); 03092 } 03093 03094 // ReadAlphabet(rTr) 03095 void vGenerator::ReadAlphabet(TokenReader& rTr) { 03096 FD_DG("vGenerator(" << this << ")::ReadAlphabet(\"" 03097 << rTr.FileName() << "\")"); 03098 mpAlphabet->Read(rTr,"Alphabet"); 03099 } 03100 03101 // ReadStates(rFileName) 03102 void vGenerator::ReadStates(const std::string& rFileName) { 03103 TokenReader tr(rFileName); 03104 ReadStates(tr); 03105 } 03106 03107 // ReadStates(tr) 03108 void vGenerator::ReadStates(TokenReader& rTr) { 03109 FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\")"); 03110 // HELPERS: 03111 Token token; 03112 AttributeVoid* attrp = mpStates->Attribute().New(); 03113 FD_DG("vGenerator(" << this << ")::ReadStates(..): attribute type " << typeid(*attrp).name()); 03114 // ALGORITHM: 03115 mpStates->Clear(); 03116 mpStates->Name("States"); 03117 mStateSymbolTable.Clear(); 03118 // track occurence of explicit symboltable 03119 bool symimpl=false; 03120 bool symexpl=false; 03121 Idx symnext=1; 03122 // loop section 03123 rTr.ReadBegin("States"); 03124 while(!rTr.Eos("States")) { 03125 // peek 03126 rTr.Peek(token); 03127 // read state by index 03128 if(token.IsInteger()) { 03129 rTr.Get(token); 03130 Idx index = token.IntegerValue(); 03131 FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by index " << index); 03132 if(mpStates->Exists(index)) { 03133 delete attrp; 03134 std::stringstream errstr; 03135 errstr << "Token " << token.IntegerValue() << " appears twice in stateset" 03136 << rTr.FileLine(); 03137 throw Exception("vGenerator::ReadStates", errstr.str(), 80); 03138 } 03139 // read attribute 03140 attrp->Read(rTr,"",this); 03141 // skip unknown attributes 03142 AttributeVoid::Skip(rTr); 03143 // insert element with attribute 03144 InsState(index); 03145 StateAttribute(index,*attrp); 03146 symnext++; 03147 continue; 03148 } 03149 // read state by name 03150 if(token.IsString()) { 03151 rTr.Get(token); 03152 FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): by name " << token.StringValue()); 03153 // interpret name, sense index suffx if present 03154 std::string statename=token.StringValue(); 03155 Idx index=symnext; 03156 std::size_t pos= statename.find_first_of('#'); 03157 if(pos==std::string::npos) symimpl=true; 03158 if(pos!=std::string::npos) symexpl=true; 03159 if(pos!=std::string::npos && pos < statename.size()-1) { 03160 std::string suffix=statename.substr(pos+1); 03161 index=ToIdx(suffix); 03162 statename=statename.substr(0,pos); 03163 FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): extracted suffix from " << token.StringValue() << ": " << statename << " idx " << index); 03164 } 03165 // no doublets 03166 if(ExistsState(statename) || ExistsState(index)) { 03167 delete attrp; 03168 std::stringstream errstr; 03169 errstr << "State " << statename << "(idx " << index <<") appears twice in stateset" 03170 << rTr.FileLine(); 03171 throw Exception("vGenerator::ReadStates", errstr.str(), 80); 03172 } 03173 // read attribute 03174 attrp->Read(rTr,"",this); 03175 // skip unknown attributes 03176 AttributeVoid::Skip(rTr); 03177 // insert element with attribute 03178 InsState(index); 03179 StateName(index,statename); 03180 StateAttribute(index,*attrp); 03181 symnext++; 03182 continue; 03183 } 03184 // read consecutive block of anonymous states 03185 if(token.IsBegin("Consecutive")) { 03186 rTr.ReadBegin("Consecutive"); 03187 Token token1,token2; 03188 rTr.Get(token1); 03189 rTr.Get(token2); 03190 FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): consecutive range"); 03191 if ((!token1.IsInteger()) || (!token2.IsInteger())) { 03192 delete attrp; 03193 std::stringstream errstr; 03194 errstr << "Invalid range of consecutive states" << rTr.FileLine(); 03195 throw Exception("vGenerator::ReadStates", errstr.str(), 80); 03196 } 03197 for(Idx index = (Idx) token1.IntegerValue(); index <= (Idx) token2.IntegerValue(); ++index) { 03198 if(mpStates->Exists(index)) { 03199 delete attrp; 03200 std::stringstream errstr; 03201 errstr << "Index " << index << " appears twice in stateset" 03202 << rTr.FileLine(); 03203 throw Exception("vGenerator::ReadStates", errstr.str(), 80); 03204 } 03205 InsState(index); 03206 symnext++; 03207 } 03208 rTr.ReadEnd("Consecutive"); 03209 continue; 03210 } 03211 // cannot process token 03212 delete attrp; 03213 std::stringstream errstr; 03214 errstr << "Invalid token" << rTr.FileLine(); 03215 throw Exception("vGenerator::ReadStates", errstr.str(), 80); 03216 } 03217 rTr.ReadEnd("States"); 03218 // test consistent explicit symboltable 03219 if(symimpl && symexpl) { 03220 delete attrp; 03221 std::stringstream errstr; 03222 errstr << "StateSet with inconsitent explicit symboltable" << rTr.FileLine(); 03223 throw Exception("vGenerator::ReadStates", errstr.str(), 80); 03224 } 03225 // dispose attribute 03226 delete attrp; 03227 FD_DG("vGenerator(" << this << ")::ReadStates(\"" << rTr.FileName() << "\"): done"); 03228 } 03229 03230 03231 // ReadStateSet(tr, rLabel, rStateSet) 03232 void vGenerator::ReadStateSet(TokenReader& rTr, const std::string& rLabel, StateSet& rStateSet) const { 03233 FD_DG("vGenerator(" << this << ")::ReadStateSet(\"" << rLabel<< "\")"); 03234 // HELPERS: 03235 Token token; 03236 AttributeVoid* attrp = rStateSet.Attribute().New(); 03237 FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name()); 03238 // ALGORITHM: 03239 rStateSet.Clear(); 03240 rTr.ReadBegin(rLabel); 03241 rStateSet.Name(rLabel); 03242 // loop section 03243 while(!rTr.Eos(rLabel)) { 03244 // peek 03245 rTr.Peek(token); 03246 // read state by index 03247 if(token.IsInteger()) { 03248 rTr.Get(token); 03249 Idx index = token.IntegerValue(); 03250 if(!ExistsState(index)) { 03251 delete attrp; 03252 std::stringstream errstr; 03253 errstr << "Token " << token.IntegerValue() << " not in stateset" 03254 << rTr.FileLine(); 03255 throw Exception("vGenerator::ReadStateSet", errstr.str(), 80); 03256 } 03257 // read attribute 03258 attrp->Read(rTr,"",this); 03259 // skip unknown attributes 03260 AttributeVoid::Skip(rTr); 03261 // insert element with attribute 03262 rStateSet.Insert(index); 03263 rStateSet.Attribute(index,*attrp); 03264 continue; 03265 } 03266 // read state by name 03267 if(token.IsString()) { 03268 rTr.Get(token); 03269 // test validity of symbolic name (no suffixes allowed here ... simply ignore) 03270 std::string statename=token.StringValue(); 03271 std::size_t pos= statename.find_first_of('#'); 03272 if(pos!=std::string::npos) { 03273 delete attrp; 03274 std::stringstream errstr; 03275 errstr << "invalid symbolic name: " << token.StringValue() 03276 << " (no suffix allowed in external state sets)" << rTr.FileLine(); 03277 throw Exception("vGenerator::ReadStateSet", errstr.str(), 80); 03278 } 03279 Idx index =StateIndex(statename); 03280 if(index==0) { 03281 delete attrp; 03282 std::stringstream errstr; 03283 errstr << "Symbolic name " << token.StringValue() << " not in stateset" 03284 << rTr.FileLine(); 03285 throw Exception("vGenerator::ReadStateSet", errstr.str(), 80); 03286 } 03287 // read attribute 03288 attrp->Read(rTr,"",this); 03289 // skip unknown attributes 03290 AttributeVoid::Skip(rTr); 03291 // insert element with attribute 03292 rStateSet.Insert(index); 03293 rStateSet.Attribute(index,*attrp); 03294 continue; 03295 } 03296 // read consecutve block of anonymous states 03297 if(token.IsBegin() && token.StringValue() == "Consecutive") { 03298 rTr.ReadBegin("Consecutive"); 03299 Token token1,token2; 03300 rTr.Get(token1); 03301 rTr.Get(token2); 03302 if(!token1.IsInteger() || !token2.IsInteger()) { 03303 delete attrp; 03304 std::stringstream errstr; 03305 errstr << "Invalid range of consecutive states" << rTr.FileLine(); 03306 throw Exception("vGenerator::ReadStateSet", errstr.str(), 80); 03307 } 03308 for(Idx index = (Idx) token1.IntegerValue(); index <= (Idx) token2.IntegerValue(); ++index) { 03309 if(!ExistsState(index)) { 03310 std::stringstream errstr; 03311 errstr << "Token " << token.IntegerValue() << " not in stateset" 03312 << rTr.FileLine(); 03313 throw Exception("vGenerator::ReadStateSet", errstr.str(), 80); 03314 } 03315 rStateSet.Insert(index); 03316 } 03317 rTr.ReadEnd("Consecutive"); 03318 continue; 03319 } 03320 // cannot process token 03321 delete attrp; 03322 std::stringstream errstr; 03323 errstr << "Invalid token" << rTr.FileLine(); 03324 throw Exception("vGenerator::ReadStateSet", errstr.str(), 50); 03325 } 03326 rTr.ReadEnd(rLabel); 03327 // dispose attribute 03328 delete attrp; 03329 } 03330 03331 // XReadStateSet(tr, rLabel, rStateSet) 03332 void vGenerator::XReadStateSet(TokenReader& rTr, StateSet& rStateSet, const std::string& rLabel) const { 03333 FD_DG("vGenerator(" << this << ")::XReadStateSet(\"" << rLabel<< "\")"); 03334 AttributeVoid* attrp = rStateSet.Attribute().New(); 03335 FD_DG("vGenerator(" << this << ")::ReadStateSet(..): attribute type " << typeid(*attrp).name()); 03336 // Clear my set 03337 rStateSet.Clear(); 03338 // Figure section 03339 std::string label=rLabel; 03340 if(label=="") label=rStateSet.Name(); 03341 if(label=="") label="StateSet"; 03342 // Read begin 03343 Token btag; 03344 rTr.ReadBegin(label,btag); 03345 // Use name if provided (std is no name) 03346 rStateSet.Name(""); 03347 if(btag.ExistsAttributeString("name")) 03348 rStateSet.Name(btag.AttributeStringValue("name")); 03349 // Scan my section 03350 while(!rTr.Eos(label)) { 03351 Token sttag; 03352 rTr.Get(sttag); 03353 // Read consecutive block of anonymous states 03354 if(sttag.IsBegin("Consecutive")) { 03355 // Get range 03356 Idx idx1=0; 03357 Idx idx2=0; 03358 if(sttag.ExistsAttributeInteger("from")) 03359 idx1= (Idx) sttag.AttributeIntegerValue("from"); 03360 if(sttag.ExistsAttributeInteger("to")) 03361 idx2= (Idx) sttag.AttributeIntegerValue("to"); 03362 // Insist in valid range 03363 if(idx1==0 || idx2 < idx1) { 03364 delete attrp; 03365 std::stringstream errstr; 03366 errstr << "Invalid range of consecutive states" << rTr.FileLine(); 03367 throw Exception("vGenerator::XReadStates", errstr.str(), 80); 03368 } 03369 FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): consecutive range " << idx1 << " to " << idx2); 03370 for(Idx index = idx1; index <= idx2; ++index) { 03371 if(rStateSet.Exists(index)) { 03372 delete attrp; 03373 std::stringstream errstr; 03374 errstr << "Doublet state index " << index << " " << rTr.FileLine(); 03375 throw Exception("vGenerator::XReadStates", errstr.str(), 80); 03376 } 03377 rStateSet.Insert(index); 03378 } 03379 // Done: consecutive 03380 rTr.ReadEnd("Consecutive"); 03381 continue; 03382 } 03383 // Ignore other sections 03384 if(!sttag.IsBegin("State")) { 03385 if(sttag.IsBegin()) 03386 rTr.ReadEnd(sttag.StringValue()); 03387 continue; 03388 } 03389 // Its a state 03390 std::string name=""; 03391 if(sttag.ExistsAttributeString("name")) 03392 name=sttag.AttributeStringValue("name"); 03393 Idx index=0; 03394 if(sttag.ExistsAttributeInteger("id")) 03395 index=sttag.AttributeIntegerValue("id"); 03396 FD_DG("vGenerator::XReadStateSet(): got idx " << index << " " << name); 03397 // reconstruct index from name if possible 03398 if(index==0) { 03399 index=StateIndex(name); 03400 } 03401 // failed to figure index 03402 if(index==0) { 03403 delete attrp; 03404 std::stringstream errstr; 03405 errstr << "Cannot figure index for state token " << sttag.Str() << rTr.FileLine(); 03406 throw Exception("vGenerator::XReadStateSet", errstr.str(), 80); 03407 } 03408 // dont allow doublets 03409 if(rStateSet.Exists(index)) { 03410 delete attrp; 03411 std::stringstream errstr; 03412 errstr << "Doublet state from token " << sttag.Str() << rTr.FileLine(); 03413 throw Exception("vGenerator::XReadStateSet", errstr.str(), 80); 03414 } 03415 // record state 03416 rStateSet.Insert(index); 03417 // record name if we read the core set 03418 if(&rStateSet==mpStates) 03419 if(name!="") { 03420 mpStateSymbolTable->SetEntry(index, name); 03421 } 03422 // test for attributes and such 03423 while(!rTr.Eos("State")) { 03424 Token token; 03425 rTr.Peek(token); 03426 // marking (if this is the main state set) 03427 Token mtag; 03428 if(token.IsBegin("Initial") && (&rStateSet==mpStates)) { 03429 rTr.ReadBegin("Initial",mtag); 03430 bool v=true; 03431 if(mtag.ExistsAttributeInteger("value")) 03432 v=mtag.AttributeIntegerValue("value"); 03433 if(v) const_cast<vGenerator*>(this)->SetInitState(index); 03434 rTr.ReadEnd("Initial"); 03435 continue; 03436 } 03437 if(token.IsBegin("Marked") && (&rStateSet==mpStates)) { 03438 rTr.ReadBegin("Marked",mtag); 03439 bool v=true; 03440 if(mtag.ExistsAttributeInteger("value")) 03441 v=mtag.AttributeIntegerValue("value"); 03442 if(v) const_cast<vGenerator*>(this)->SetMarkedState(index); 03443 rTr.ReadEnd("Marked"); 03444 continue; 03445 } 03446 // read attribute 03447 FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): attribute ?"); 03448 attrp->Read(rTr,"",this); 03449 rStateSet.Attribute(index,*attrp); 03450 // break on first unknown/undigested 03451 break; 03452 } 03453 // read end 03454 rTr.ReadEnd("State"); 03455 } 03456 rTr.ReadEnd(label); 03457 // dispose attribute 03458 delete attrp; 03459 FD_DG("vGenerator(" << this << ")::XReadStates(\"" << rTr.FileName() << "\"): done"); 03460 } 03461 03462 03463 // ReadTransRel(rFileName) 03464 void vGenerator::ReadTransRel(const std::string& rFileName) { 03465 TokenReader tr(rFileName); 03466 ReadTransRel(tr); 03467 } 03468 03469 // ReadTransRel(tr) 03470 void vGenerator::ReadTransRel(TokenReader& rTr) { 03471 FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\")"); 03472 AttributeVoid* attrp = mpTransRel->Attribute().New(); 03473 FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name()); 03474 try { 03475 Token token; 03476 Token x1t; 03477 Token x2t; 03478 Token evt; 03479 rTr.ReadBegin("TransRel"); 03480 // Read tokens 03481 while (rTr.Peek(token)) { 03482 03483 // clear my transition 03484 Idx x1 = 0, ev = 0, x2 = 0; 03485 03486 // 0: end of transition relation 03487 if(token.IsEnd()) break; 03488 03489 03490 // 1: the x1 token 03491 rTr >> x1t; 03492 if(x1t.IsInteger()) { 03493 x1=x1t.IntegerValue(); 03494 } else if (x1t.IsString()) { 03495 x1t.StringValue(); 03496 x1=StateIndex(x1t.StringValue()); 03497 } else break; 03498 03499 // 2: the event token 03500 rTr >> evt; 03501 if(evt.IsString()) { 03502 evt.StringValue(); 03503 ev=EventIndex(evt.StringValue()); 03504 } else break; 03505 03506 // 3: the x2 evt 03507 rTr >> x2t; 03508 if(x2t.IsInteger()) { 03509 x2=x2t.IntegerValue(); 03510 } else if(x2t.IsString()) { 03511 x2t.StringValue(); 03512 x2=StateIndex(x2t.StringValue()); 03513 } else break; 03514 03515 // 4: attributes 03516 attrp->Read(rTr,"",this); 03517 03518 // 5: skip unknown attributes 03519 AttributeVoid::Skip(rTr); 03520 03521 // check values 03522 if(!ExistsState(x1)){ 03523 std::stringstream errstr; 03524 errstr << "invalid state x1 " << x1t.StringValue() << " " << rTr.FileLine(); 03525 throw Exception("vGenerator::ReadTransRel", errstr.str(), 85); 03526 } 03527 if(!ExistsState(x2)){ 03528 std::stringstream errstr; 03529 errstr << "invalid state x2 " << x2t.StringValue() << " " << rTr.FileLine(); 03530 throw Exception("vGenerator::ReadTransRel", errstr.str(), 85); 03531 } 03532 if(!ExistsEvent(ev)) { 03533 std::stringstream errstr; 03534 errstr << "invalid event " << evt.StringValue() << " " << rTr.FileLine(); 03535 throw Exception("vGenerator::ReadTransRel", errstr.str(), 85); 03536 } 03537 03538 // insert transition 03539 Transition trans=Transition(x1,ev,x2); 03540 SetTransition(trans); 03541 TransAttribute(trans,*attrp); 03542 03543 } // end while 03544 rTr.ReadEnd("TransRel"); 03545 } 03546 03547 catch (faudes::Exception& oex) { 03548 delete attrp; 03549 std::stringstream errstr; 03550 errstr << "Reading TransRel failed in " << rTr.FileLine() << oex.What(); 03551 throw Exception("vGenerator::ReadTransRel", errstr.str(), 50); 03552 } 03553 FD_DG("vGenerator(" << this << ")::ReadTransRel(\"" << rTr.FileName() << "\"): sone"); 03554 03555 // dispose attribute 03556 delete attrp; 03557 } 03558 03559 03560 // XReadTransRel(tr) 03561 void vGenerator::XReadTransRel(TokenReader& rTr) { 03562 FD_DG("vGenerator(" << this << ")::XReadTransRel()"); 03563 AttributeVoid* attrp = mpTransRel->Attribute().New(); 03564 FD_DG("vGenerator(" << this << ")::ReadTransRel(..): attribute type " << typeid(*attrp).name()); 03565 // Clear my set 03566 mpTransRel->Clear(); 03567 mpTransRel->Name("TransRel"); 03568 // Read begin 03569 Token btag; 03570 rTr.ReadBegin("TransitionRelation",btag); 03571 // Scan my section 03572 while(!rTr.Eos("TransitionRelation")) { 03573 Token trtag; 03574 rTr.Get(trtag); 03575 // Ignore other sections 03576 if(!trtag.IsBegin("Transition")) { 03577 if(trtag.IsBegin()) 03578 rTr.ReadEnd(trtag.StringValue()); 03579 continue; 03580 } 03581 // Its a transition 03582 Idx x1=0; 03583 Idx x2=0; 03584 Idx ev=0; 03585 std::string evname; 03586 std::string x1name; 03587 std::string x2name; 03588 if(trtag.ExistsAttributeInteger("x1")) 03589 x1=trtag.AttributeIntegerValue("x1"); 03590 if(trtag.ExistsAttributeInteger("x2")) 03591 x2=trtag.AttributeIntegerValue("x2"); 03592 if(trtag.ExistsAttributeString("x1")) 03593 x1name=trtag.AttributeStringValue("x1"); 03594 if(trtag.ExistsAttributeString("x2")) 03595 x2name=trtag.AttributeStringValue("x2"); 03596 if(trtag.ExistsAttributeString("event")) 03597 evname=trtag.AttributeStringValue("event"); 03598 // Interpret names 03599 ev=EventIndex(evname); 03600 if(x1==0) x1=StateIndex(x1name); 03601 if(x2==0) x2=StateIndex(x2name); 03602 // Report 03603 FD_DG("vGenerator::XReadTransRel(): got transition " << TStr(Transition(x1,ev,x2))); 03604 // test 1: components specified 03605 if(x1==0 || x2==0 || ev==0) { 03606 delete attrp; 03607 std::stringstream errstr; 03608 errstr << "Invalid transition at token " << trtag.Str() << rTr.FileLine(); 03609 throw Exception("vGenerator::XReadTransRel", errstr.str(), 80); 03610 } 03611 // test 2: no doublets 03612 if(ExistsTransition(x1,ev,x2)) { 03613 delete attrp; 03614 std::stringstream errstr; 03615 errstr << "Doublet transition at token " << trtag.Str() << rTr.FileLine(); 03616 throw Exception("vGenerator::XReadTransRel", errstr.str(), 80); 03617 } 03618 // test 3: components must exist 03619 if(!ExistsState(x1)){ 03620 delete attrp; 03621 std::stringstream errstr; 03622 errstr << "Invalid state x1 " << x1 << " " << rTr.FileLine(); 03623 throw Exception("vGenerator::XReadTransRel", errstr.str(), 80); 03624 } 03625 if(!ExistsState(x2)){ 03626 delete attrp; 03627 std::stringstream errstr; 03628 errstr << "Invalid state x2 " << x2 << " " << rTr.FileLine(); 03629 throw Exception("vGenerator::XReadTransRel", errstr.str(), 80); 03630 } 03631 if(!ExistsEvent(ev)){ 03632 delete attrp; 03633 std::stringstream errstr; 03634 errstr << "Invalid event " << evname << " " << rTr.FileLine(); 03635 throw Exception("vGenerator::XReadTransRel", errstr.str(), 80); 03636 } 03637 // record transition 03638 SetTransition(x1,ev,x2); 03639 // test for attribute 03640 Token token; 03641 rTr.Peek(token); 03642 if(!token.IsEnd("Transition")) { 03643 // read attribute 03644 attrp->Read(rTr,"",this); 03645 TransAttribute(Transition(x1,ev,x2),*attrp); 03646 } 03647 // read end 03648 rTr.ReadEnd("Transition"); 03649 } 03650 rTr.ReadEnd("TransitionRelation"); 03651 // dispose attribute 03652 delete attrp; 03653 FD_DG("vGenerator(" << this << ")::XReadTransRel(\"" << rTr.FileName() << "\"): done"); 03654 } 03655 03656 // EStr(index) 03657 std::string vGenerator::EStr(Idx index) const { 03658 std::string name = EventName(index); 03659 return name+"#"+faudes::ToStringInteger(index); 03660 } 03661 03662 // SStr(index) 03663 std::string vGenerator::SStr(Idx index) const { 03664 std::string name = StateName(index); 03665 if(name == "") name=ToStringInteger(index); 03666 return name+"#"+faudes::ToStringInteger(index); 03667 } 03668 03669 // TStr(index) 03670 std::string vGenerator::TStr(const Transition& trans) const { 03671 return SStr(trans.X1) + "--(" + EStr(trans.Ev) + ")-->" + SStr(trans.X2); 03672 } 03673 03674 03675 // GraphWrite(rFileName,rOutFormat) 03676 void vGenerator::GraphWrite(const std::string& rFileName, const std::string& rOutFormat, 03677 const std::string& rDotExec) const { 03678 FD_DG("vGenerator::GraphWrite(...): " << typeid(*this).name()); 03679 // generate temp dot ibput file 03680 std::string dotin = CreateTempFile(); 03681 if(dotin == "") { 03682 std::stringstream errstr; 03683 errstr << "Exception opening temp file"; 03684 throw Exception("vGenerator::GraphWrite", errstr.str(), 2); 03685 } 03686 try{ 03687 DotWrite(dotin); 03688 } 03689 catch (faudes::Exception& exception) { 03690 RemoveFile(dotin); 03691 std::stringstream errstr; 03692 errstr << "Exception writing dot input file"; 03693 throw Exception("vGenerator::GraphWrite", errstr.str(), 2); 03694 } 03695 try{ 03696 faudes::ProcessDot(dotin,rFileName,rOutFormat,rDotExec); 03697 } 03698 catch (faudes::Exception& exception) { 03699 RemoveFile(dotin); 03700 std::stringstream errstr; 03701 errstr << "Exception processing dot file"; 03702 throw Exception("vGenerator::GraphWrite", errstr.str(), 3); 03703 } 03704 RemoveFile(dotin); 03705 } 03706 03707 // rti wrapper 03708 bool IsAccessible(const vGenerator& rGen) { 03709 return rGen.IsAccessible(); 03710 } 03711 03712 // rti wrapper 03713 bool IsCoaccessible(const vGenerator& rGen) { 03714 return rGen.IsCoaccessible(); 03715 } 03716 03717 // rti wrapper 03718 bool IsTrim(const vGenerator& rGen) { 03719 return rGen.IsTrim(); 03720 } 03721 03722 // rti wrapper 03723 bool IsOmegaTrim(const vGenerator& rGen) { 03724 return rGen.IsOmegaTrim(); 03725 } 03726 03727 // rti wrapper 03728 bool IsComplete(const vGenerator& rGen) { 03729 return rGen.IsComplete(); 03730 } 03731 03732 // rti wrapper 03733 bool IsComplete(const vGenerator& rGen, const StateSet& rStateSet) { 03734 return rGen.IsComplete(rStateSet); 03735 } 03736 03737 // rti wrapper 03738 bool IsDeterministic(const vGenerator& rGen) { 03739 return rGen.IsDeterministic(); 03740 } 03741 03742 03743 // rti wrapper 03744 void Accessible(vGenerator& rGen) { 03745 rGen.Accessible(); 03746 } 03747 03748 // rti wrapper 03749 void Accessible(const vGenerator& rGen, vGenerator& rRes) { 03750 rRes=rGen; 03751 rRes.Accessible(); 03752 } 03753 03754 // rti wrapper 03755 void Coaccessible(vGenerator& rGen) { 03756 rGen.Coaccessible(); 03757 } 03758 03759 // rti wrapper 03760 void Coaccessible(const vGenerator& rGen, vGenerator& rRes) { 03761 rRes=rGen; 03762 rRes.Coaccessible(); 03763 } 03764 03765 // rti wrapper 03766 void Complete(vGenerator& rGen) { 03767 rGen.Complete(); 03768 } 03769 03770 // rti wrapper 03771 void Complete(const vGenerator& rGen, vGenerator& rRes) { 03772 rRes=rGen; 03773 rRes.Complete(); 03774 } 03775 03776 // rti wrapper 03777 void Trim(vGenerator& rGen) { 03778 rGen.Trim(); 03779 } 03780 03781 // rti wrapper 03782 void Trim(const vGenerator& rGen, vGenerator& rRes) { 03783 rRes=rGen; 03784 rRes.Trim(); 03785 } 03786 03787 // rti wrapper 03788 void OmegaTrim(vGenerator& rGen) { 03789 rGen.OmegaTrim(); 03790 } 03791 03792 // rti wrapper 03793 void OmegaTrim(const vGenerator& rGen, vGenerator& rRes) { 03794 rRes=rGen; 03795 rRes.OmegaTrim(); 03796 } 03797 03798 // rti wrapper 03799 void MarkAllStates(vGenerator& rGen) { 03800 rGen.InjectMarkedStates(rGen.States()); 03801 } 03802 03803 03804 // rti wrapper 03805 void AlphabetExtract(const vGenerator& rGen, EventSet& rRes) { 03806 // This function is an ideal debugging case for lbp_function.cpp. 03807 // FD_WARN("AlphabetExtract(): gen at " << &rGen << " sig at " << &rRes); 03808 // FD_WARN("AlphabetExtract(): gen id " << typeid(rGen).name() << " sig id " << typeid(rRes).name()); 03809 rRes = rGen.Alphabet(); 03810 // rRes.Write(); 03811 } 03812 03813 // rti convenience function 03814 void SetIntersection(const GeneratorVector& rGenVec, EventSet& rRes) { 03815 // prepare result 03816 rRes.Clear(); 03817 // ignore empty 03818 if(rGenVec.Size()==0) return; 03819 // copy first 03820 rRes.Assign(rGenVec.At(0).Alphabet()); 03821 // perform intersecttion 03822 for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) 03823 SetIntersection(rGenVec.At(i).Alphabet(),rRes,rRes); 03824 } 03825 03826 03827 // rti convenience function 03828 void SetUnion(const GeneratorVector& rGenVec, EventSet& rRes) { 03829 // prepare result 03830 rRes.Clear(); 03831 // ignore empty 03832 if(rGenVec.Size()==0) return; 03833 // copy first 03834 rRes.Assign(rGenVec.At(0).Alphabet()); 03835 // perform intersecttion 03836 for(GeneratorVector::Position i=1; i<rGenVec.Size(); i++) 03837 SetUnion(rGenVec.At(i).Alphabet(),rRes,rRes); 03838 } 03839 03840 // rti convenience function 03841 void SetIntersection(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) { 03842 SetIntersection(rGenA.Alphabet(),rGenB.Alphabet(),rRes); 03843 } 03844 03845 // rti convenience function 03846 void SetUnion(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) { 03847 SetUnion(rGenA.Alphabet(),rGenB.Alphabet(),rRes); 03848 } 03849 03850 // rti convenience function 03851 void SetDifference(const vGenerator& rGenA, const vGenerator& rGenB, EventSet& rRes) { 03852 SetDifference(rGenA.Alphabet(),rGenB.Alphabet(),rRes); 03853 } 03854 03855 03856 } // name space 03857 03858 |
libFAUDES 2.22s --- 2013.10.07 --- c++ source docu by doxygen