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