1_generator.cpp File Reference


Detailed Description

Tutorial, basic faudes::Generator methods.

The Generator class implements the 5-tuple automaton G, consisting of

This tutorial demonstrates how to insert/erase states, events and transitions. It also demonstrates file IO.

#include "libfaudes.h"

// make the faudes namespace available to our program
using namespace faudes;



// main program

int main() {

  // Constructors (part 1) and filling example

  // at first we create an empty Generator object

  Generator g1;

  // do some random "user interaction" stuff with the Generator g1

  g1.InsState("s1");  
  g1.InsState("s2");                  
  g1.InsState("s3");                  

  g1.InsEvent("a");         
  g1.InsEvent("b");

  g1.SetTransition("s1", "a", "s2");  
  g1.SetTransition("s2", "a", "s3");  
  g1.SetTransition("s3", "b", "s1");

  g1.SetInitState("s1");              
  g1.SetMarkedState("s2");
  g1.SetMarkedState("s3");

  // inspect result on console

  std::cout << "################################\n";
  std::cout << "# tutorial, handcraft generator \n";
  g1.Write();
  std::cout << "################################\n";



  // Constructors (part 2) & Copying and versioning

  // Create a  1:1 copy of the Generator with the copy constructor. 

  Generator g_copy(g1);

  // ... with copy method, or the assignement operator

  Generator g2;
  g1.Copy(g2);
  Generator g3=g2;

  // create a Generator copy with versioned events (for testing algorithms):
  // versioning by an integer. E.g. for integer 3 events {"a", "b", "c"}
  // become {"a_3", "b_3", "c_3"}.

  Generator version1;
  g1.Version(3, version1);

  // versioning by a string. "a" -> "a_versionstring"

  Generator version2;
  g1.Version("str", version2);

  // inspect result on console

  std::cout << "################################\n";
  std::cout << "# tutorial, version of generator \n";
  version2.Write();
  std::cout << "################################\n";



  // Methods for Input/Output

  // read a Generator from file 

  g2.Read("data/simplemachine.gen");

  // create a Generator by reading a Generator file

  Generator g4("data/simplemachine.gen");


  // write a Generator to file 
  // (map state indices to begin with 1)

  g4.Write("tmp_simplemachine.gen");

  // write a Generator to file by appending the output 
  // (map state indeces to begin with 1)

  g4.Write("tmp_simplemachine.gen", std::ios::out|std::ios::app);

  // debug output of Generator to console 
  // (use actual state indices)

  std::cout << "################################\n";
  std::cout << "# tutorial, debug dump \n";
  g4.DWrite();
  std::cout << "################################\n";

  // create dotfile for further processing by graphviz 
  // (map state indices to begin with 1)

  g4.DotWrite("tmp_simplemachine.dot"); 
  g4.DDotWrite("tmp_simplemachine_debug.dot");

  // there also is a convenience method, that runs graphviz to
  // generate graphical output; requires  "dot" binary in $PATH
  try {
    g4.GraphWrite("tmp_simplemachin.png");
  } catch(faudes::Exception& exception) {
    std::cout << "1_generator: cannot execute graphviz' dot. " << std::endl;
  } 


  // create a debug string for an event with symbolic name + index

  std::string str_singleevent = g1.EStr(2);

  // create a debug string for a state with symbolic name + index.
  // If there is no symblic name, a symbolic name of the index is constructed.

  std::string str_singlestate = g1.SStr(3);

  // build string of events in the Generator's alphabet

  std::string str_alph =  g1.AlphabetToString();

  // build string of states in the Generator's set of states
  std::string str_states = g1.StatesToString();

  // there also are TransRelToString(), InitStatesToString() and  MarkedStatesToString()  


  // Accessing the Generator's Members

  // get the Generator's name

  std::string str_name = g1.Name();

  // set new name for Generator

  g1.Name("NewName");

  // retrieve the unique id of the Generator (statically counted)

  Idx genid = g1.Id();


  // the core members alphabet, stateset and transitionrelation may be retrieved 
  // as const references; ie. they can be inspected freely, but write access is 
  // exclusively via the provided Generator methods.

  // retrieve a const reference to and copy of the Generator's alphabet

  const EventSet&  eset_ref_alph  = g1.Alphabet();
  EventSet         eset_copy_alph = g1.Alphabet();

  // you cannot alter the alphabet of a generator via an  alphabet method
  // eset_ref_alph.Insert("new_event");  // compile time error!

  // however, the copy can be altered, but with no effect on the original generator

  eset_copy_alph.Insert("new_event"); 
  if(g1.ExistsEvent("new_event")) std::cout << "### THIS CANNOT HAPPEN ###";

  // retrieve a const reference to and copy of the Generator's set of states "mStates"

  const StateSet& sset_ref_states = g1.States();
  StateSet sset_copy_states = g1.States();

  // retrieve a const reference to and a copy of the Generator's transition relation "mTransRel"

  const TransSet& tset_ref_trel = g1.TransRel();
  TransSet tset_copy_trel = g1.TransRel();

  // same with initial states and marked states

  const StateSet& sset_ref_istates = g1.InitStates();
  StateSet sset_copy_istates = g1.InitStates();

  const StateSet& sset_ref_mstates = g1.MarkedStates();
  StateSet sset_copy_mstates = g1.MarkedStates();



  // Modifying the 5-tuple Generator (X, Sigma, Delta, X0 and Xm)

  // insert an event by it's symbolic name in the alphabet
  // (if the event is not known so far, a new index for the symbolic name is generated) 
  g1.InsEvent("newevent");


  // insert an existing event into the Generator's alphabet (mAlphabet)
  // (by "existing event" we refer to an event that has been previously inserted to some Generator)

  g1.InsEvent(1);   // of course index 1 is already in the alphabet here...

  // insert a bunch of events (EventSet) and get the integer index if requested

  EventSet eset1;
  eset1.Insert("newevent1");
  Idx idx_tmp = eset1.Insert("newevent2");
  g1.InsEvents(eset1);

  // delete an event from Generator ie delete from alphabet and transition relation

  g1.DelEvent("newevent1"); // by symbolic name
  g1.DelEvent(idx_tmp);     // by index

  // delete a bunch of events
  // g1.DelEvents(eset1); // .. of course we have already deleted them before...

  // insert a new state. The state gets a integer index that is unique within
  // the Generator

  idx_tmp = g1.InsState();            // anonymous state
  idx_tmp = g1.InsState("newstate2"); // named state

  // insert a new state as initial state

  idx_tmp = g1.InsInitState();
  idx_tmp = g1.InsInitState("newinitstate");

  // ... same for marked states

  idx_tmp = g1.InsMarkedState();
  idx_tmp = g1.InsMarkedState("newmarkedstate");


  // delete single states from Generator ie stateset and transitionrelation

  g1.DelState(idx_tmp); // by index (relatively fast, for algorithms)
  g1.DelState("newinitstate"); // by symbolic name, if name assigned

  // delete a bunch of states 
  // (this should be more efficient than deleting states individually)

  StateSet stateset1;
  stateset1.Insert(1);
  stateset1.Insert(2);
  stateset1.Insert(3);
  g1.DelStates(stateset1);

  // for further proceeding we insert some new states and events...

  Idx idx_s10 = g1.InsState("s10");
  Idx idx_s11 = g1.InsState("s11");
  Idx idx_s12 = g1.InsState("s12");
  Idx idx_e10 = g1.InsEvent("e10");
  Idx idx_e11 = g1.InsEvent("e11");

  // set a state that already exists in Generator as initial state

  g1.SetInitState(idx_s10);

  // set a state that already exists in Generator as marked state

  g1.SetMarkedState(idx_s11);

  // unset an existing state as initial state (does not remove from mStates)

  g1.ClrInitState(idx_s10); 

  // unset an existing state as marked state (does not remove from stateset)

  g1.ClrMarkedState(idx_s10); 

  // clear all initial states (does not remove from stateset)

  //   g1.ClrInitStates();  // we do not really do it here, so it's commented

  // clear all marked states (mStates stays untouched)

  //   g1.ClrMarkedStates();  // we do not really do it here, so it's commented

  // set a transition for existing states and events

  g1.SetTransition(idx_s10, idx_e10, idx_s11); // by indices
  g1.SetTransition("s10", "e11", "s10"); // by symbolic names (slow)


  // report back to console

  std::cout << "################################\n";
  std::cout << "# tutorial, on the way \n";
  g1.DWrite();
  std::cout << "################################\n";


  // clear a transition (does not touch mStates, mInitStates and mMarkedStates)

  g1.ClrTransition(idx_s10, idx_e10, idx_s11); // by index

  // transitions can also be cleared by names (slower) or by an assigned
  // TransSet::Iterator (faster); use ClearTransRel() to remove all transitions


  // clear the symbolic name for a state in the StateSymbolTable

  g1.ClrStateName(idx_s10); 

  // exists event index/name in mAlphabet?

  bool bool_eventexists1 = g1.ExistsEvent("e11"); 
  bool bool_eventexists2 = g1.ExistsEvent(2); 


  // exists state in mStates?

  bool bool_stateexists1 = g1.ExistsState(4); 


  // check if a state is an initial state

  bool bool_initstateexists = g1.ExistsInitState(4); 

  // check if a state is a marked state

  bool bool_ismarkedstate = g1.ExistsMarkedState(4); 

  // look up event name for index in the EventSymbolTable of the event domain

  std::string str_eventname1 = g1.EventName(1);

  // look up event index for name in the EventSymbolTable of the event domain

  Idx idx_eventindex = g1.EventIndex("e11");

  // get symbolic name assigned to state (returns "" if no name assigned).

  std::string str_tmp = g1.StateName(idx_s10);

  // get index for symbolic state name. only possible for state names of states in
  // the Generator 

  idx_tmp = g1.StateIndex("s12");

  // clear Generator (including alphabet)

  g4.Clear();

  // get the number of events in the Generator's alphabet

  Idx idx_eventnum = g1.AlphabetSize();

  // get the number of states

  Idx idx_statenum = g1.Size();

  // get the number of transitions

  Idx idx_transnum = g1.TransRelSize();

  // there also are InitStatesSize(), MarkedStatesSize()

  // is the alphabet of the Generator empty?

  bool bool_alphempty = g1.AlphabetEmpty();

  // is the Generator empty (number of states == 0) ?

  bool bool_isempty = g1.Empty();

  // see also TransRelEmpty, InitStatesEmpty, MarkedStatesEmpty


  // insert a small loop 

  Idx initstate = g1.InsInitState("in");
  Idx markedstate = g1.InsMarkedState("out");
  g1.SetTransition("in","a","out");
  g1.SetTransition("out","a","in");


  // show effect on console 

  std::cout << "################################\n";
  std::cout << "# tutorial, after ins and del \n";
  g1.DWrite();
  std::cout << "################################\n";


  // Iterators

  // since the core members are all implemented as sets, iterators
  // effectively are cont_iterators, i.e. you cannot change the 
  // current value of an iterator. instead you may remove the value 
  // and insert the new value.

  // iteration over alphabet indices (member "mAlphabet")

  std::cout << "################################\n";
  std::cout << "# tutorial, iterators 1         \n";
  EventSet::Iterator eit;
  for (eit = g1.AlphabetBegin(); eit != g1.AlphabetEnd(); ++eit) {
    std::cout << "event \"" << g1.EventName(*eit) << "\" with index "<< *eit << std::endl;
  }
  std::cout << "################################\n";

  // iteration over state indices (member "mStates")

  std::cout << "################################\n";
  std::cout << "# tutorial, iterators 2         \n";
  StateSet::Iterator sit;
  for (sit = g1.StatesBegin(); sit != g1.StatesEnd(); ++sit) {
    std::cout << *sit << std::endl;
  }
  std::cout << "################################\n";

  // iteration over complete transition relation (member "mTransRel")

  std::cout << "################################\n";
  std::cout << "# tutorial, iterators 3         \n";
  TransSet::Iterator tit;
  for (tit = g1.TransRelBegin(); tit != g1.TransRelEnd(); ++tit) {
    std::cout << g1.TStr(*tit) << std::endl;
  }
  std::cout << "################################\n";

  // iteration over transitions from a given state; note that we avoid
  // computation of the end of the iteration in every step

  std::cout << "################################\n";
  std::cout << "# tutorial, iterators 4         \n";
  idx_tmp = g1.StateIndex("s1");
  TransSet::Iterator tit_end;
  tit = g1.TransRelBegin(idx_tmp);
  tit_end = g1.TransRelEnd(idx_tmp);
  for (; tit != tit_end; ++tit) {
    std::cout << g1.TStr(*tit) << std::endl;
  }
  std::cout << "################################\n";

  // variations: transitions of given state index + given event index:
  // TransRelBegin(x1, ev) - TransRelEnd(x1, ev)

  // iteration over initial and marked states:
  // InitStatesBegin() - InitStatesEnd()  (member "mInitStates")
  // MarkedStatesBegin() - MarkedStatesEnd() (member "mMarkedStates")


  // retrieve copies of the Generator's transition releation
  // in different sorting orders than X1 -> Ev -> X2

  // note: the availabity of iterator ranges depends on the sorting order;
  // eg iteration with specified x2 requires X2->Ev->X1 or X2->X1->Ev sorting.

  // retrieve a copy that is sorted by X2 -> Ev -> X1 by the binary
  // predicate TransSort::X2EvX1. 
  
  TransSetX2EvX1 tset_x2evx1;
  g1.TransRel(tset_x2evx1);

  // report to console

  std::cout << "################################\n";
  std::cout << "# tutorial, x2-ev-x1 sorting\n";
  TransSetX2EvX1::Iterator tit2;
  for (tit2 = tset_x2evx1.Begin(); tit2 != tset_x2evx1.End(); ++tit2) {
    std::cout << g1.TStr(*tit2) << std::endl;
  }
  std::cout << "################################\n";



  // Convenience Methods

  // remove all events from mAlphabet, that do not have a transition in
  // mTransRel:  g1.MinimizeAlphabet()

  // get an EventSet containing all the events that drive some transition 

  EventSet eset_usedevents = g1.UsedEvents();

  // get an EventSet containing all the events that do not drive any transition

  EventSet eset_unusedevents = g1.UnusedEvents();

  // return the active event set at a given state 

  EventSet eset_activeeventset = g1.ActiveEventSet(idx_s12);

  // return a StateSet containing all the states that are connected by
  // some transition 

  StateSet sset_trel_sspace = g1.TransRelStateSpace();

  // return a StateSet containing all the successor states of a given predecessor
  // state.

  StateSet sset_successors = g1.TransRelStateSpace(idx_s12);

  // note: if you need predecessor states, use a resorted transition relation

  // Symbolic state name handling

  // are symbolic state names enabled? depending on this boolean value
  // library functions like Determine or StateMin may create symbolic
  // state names.

  bool bool_statenamesenabled = g1.StateNamesEnabled();

  // disable state name creation in resulting generators for functions in
  // the faudes library, that support this feature (nearly all) with
  // "false"; enable state name creation with "true".

  g1.StateNamesEnabled(true); // anyway .. true is the default value

  // clear existing symbolic statenames for states in the Generator

  // g1.ClearStateNames(); 

  // set symbolic names for all states in the generator. the symbolic name becomes
  // the equivalent string representation of the state's integer index. This is
  // only usefull for debugging purposes.

  g1.SetDefaultStateNames();


  // show effect on console 

  std::cout << "################################\n";
  std::cout << "# tutorial, default names \n";
  g1.Write();
  std::cout << "################################\n";


  // Accessible, Coaccessible, Trim

  // StateSet containing all accessible states

  std::cout << "################################\n";
  std::cout << "# tutorial, accessible  \n";
  StateSet sset_accessibleset = g1.AccessibleSet();
  sset_accessibleset.Write();
  std::cout << "################################\n";


  // Make the Generator accessible by removing transitions and states. If
  // the Generator containes at least one initial state the Generator
  // can be made accessible and the return value is "true", else "false".

  bool bool_isaccessiblenow = g1.Accessible();

  // Is the Generator accessible. (No modification of the Generator)

  bool bool_isaccessible = g1.IsAccessible();

  // StateSet containing all coaccessible states

  std::cout << "################################\n";
  std::cout << "# tutorial, coaccessible \n";
  StateSet sset_coaccessibleset = g1.CoaccessibleSet();
  sset_coaccessibleset.Write();
  std::cout << "################################\n";

  // make the Generator coaccessible by removing transitions and states; if
  // the Generator containes at least one initial state the Generator
  // can be made coaccessible and the return value is "true", else "false".

  bool bool_iscoaccessiblenow = g1.Coaccessible();

  // is the Generator coaccessible? (No modification of the Generator)

  bool bool_iscoaccessible = g1.IsCoaccessible();

  // StateSet containing all trim states

  StateSet sset_trimset = g1.TrimSet();

  // make the Generator trim by removing transitions and states; if
  // the Generator containes at least one initial state and one marked state
  // the return value is "true", else "false".

  bool bool_istrimnow = g1.Trim();

  // is the Generator trim? (No modification of the Generator)

  bool bool_istrim = g1.IsTrim();

  // show effect on console

  std::cout << "################################\n";
  std::cout << "# tutorial, coaccessible \n";
  g1.Write();
  std::cout << "################################\n";

  return 0;
}



Definition in file 1_generator.cpp.

#include "libfaudes.h"

Go to the source code of this file.

Functions

int main ()
 Run the tutorial.


Function Documentation

int main  ) 
 

Run the tutorial.

Definition at line 33 of file 1_generator.cpp.


Generated on Fri May 9 11:26:47 2008 for libFAUDES 2.09b by  doxygen 1.4.4