libFAUDES

Sections

Index

1_generator.cpp

Go 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