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