|
libFAUDES
Sections
Index
|
1_generator.cppGo to the documentation of this file.00001 /** @file 1_generator.cpp 00002 00003 Tutorial, basic faudes::Generator methods. 00004 00005 The Generator class implements the 5-tuple automaton G, consisting of 00006 - Set of States Q, 00007 - Alphabet Sigma, 00008 - Transition Relation Delta, 00009 - Set of Initial States Qo, and 00010 - Set of Marked States Qm. 00011 00012 This tutorial demonstrates how to insert/erase states, events and transitions. 00013 It also demonstrates file IO. 00014 00015 @ingroup Tutorials 00016 @include 1_generator.cpp 00017 00018 */ 00019 00020 00021 #include "libfaudes.h" 00022 00023 // make the faudes namespace available to our program 00024 using namespace faudes; 00025 00026 00027 00028 ///////////////// 00029 // main program 00030 ///////////////// 00031 00032 int main() { 00033 00034 //////////////////////////////////////////// 00035 // Constructors (part 1) and filling example 00036 //////////////////////////////////////////// 00037 00038 // at first we create an empty Generator object 00039 00040 Generator g1; 00041 00042 // do some random "user interaction" stuff with the Generator g1 00043 00044 g1.InsState("s1"); 00045 g1.InsState("s2"); 00046 g1.InsState("s3"); 00047 00048 g1.InsEvent("a"); 00049 g1.InsEvent("b"); 00050 00051 g1.SetTransition("s1", "a", "s2"); 00052 g1.SetTransition("s2", "a", "s3"); 00053 g1.SetTransition("s3", "b", "s1"); 00054 00055 g1.SetInitState("s1"); 00056 g1.SetMarkedState("s2"); 00057 g1.SetMarkedState("s3"); 00058 00059 // inspect result on console 00060 00061 std::cout << "################################\n"; 00062 std::cout << "# tutorial, handcraft generator \n"; 00063 g1.Write(); 00064 std::cout << "################################\n"; 00065 00066 00067 00068 /////////////////////////////////////////////////// 00069 // Constructors (part 2) & Copying and versioning 00070 /////////////////////////////////////////////////// 00071 00072 // Create a 1:1 copy of the Generator with the copy constructor ... 00073 00074 Generator g_copy(g1); 00075 00076 // ... with assignment method, or assignement operator 00077 00078 Generator g2; 00079 g2.Assign(g1); 00080 Generator g3=g2; 00081 00082 // create a Generator copy with versioned events (for testing algorithms): 00083 // versioning by an integer. E.g. for integer 3 events {"a", "b", "c"} 00084 // become {"a_3", "b_3", "c_3"}. 00085 00086 Generator version1; 00087 g3.Version(3, version1); 00088 00089 // versioning by a string. "a" -> "a_versionstring" 00090 00091 Generator version2; 00092 g3.Version("str", version2); 00093 00094 // inspect result on console 00095 00096 std::cout << "################################\n"; 00097 std::cout << "# tutorial, version of generator \n"; 00098 version2.Write(); 00099 std::cout << "################################\n"; 00100 00101 00102 00103 /////////////////////////////////////////////// 00104 // Methods for Input/Output 00105 /////////////////////////////////////////////// 00106 00107 // read a Generator from file 00108 00109 g2.Read("data/simplemachine.gen"); 00110 00111 // create a Generator by reading a Generator file 00112 00113 Generator g4("data/simplemachine.gen"); 00114 00115 00116 // write a Generator to file 00117 // (map state indices to begin with 1) 00118 00119 g4.Write("tmp_simplemachine.gen"); 00120 00121 // write a Generator to file by appending the output 00122 // (map state indeces to begin with 1) 00123 00124 g4.Write("tmp_simplemachine.gen", std::ios::out|std::ios::app); 00125 00126 // debug output of Generator to console 00127 // (use actual state indices) 00128 00129 std::cout << "################################\n"; 00130 std::cout << "# tutorial, debug dump \n"; 00131 g4.DWrite(); 00132 std::cout << "################################\n"; 00133 00134 // create dotfile for further processing by graphviz 00135 // (map state indices to begin with 1) 00136 00137 g4.DotWrite("tmp_simplemachine.dot"); 00138 g4.DDotWrite("tmp_simplemachine_debug.dot"); 00139 00140 // there also is a convenience method, that runs graphviz to 00141 // generate graphical output; requires "dot" binary in $PATH 00142 try { 00143 g4.GraphWrite("tmp_simplemachin.png"); 00144 } catch(faudes::Exception& exception) { 00145 std::cout << "1_generator: cannot execute graphviz' dot. " << std::endl; 00146 } 00147 00148 00149 // create a debug string for an event with symbolic name + index 00150 00151 std::string str_singleevent = g1.EStr(2); 00152 00153 // create a debug string for a state with symbolic name + index. 00154 // If there is no symblic name, a symbolic name of the index is constructed. 00155 00156 std::string str_singlestate = g1.SStr(3); 00157 00158 // build string of events in the Generator's alphabet 00159 00160 std::string str_alph = g1.AlphabetToString(); 00161 00162 // build string of states in the Generator's set of states 00163 std::string str_states = g1.StatesToString(); 00164 00165 // there also are TransRelToString(), InitStatesToString() and MarkedStatesToString() 00166 00167 00168 ////////////////////////////////////// 00169 // Accessing the Generator's Members 00170 ////////////////////////////////////// 00171 00172 // get the Generator's name 00173 00174 std::string str_name = g1.Name(); 00175 00176 // set new name for Generator 00177 00178 g1.Name("NewName"); 00179 00180 00181 00182 // the core members alphabet, stateset and transitionrelation may be retrieved 00183 // as const references; ie. they can be inspected freely, but write access is 00184 // exclusively via the provided Generator methods. 00185 00186 // retrieve a const reference to and copy of the Generator's alphabet 00187 00188 const EventSet& eset_ref_alph = g1.Alphabet(); 00189 EventSet eset_copy_alph = g1.Alphabet(); 00190 00191 // you cannot alter the alphabet of a generator via an alphabet method 00192 // eset_ref_alph.Insert("new_event"); // compile time error! 00193 00194 // however, the copy can be altered, but with no effect on the original generator 00195 00196 eset_copy_alph.Insert("new_event"); 00197 if(g1.ExistsEvent("new_event")) std::cout << "### THIS CANNOT HAPPEN ###"; 00198 00199 // retrieve a const reference to and copy of the Generator's set of states "mStates" 00200 00201 const StateSet& sset_ref_states = g1.States(); 00202 StateSet sset_copy_states = g1.States(); 00203 00204 // retrieve a const reference to and a copy of the Generator's transition relation "mTransRel" 00205 00206 const TransSet& tset_ref_trel = g1.TransRel(); 00207 TransSet tset_copy_trel = g1.TransRel(); 00208 00209 // same with initial states and marked states 00210 00211 const StateSet& sset_ref_istates = g1.InitStates(); 00212 StateSet sset_copy_istates = g1.InitStates(); 00213 00214 const StateSet& sset_ref_mstates = g1.MarkedStates(); 00215 StateSet sset_copy_mstates = g1.MarkedStates(); 00216 00217 00218 00219 ////////////////////////////////////////////////////////////////////////////// 00220 // Modifying the 5-tuple Generator (X, Sigma, Delta, X0 and Xm) 00221 ////////////////////////////////////////////////////////////////////////////// 00222 00223 // insert an event by it's symbolic name in the alphabet 00224 // (if the event is not known so far, a new index for the symbolic name is generated) 00225 g1.InsEvent("newevent"); 00226 00227 00228 // insert an existing event into the Generator's alphabet (mAlphabet) 00229 // (by "existing event" we refer to an event that has been previously inserted to some Generator) 00230 00231 g1.InsEvent(1); // of course index 1 is already in the alphabet here... 00232 00233 // insert a bunch of events (EventSet) and get the integer index if requested 00234 00235 EventSet eset1; 00236 eset1.Insert("newevent1"); 00237 Idx idx_tmp = eset1.Insert("newevent2"); 00238 g1.InsEvents(eset1); 00239 00240 // delete an event from Generator ie delete from alphabet and transition relation 00241 00242 g1.DelEvent("newevent1"); // by symbolic name 00243 g1.DelEvent(idx_tmp); // by index 00244 00245 // delete a bunch of events 00246 // g1.DelEvents(eset1); // .. of course we have already deleted them before... 00247 00248 // insert a new state. The state gets a integer index that is unique within 00249 // the Generator 00250 00251 idx_tmp = g1.InsState(); // anonymous state 00252 idx_tmp = g1.InsState("newstate2"); // named state 00253 00254 // insert a new state as initial state 00255 00256 idx_tmp = g1.InsInitState(); 00257 idx_tmp = g1.InsInitState("newinitstate"); 00258 00259 // ... same for marked states 00260 00261 idx_tmp = g1.InsMarkedState(); 00262 idx_tmp = g1.InsMarkedState("newmarkedstate"); 00263 00264 00265 // delete single states from Generator ie stateset and transitionrelation 00266 00267 g1.DelState(idx_tmp); // by index (relatively fast, for algorithms) 00268 g1.DelState("newinitstate"); // by symbolic name, if name assigned 00269 00270 // delete a bunch of states 00271 // (this should be more efficient than deleting states individually) 00272 00273 StateSet stateset1; 00274 stateset1.Insert(1); 00275 stateset1.Insert(2); 00276 stateset1.Insert(3); 00277 g1.DelStates(stateset1); 00278 00279 // for further proceeding we insert some new states and events... 00280 00281 Idx idx_s10 = g1.InsState("s10"); 00282 Idx idx_s11 = g1.InsState("s11"); 00283 Idx idx_s12 = g1.InsState("s12"); 00284 Idx idx_e10 = g1.InsEvent("e10"); 00285 Idx idx_e11 = g1.InsEvent("e11"); 00286 00287 // set a state that already exists in Generator as initial state 00288 00289 g1.SetInitState(idx_s10); 00290 00291 // set a state that already exists in Generator as marked state 00292 00293 g1.SetMarkedState(idx_s11); 00294 00295 // unset an existing state as initial state (does not remove from mStates) 00296 00297 g1.ClrInitState(idx_s10); 00298 00299 // unset an existing state as marked state (does not remove from stateset) 00300 00301 g1.ClrMarkedState(idx_s10); 00302 00303 // clear all initial states (does not remove from stateset) 00304 00305 // g1.ClrInitStates(); // we do not really do it here, so it's commented 00306 00307 // clear all marked states (mStates stays untouched) 00308 00309 // g1.ClrMarkedStates(); // we do not really do it here, so it's commented 00310 00311 // set a transition for existing states and events 00312 00313 g1.SetTransition(idx_s10, idx_e10, idx_s11); // by indices 00314 g1.SetTransition("s10", "e11", "s10"); // by symbolic names (slow) 00315 00316 00317 // report back to console 00318 00319 std::cout << "################################\n"; 00320 std::cout << "# tutorial, on the way \n"; 00321 g1.DWrite(); 00322 std::cout << "################################\n"; 00323 00324 00325 // clear a transition (does not touch mStates, mInitStates and mMarkedStates) 00326 00327 g1.ClrTransition(idx_s10, idx_e10, idx_s11); // by index 00328 00329 // transitions can also be cleared by names (slower) or by an assigned 00330 // TransSet::Iterator (faster); use ClearTransRel() to remove all transitions 00331 00332 00333 // clear the symbolic name for a state in the StateSymbolTable 00334 00335 g1.ClrStateName(idx_s10); 00336 00337 // exists event index/name in mAlphabet? 00338 00339 bool bool_eventexists1 = g1.ExistsEvent("e11"); 00340 bool bool_eventexists2 = g1.ExistsEvent(2); 00341 00342 00343 // exists state in mStates? 00344 00345 bool bool_stateexists1 = g1.ExistsState(4); 00346 00347 00348 // check if a state is an initial state 00349 00350 bool bool_initstateexists = g1.ExistsInitState(4); 00351 00352 // check if a state is a marked state 00353 00354 bool bool_ismarkedstate = g1.ExistsMarkedState(4); 00355 00356 // look up event name for index in the EventSymbolTable of the event domain 00357 00358 std::string str_eventname1 = g1.EventName(1); 00359 00360 // look up event index for name in the EventSymbolTable of the event domain 00361 00362 Idx idx_eventindex = g1.EventIndex("e11"); 00363 00364 // get symbolic name assigned to state (returns "" if no name assigned). 00365 00366 std::string str_tmp = g1.StateName(idx_s10); 00367 00368 // get index for symbolic state name. only possible for state names of states in 00369 // the Generator 00370 00371 idx_tmp = g1.StateIndex("s12"); 00372 00373 // clear Generator (including alphabet) 00374 00375 g4.Clear(); 00376 00377 // get the number of events in the Generator's alphabet 00378 00379 Idx idx_eventnum = g1.AlphabetSize(); 00380 00381 // get the number of states 00382 00383 Idx idx_statenum = g1.Size(); 00384 00385 // get the number of transitions 00386 00387 Idx idx_transnum = g1.TransRelSize(); 00388 00389 // there also are InitStatesSize(), MarkedStatesSize() 00390 00391 // is the alphabet of the Generator empty? 00392 00393 bool bool_alphempty = g1.AlphabetEmpty(); 00394 00395 // is the Generator empty (number of states == 0) ? 00396 00397 bool bool_isempty = g1.Empty(); 00398 00399 // see also TransRelEmpty, InitStatesEmpty, MarkedStatesEmpty 00400 00401 00402 // insert a small loop 00403 00404 Idx initstate = g1.InsInitState("in"); 00405 Idx markedstate = g1.InsMarkedState("out"); 00406 g1.SetTransition("in","a","out"); 00407 g1.SetTransition("out","a","in"); 00408 00409 00410 // show effect on console 00411 00412 std::cout << "################################\n"; 00413 std::cout << "# tutorial, after ins and del \n"; 00414 g1.DWrite(); 00415 std::cout << "################################\n"; 00416 00417 00418 /////////////////////// 00419 // Iterators 00420 /////////////////////// 00421 00422 // since the core members are all implemented as sets, iterators 00423 // effectively are cont_iterators, i.e. you cannot change the 00424 // current value of an iterator. instead you may remove the value 00425 // and insert the new value. 00426 00427 // iteration over alphabet indices (member "mAlphabet") 00428 00429 std::cout << "################################\n"; 00430 std::cout << "# tutorial, iterators 1 \n"; 00431 EventSet::Iterator eit; 00432 for (eit = g1.AlphabetBegin(); eit != g1.AlphabetEnd(); ++eit) { 00433 std::cout << "event \"" << g1.EventName(*eit) << "\" with index "<< *eit << std::endl; 00434 } 00435 std::cout << "################################\n"; 00436 00437 // iteration over state indices (member "mStates") 00438 00439 std::cout << "################################\n"; 00440 std::cout << "# tutorial, iterators 2 \n"; 00441 StateSet::Iterator sit; 00442 for (sit = g1.StatesBegin(); sit != g1.StatesEnd(); ++sit) { 00443 std::cout << *sit << std::endl; 00444 } 00445 std::cout << "################################\n"; 00446 00447 // iteration over complete transition relation (member "mTransRel") 00448 00449 std::cout << "################################\n"; 00450 std::cout << "# tutorial, iterators 3 \n"; 00451 TransSet::Iterator tit; 00452 for (tit = g1.TransRelBegin(); tit != g1.TransRelEnd(); ++tit) { 00453 std::cout << g1.TStr(*tit) << std::endl; 00454 } 00455 std::cout << "################################\n"; 00456 00457 // iteration over transitions from a given state; note that we avoid 00458 // computation of the end of the iteration in every step 00459 00460 std::cout << "################################\n"; 00461 std::cout << "# tutorial, iterators 4 \n"; 00462 idx_tmp = g1.StateIndex("s1"); 00463 TransSet::Iterator tit_end; 00464 tit = g1.TransRelBegin(idx_tmp); 00465 tit_end = g1.TransRelEnd(idx_tmp); 00466 for (; tit != tit_end; ++tit) { 00467 std::cout << g1.TStr(*tit) << std::endl; 00468 } 00469 std::cout << "################################\n"; 00470 00471 // variations: transitions of given state index + given event index: 00472 // TransRelBegin(x1, ev) - TransRelEnd(x1, ev) 00473 00474 // iteration over initial and marked states: 00475 // InitStatesBegin() - InitStatesEnd() (member "mInitStates") 00476 // MarkedStatesBegin() - MarkedStatesEnd() (member "mMarkedStates") 00477 00478 00479 //////////////////////////////////////////////////////////// 00480 // retrieve copies of the Generator's transition releation 00481 // in different sorting orders than X1 -> Ev -> X2 00482 //////////////////////////////////////////////////////////// 00483 00484 // note: the availabity of iterator ranges depends on the sorting order; 00485 // eg iteration with specified x2 requires X2->Ev->X1 or X2->X1->Ev sorting. 00486 00487 // retrieve a copy that is sorted by X2 -> Ev -> X1 by the binary 00488 // predicate TransSort::X2EvX1. 00489 00490 TransSetX2EvX1 tset_x2evx1; 00491 g1.TransRel(tset_x2evx1); 00492 00493 // report to console 00494 00495 std::cout << "################################\n"; 00496 std::cout << "# tutorial, x2-ev-x1 sorting\n"; 00497 TransSetX2EvX1::Iterator tit2; 00498 for (tit2 = tset_x2evx1.Begin(); tit2 != tset_x2evx1.End(); ++tit2) { 00499 std::cout << g1.TStr(*tit2) << std::endl; 00500 } 00501 std::cout << "################################\n"; 00502 00503 00504 00505 //////////////////////// 00506 // Convenience Methods 00507 //////////////////////// 00508 00509 // remove all events from mAlphabet, that do not have a transition in 00510 // mTransRel: g1.MinimizeAlphabet() 00511 00512 // get an EventSet containing all the events that drive some transition 00513 00514 EventSet eset_usedevents = g1.UsedEvents(); 00515 00516 // get an EventSet containing all the events that do not drive any transition 00517 00518 EventSet eset_unusedevents = g1.UnusedEvents(); 00519 00520 // return the active event set at a given state 00521 00522 EventSet eset_activeeventset = g1.ActiveEventSet(idx_s12); 00523 00524 // return a StateSet containing all the states that are connected by 00525 // some transition 00526 00527 StateSet sset_trel_sspace = g1.TransRelStateSpace(); 00528 00529 // return a StateSet containing all the successor states of a given predecessor 00530 // state. 00531 00532 StateSet sset_successors = g1.TransRelStateSpace(idx_s12); 00533 00534 // note: if you need predecessor states, use a resorted transition relation 00535 00536 ///////////////////////////////// 00537 // Symbolic state name handling 00538 ///////////////////////////////// 00539 00540 // are symbolic state names enabled? depending on this boolean value 00541 // library functions like Determine or StateMin may create symbolic 00542 // state names. 00543 00544 bool bool_statenamesenabled = g1.StateNamesEnabled(); 00545 00546 // disable state name creation in resulting generators for functions in 00547 // the faudes library, that support this feature (nearly all) with 00548 // "false"; enable state name creation with "true". 00549 00550 g1.StateNamesEnabled(true); // anyway .. true is the default value 00551 00552 // clear existing symbolic statenames for states in the Generator 00553 00554 // g1.ClearStateNames(); 00555 00556 // set symbolic names for all states in the generator. the symbolic name becomes 00557 // the equivalent string representation of the state's integer index. This is 00558 // only usefull for debugging purposes. 00559 00560 g1.SetDefaultStateNames(); 00561 00562 00563 // show effect on console 00564 00565 std::cout << "################################\n"; 00566 std::cout << "# tutorial, default names \n"; 00567 g1.Write(); 00568 std::cout << "################################\n"; 00569 00570 00571 /////////////////////////////////// 00572 // Accessible, Coaccessible, Complete, Trim 00573 /////////////////////////////////// 00574 00575 // read example generator for reachability analysis 00576 Generator greach("data/trimness_nottrim.gen"); 00577 00578 std::cout << "################################\n"; 00579 std::cout << "# tutorial, reachability test case \n"; 00580 greach.Write(); 00581 std::cout << "# tutorial, reachability relevant sets \n"; 00582 greach.States().Write(); 00583 greach.AccessibleSet().Write(); 00584 greach.CoaccessibleSet().Write(); 00585 greach.TerminalStates().Write(); 00586 std::cout << "# tutorial, reachability analysis \n"; 00587 if(greach.IsAccessible()) 00588 std::cout << "accesibility: ok\n"; 00589 else 00590 std::cout << "accesibility: failed\n"; 00591 if(greach.IsCoaccessible()) 00592 std::cout << "coaccesibility: ok\n"; 00593 else 00594 std::cout << "coaccesibility: failed\n"; 00595 if(greach.IsComplete()) 00596 std::cout << "completeness: ok\n"; 00597 else 00598 std::cout << "completeness: failed\n"; 00599 if(greach.IsTrim()) 00600 std::cout << "trimness: ok\n"; 00601 else 00602 std::cout << "trimness: failed\n"; 00603 if(greach.IsOmegaTrim()) 00604 std::cout << "omega-trimness: ok\n"; 00605 else 00606 std::cout << "omega-trimness: failed\n"; 00607 std::cout << "################################\n"; 00608 00609 00610 // Make the Generator accessible by removing transitions and states. 00611 // The routine returns true if the generator has an initial state. 00612 Generator gaccess(greach); 00613 gaccess.Name("GAccessible"); 00614 bool bool_hasinit = gaccess.Accessible(); 00615 00616 // Make the Generator coaccessible by removing transitions and states. 00617 // The routine returns true if the generator has a marked state. 00618 Generator gcoaccess(greach); 00619 gcoaccess.Name("GCoccessible"); 00620 bool bool_hasmarked = gcoaccess.Coaccessible(); 00621 00622 // Make the Generator complete by removing transitions and states. 00623 // The routine returns true if the generator has an initial state. 00624 Generator gcompl(greach); 00625 gcompl.Name("GComplete"); 00626 gcompl.Complete(); 00627 00628 // Make the Generator trim by removing transitions and states. 00629 // The routine returns true if the generator has an initial state 00630 // and a marked state. 00631 Generator gtrim(greach); 00632 gtrim.Name("GTrim"); 00633 bool bool_isnontrivial = gtrim.Trim(); 00634 00635 // Make the Generator omega-trim by removing transitions and states. 00636 // The routine returns true if the generator has an initial state 00637 // and a marked state. 00638 Generator gotrim(greach); 00639 gotrim.Name("GOmegaTrim"); 00640 gotrim.OmegaTrim(); 00641 00642 // show effect on console 00643 std::cout << "################################\n"; 00644 std::cout << "# tutorial, reachability results \n"; 00645 gaccess.Write(); 00646 gcoaccess.Write(); 00647 gcompl.Write(); 00648 gtrim.Write(); 00649 gotrim.Write(); 00650 std::cout << "################################\n"; 00651 00652 // contribute to html docu 00653 greach.Write("tmp_greach.gen"); 00654 gaccess.Write("tmp_gaccess.gen"); 00655 gcoaccess.Write("tmp_gcoaccess.gen"); 00656 gcompl.Write("tmp_gcompl.gen"); 00657 gtrim.Write("tmp_gtrim.gen"); 00658 gotrim.Write("tmp_gotrim.gen"); 00659 00660 // Test protocol 00661 FAUDES_TEST_DUMP("accessible",gaccess); 00662 FAUDES_TEST_DUMP("coaccessible",gcoaccess); 00663 FAUDES_TEST_DUMP("complete",gcompl); 00664 FAUDES_TEST_DUMP("trim",gtrim); 00665 FAUDES_TEST_DUMP("omega trim",gotrim); 00666 00667 return 0; 00668 } 00669 00670 00671 |
libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3