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