2_containers.cppGo 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 |