2_containers.cpp

Go to the documentation of this file.
00001 /** @file 2_containers.cpp 
00002 
00003 Tutorial, container classes. This tutorial demonstrates
00004 how to use the faudes::EventSet and faudes::StateSet containers.
00005 
00006 The EventSet class consists of an internal sorted set of unique elements
00007 of integer type faudes::Idx. Events are required to have
00008 globally unique names. For event name resolution, the EventSet holds a 
00009 pointer to a (static) SymbolTable object. File IO is via event names
00010 as opposed to event indices. EventSets are seen as selfcontained.
00011 
00012 The StateSet class consists of an internal sorted set of unique elements
00013 of integer type faudes::Idx. StateSets  do *NOT* provide state names
00014 and file IO is via indices only. (Note: generators provide states names,
00015 so you may prefer generator methods for file IO)
00016 
00017 @ingroup Tutorials 
00018 
00019 @include 2_containers.cpp
00020 */
00021 
00022 
00023 
00024 #include "libfaudes.h"
00025 
00026 
00027 using namespace faudes;
00028 
00029 
00030 
00031 int main() {
00032 
00033   ////////////////////////////////////////////////////
00034   // EventSets
00035   ////////////////////////////////////////////////////
00036 
00037   // Create EventSet objects  
00038   EventSet alphabet1;
00039   EventSet alphabet2;
00040   EventSet alphabet3;
00041 
00042   // Set names
00043   alphabet1.Name("A1");
00044   alphabet2.Name("A2");
00045   alphabet3.Name("A3");
00046 
00047   // New events can be inserted by calling the Insert method
00048   // with a symbolic name. If the symbolic name is not kown, it is assigned
00049   // the next free index in the static EventSymbolTable. It any case,
00050   // Insert returns the index inserted to the set.
00051   Idx ev1 = alphabet1.Insert("a");
00052   Idx ev2 = alphabet1.Insert("b");
00053   Idx ev3 = alphabet1.Insert("c");
00054   Idx ev4 = alphabet1.Insert("d");
00055   Idx ev5 = alphabet2.Insert("c"); // ev3 == ev5
00056   Idx ev6 = alphabet2.Insert("d"); // ev4 == ev6
00057   Idx ev7 = alphabet2.Insert("e");
00058   Idx ev8 = alphabet2.Insert("f");
00059   Idx ev9 = alphabet2.Insert("g");
00060 
00061   // The event index can be used to refer to existing events. This avoids
00062   // name lookup.
00063   alphabet3.Insert(ev1); // "a"
00064   alphabet3.Insert(ev7); // "e"
00065   alphabet3.Insert(ev8); // "f"
00066  
00067   // Report to console
00068   std::cout << "################################\n";
00069   std::cout << "# tutorial, alphabets A1,A2 and A3 \n";
00070   alphabet1.DWrite();
00071   alphabet2.DWrite();
00072   alphabet3.DWrite();
00073   std::cout << "################################\n";
00074 
00075 
00076   // Iterator usage
00077   EventSet::Iterator eit;
00078   std::cout << "################################\n";
00079   std::cout << "# tutorial, iterators \n";
00080   for (eit = alphabet1.Begin(); eit != alphabet1.End(); eit++) {
00081     std::cout << alphabet1.SymbolicName(*eit) << ": " << *eit << std::endl;
00082   }
00083   std::cout << "################################\n";
00084 
00085 
00086   // Read an alphabet from generator file
00087   alphabet3.Read("data/simplemachine.gen", "Alphabet");
00088 
00089   // Read an alphabet from file at object construction
00090   EventSet alphabet4("data/simplemachine.gen", "Alphabet");
00091 
00092   // Write a alphabet to file
00093   alphabet2.Write("tmp_alphabet.txt");
00094 
00095   // Report
00096   std::cout << "################################\n";
00097   std::cout << "# tutorial, alphabets of simple machine  \n";
00098   alphabet4.DWrite();
00099   std::cout << "################################\n";
00100 
00101 
00102   // Set inclusion by overloaded <= operator
00103   if(alphabet1 <= alphabet2) {
00104     std::cout << "################################\n";
00105     std::cout << "alphabet1 includes alphabet2" << std::endl;
00106     std::cout << "################################\n";
00107   }
00108   else {
00109     std::cout << "################################\n";
00110     std::cout << "alphabet1 does not include alphabet2" << std::endl;
00111     std::cout << "################################\n";
00112   }
00113   
00114   // Delete an event by name
00115   alphabet2.Erase("e");
00116 
00117   // Delete an event by index
00118   alphabet2.Erase(alphabet2.Index("f"));
00119 
00120   // Clear an eventset
00121   alphabet4.Clear();
00122 
00123   // Test existence of event
00124   if (alphabet2.Exists("d")) {
00125     std::cout << "alphabet2: event d exists" << std::endl;
00126   }
00127 
00128 
00129   // Report
00130   std::cout << "################################\n";
00131   std::cout << "# tutorial, updated alphabets 1 and 2  \n";
00132   alphabet1.DWrite();
00133   alphabet2.DWrite();
00134   std::cout << "################################\n";
00135 
00136 
00137   // Set difference
00138   EventSet adifference = alphabet1 - alphabet2;
00139   std::cout << "################################\n";
00140   std::cout << "set difference: " << adifference.ToString() << std::endl;
00141   std::cout << "################################\n";
00142 
00143 
00144   // Set union
00145   EventSet aunion = alphabet1 + alphabet2;
00146   std::cout << "################################\n";
00147   std::cout << "set union: " << aunion.ToString() << std::endl;
00148   std::cout << "################################\n";
00149 
00150   // Set intersection
00151   EventSet aintersection = alphabet1 * alphabet2;
00152   std::cout << "################################\n";
00153   std::cout << "set intersection: " << aintersection.ToString() << std::endl;
00154   std::cout << "################################\n";
00155 
00156   // Test protocol
00157   FAUDES_TEST_DUMP("set difference",adifference);
00158   FAUDES_TEST_DUMP("set union",aunion);
00159   FAUDES_TEST_DUMP("set intersection",aintersection);
00160 
00161 
00162   ////////////////////////////////////////////////////
00163   // StateSets
00164   ////////////////////////////////////////////////////
00165 
00166 
00167   std::cout << "################################\n";
00168   std::cout << "# tutorial, state sets \n";
00169 
00170   // Create a StateSet
00171   StateSet stateset1;
00172 
00173   // Introduce states
00174   Idx state1 = stateset1.Insert(47);
00175   Idx state2 = stateset1.Insert(11);
00176   Idx state3 = stateset1.Insert();    // becomes 48
00177 
00178   // Introduce more states
00179   for(int i=0; i<25; i++) stateset1.Insert(); // becomes 49 ... 73
00180   Idx state4 = stateset1.Insert(100);
00181 
00182   // Iterator usage 
00183   StateSet::Iterator sit;
00184   std::cout << "stateset1: ";
00185   for (sit = stateset1.Begin(); sit != stateset1.End(); ++sit) {
00186     std::cout << stateset1.Str(*sit) << " ";
00187   }
00188   std::cout << std::endl;
00189 
00190   // Print as string (using file format)
00191   std::cout << "stateset1: " << stateset1.ToString() << std::endl;
00192   
00193   // Write a stateset to file (section defaults to "IndexSet")
00194   stateset1.Write("tmp_stateset.txt");
00195 
00196   // Read back from file (section defaults to "current begin token")
00197   StateSet stateset2;
00198   stateset2.Read("tmp_stateset.txt");
00199 
00200   // Debug output to console
00201   stateset2.Write();
00202 
00203   // Delete a state by index
00204   stateset2.Erase(state2);
00205 
00206   // Copy a StateSet
00207   StateSet stateset3 = stateset1;
00208 
00209   // Clear a StateSet
00210   stateset1.Clear();
00211 
00212   // Test existence of state
00213   if (stateset3.Exists(state1)) {
00214     std::cout << "stateset3: state " << state1 << " exists" << std::endl;
00215   }
00216 
00217   std::cout << "################################\n\n";
00218 
00219 
00220   ////////////////////////////////////////////////////
00221   // advanced topic: attributed sets
00222   ////////////////////////////////////////////////////
00223 
00224        
00225   std::cout << "################################\n";
00226   std::cout << "# tutorial, attributes \n";
00227 
00228   // Convenience type definition for states with flag attribute (see attributes.h)
00229   typedef TaStateSet<AttributeFlags> FStateSet;
00230 
00231   // Construct from a file (read attributes if specified)
00232   FStateSet fstateset1("tmp_stateset.txt");
00233 
00234   // Construct from stateset with no attributes
00235   FStateSet fstateset3(stateset3);
00236 
00237   // Report
00238   std::cout << "fstateset3: " << fstateset3.ToString() << std::endl;
00239   
00240   // Manipulate attribute by state index (this requires the state to exist)
00241   fstateset3.Attributep(60)->Set(0xff);
00242 
00243   // Insert new state with attribute
00244   AttributeFlags fattr;
00245   fattr.Set(0x55);
00246   Idx fstate = fstateset3.Insert(fattr);
00247 
00248   // Report
00249   std::cout << "fstateset3: attribute of state 60: " 
00250             << fstateset3.Attribute(60).ToString() << std::endl;
00251   std::cout << "fstateset3: attribute of state " << fstate 
00252       << ": " << fstateset3.Attribute(fstate).ToString() << std::endl;
00253   std::cout << "fstateset3: " << fstateset3.ToString() << std::endl;
00254 
00255   // Write to file 
00256   fstateset3.Write("tmp_fstateset.txt");  
00257 
00258   // Convert to set without attributes (drop attributes)
00259   stateset3 = fstateset3;
00260 
00261   // Report
00262   std::cout << "stateset3: " << stateset3.ToString() << std::endl;
00263        
00264   // Set comparision ignores attributes
00265   if(stateset3==fstateset3) 
00266     std::cout << "stateset3 indeed equals fstateset3 " << std::endl;
00267 
00268   // Explicit equality test shows
00269   if(!stateset3.EqualAttributes(fstateset3)) 
00270     std::cout << "stateset3 indeed has different attributes as fstateset3 " << std::endl;
00271 
00272   // Provided that actual types match, attributes are copied even when accesssing 
00273   // via non attributed StateSet methods
00274   FStateSet fstateset4;
00275   StateSet& rfstateset3 = fstateset3;
00276   StateSet& rfstateset4 = fstateset4;
00277   rfstateset4 = rfstateset3;
00278 
00279   // Remove a state with no attribute (provoce deep copy)
00280   rfstateset3.Erase(50);
00281     
00282   // Test attribute equality
00283   if(fstateset4.EqualAttributes(fstateset3)) 
00284     std::cout << "fstateset4 indeed has equal attributes with fstateset3 " << std::endl;
00285   if(rfstateset4.EqualAttributes(rfstateset3)) 
00286     std::cout << "rfstateset4 indeed has equal attributes with rfstateset3 " << std::endl;
00287 
00288   // Report
00289   std::cout << "fstateset4: " << fstateset4.ToString() << std::endl;
00290   std::cout << "################################\n\n";
00291 
00292   // Test protocol
00293   FAUDES_TEST_DUMP("attrbibutes eq0", stateset3 == fstateset3);
00294   FAUDES_TEST_DUMP("attrbibutes eq1", stateset3.EqualAttributes(fstateset3));
00295   FAUDES_TEST_DUMP("attrbibutes eq2", fstateset4.EqualAttributes(fstateset3));
00296   FAUDES_TEST_DUMP("attrbibutes eq3", rfstateset4.EqualAttributes(rfstateset3));
00297 
00298 
00299   ////////////////////////////////////////////////////
00300   // Vectors
00301   ////////////////////////////////////////////////////
00302 
00303   std::cout << "################################\n";
00304   std::cout << "# tutorial, vectors \n";
00305 
00306   // Have a vector of event sets
00307   EventSetVector alphvect;
00308 
00309   // Populate the vector (take copies)
00310   alphvect.PushBack(alphabet1);
00311   alphvect.PushBack(alphabet2);
00312   alphvect.PushBack(alphabet3);
00313  
00314   // Access entries
00315   std::cout << "# event set no 1 (counting from 0):\n";
00316   alphvect.At(1).Write();
00317   
00318   // Manipulate entries
00319   alphvect.At(1).Insert("delta_1");
00320 
00321   // Report
00322   std::cout << "# all three event sets:\n";
00323   alphvect.Write();
00324 
00325   // Set filenames for convenient token io
00326   alphvect.FilenameAt(0,"tmp_alph0.txt");
00327   alphvect.FilenameAt(1,"tmp_alph1.txt");
00328   alphvect.FilenameAt(2,"tmp_alph2.txt");
00329   alphvect.Write("tmp_alphvect.txt");
00330 
00331 
00332   // query, whether the vector can take an element
00333   System cgen;
00334   bool vcast = alphvect.ElementTry(cgen);
00335   if(vcast) 
00336     std::cout << "# EventSetVector can take Generator elements [fail]\n";
00337   else
00338     std::cout << "# EventSetVector cannot take Generator elements [expected]\n";
00339 
00340   // record
00341   FAUDES_TEST_DUMP("vect element cast",vcast);
00342 
00343 
00344   // Done
00345   std::cout << "################################\n";
00346 
00347 
00348   ////////////////////////////////////////////////////
00349   // Developper internal: deferred copy stress test
00350   ////////////////////////////////////////////////////
00351 
00352 
00353   std::cout << "################################\n";
00354   std::cout << "# tutorial, deferred copy stress test \n";
00355 
00356   // Create state set {1,2,...44}
00357   StateSet setA;
00358   for(Idx state=1; state<45; state++) {
00359     setA.Insert(state);
00360   }
00361   setA.Write();
00362 
00363   // Have a deferred copy
00364   StateSet setB=setA;
00365 
00366   // Test protocol
00367   FAUDES_TEST_DUMP("deferred copy A",setA);
00368   FAUDES_TEST_DUMP("deferred copy B",setB);
00369 
00370   // Collect iterators
00371   std::vector<StateSet::Iterator> edIts;
00372 
00373   // Investigate deferred copy setB
00374   StateSet::Iterator cit=setB.Begin(); 
00375   for(;cit!=setB.End(); cit++) {
00376     if(*cit % 5 !=0) continue;
00377     edIts.push_back(cit);
00378   } 
00379   
00380   // Test protocol
00381   FAUDES_TEST_DUMP("deferred copy A - 2",setA);
00382   FAUDES_TEST_DUMP("deferred copy B - 2",setB);
00383 
00384   // setB should share with setA and have quite some iterators
00385   setB.DWrite();
00386 
00387   // Trigger detach and lock set B
00388   setB.Lock();
00389 
00390   // Further investigate true copy of setB
00391   cit=setB.Begin(); 
00392   for(;cit!=setB.End(); cit++) {
00393     if(*cit % 5 ==0) continue;
00394     if(*cit % 2 !=0) continue;
00395     edIts.push_back(cit);
00396   } 
00397   
00398   // setB neither shares nor track iterators
00399   setB.DWrite();
00400 
00401   // Have other deferred copy
00402   StateSet setC=setB;
00403 
00404   // Write on the deferred copy to trigger actual copy 
00405   setC.Insert(77);
00406 
00407   // Perform edit on deferred copy
00408   std::vector<StateSet::Iterator>::iterator iit=edIts.begin();
00409   for(;iit!=edIts.end(); iit++) {
00410     Idx oldstate = **iit;
00411     setC.Erase(oldstate); 
00412     setC.Insert(100+oldstate); 
00413   }
00414      
00415   // setB should not share and still dont track any iterators
00416   setB.Write();
00417   setB.DWrite();
00418   std::cout << "################################\n";
00419      
00420   // Test protocol
00421   FAUDES_TEST_DUMP("deferred copy A - 3",setA);
00422   FAUDES_TEST_DUMP("deferred copy B - 3",setB);
00423   FAUDES_TEST_DUMP("deferred copy C - 3",setC);
00424 
00425   ////////////////////////////////////////////////////
00426   // Developper internal: memory leak in BaseSet
00427   ////////////////////////////////////////////////////
00428 
00429   /*
00430   EventSet evs2;
00431   Generator gsm2;
00432   evs2.Insert("alpha");
00433   Generator gsm("data/simplemachine.gen");
00434   for(int i=0;i<2000000;i++) {
00435   for(int j=0;j<20000;j++) {
00436     gsm.IsCoaccessible();
00437     Deterministic(gsm,gsm2);
00438     Project(gsm,evs2,gsm2);
00439   }
00440   }
00441   */
00442 
00443   return 0;
00444 }

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen