2_containers.cpp
Go to the documentation of this file.
1/** @file 2_containers.cpp
2
3Tutorial, container classes. This tutorial demonstrates
4how to use the faudes::EventSet and faudes::StateSet containers.
5
6The EventSet class consists of an internal sorted set of unique elements
7of integer type faudes::Idx. Events are required to have
8globally unique names. For event name resolution, the EventSet holds a
9pointer to a (static) SymbolTable object. File IO is via event names
10as opposed to event indices. EventSets are seen as selfcontained.
11
12The StateSet class consists of an internal sorted set of unique elements
13of integer type faudes::Idx. StateSets do *NOT* provide state names
14and file IO is via indices only. (Note: generators provide states names,
15so you may prefer generator methods for file IO)
16
17@ingroup Tutorials
18
19@include 2_containers.cpp
20*/
21
22
23
24#include "libfaudes.h"
25
26
27using namespace faudes;
28
29
30
31int main() {
32
33 ////////////////////////////////////////////////////
34 // EventSets
35 ////////////////////////////////////////////////////
36
37 // Create EventSet objects
38 EventSet alphabet1;
39 EventSet alphabet2;
40 EventSet alphabet3;
41
42 // Set names
43 alphabet1.Name("A1");
44 alphabet2.Name("A2");
45 alphabet3.Name("A3");
46
47 // New events can be inserted by calling the Insert method
48 // with a symbolic name. If the symbolic name is not kown, it is assigned
49 // the next free index in the static EventSymbolTable. It any case,
50 // Insert returns the index inserted to the set.
51 Idx ev1 = alphabet1.Insert("a");
52 Idx ev2 = alphabet1.Insert("b");
53 Idx ev3 = alphabet1.Insert("c");
54 Idx ev4 = alphabet1.Insert("d");
55 Idx ev5 = alphabet2.Insert("c"); // ev3 == ev5
56 Idx ev6 = alphabet2.Insert("d"); // ev4 == ev6
57 Idx ev7 = alphabet2.Insert("e");
58 Idx ev8 = alphabet2.Insert("f");
59 Idx ev9 = alphabet2.Insert("g");
60
61 // The event index can be used to refer to existing events. This avoids
62 // name lookup.
63 alphabet3.Insert(ev1); // "a"
64 alphabet3.Insert(ev7); // "e"
65 alphabet3.Insert(ev8); // "f"
66
67 // Report to console
68 std::cout << "################################\n";
69 std::cout << "# tutorial, alphabets A1,A2 and A3 \n";
70 alphabet1.DWrite();
71 alphabet2.DWrite();
72 alphabet3.DWrite();
73 std::cout << "################################\n";
74
75
76 // Iterator usage (C++98)
77 EventSet::Iterator eit;
78 std::cout << "################################\n";
79 std::cout << "# tutorial, iterators (classic)\n";
80 for (eit = alphabet1.Begin(); eit != alphabet1.End(); eit++) {
81 std::cout << alphabet1.SymbolicName(*eit) << ": " << *eit << std::endl;
82 }
83 std::cout << "################################\n";
84
85 // Iterator usage (C++11)
86 std::cout << "################################\n";
87 std::cout << "# tutorial, iterators (modern)\n";
88 for (auto ev : alphabet1) {
89 std::cout << alphabet1.SymbolicName(ev) << ": " << ev << std::endl;
90 }
91 std::cout << "################################\n";
92
93
94 // Read an alphabet from generator file
95 alphabet3.Read("data/simplemachine.gen", "Alphabet");
96
97 // Read an alphabet from file at object construction
98 EventSet alphabet4("data/simplemachine.gen", "Alphabet");
99
100 // Write a alphabet to file
101 alphabet2.Write("tmp_alphabet.txt");
102
103 // Report
104 std::cout << "################################\n";
105 std::cout << "# tutorial, alphabets of simple machine \n";
106 alphabet4.DWrite();
107 std::cout << "################################\n";
108
109
110 // Set inclusion by overloaded <= operator
111 if(alphabet1 <= alphabet2) {
112 std::cout << "################################\n";
113 std::cout << "alphabet1 includes alphabet2" << std::endl;
114 std::cout << "################################\n";
115 }
116 else {
117 std::cout << "################################\n";
118 std::cout << "alphabet1 does not include alphabet2" << std::endl;
119 std::cout << "################################\n";
120 }
121
122 // Delete an event by name
123 alphabet2.Erase("e");
124
125 // Delete an event by index
126 alphabet2.Erase(alphabet2.Index("f"));
127
128 // Clear an eventset
129 alphabet4.Clear();
130
131 // Test existence of event
132 if (alphabet2.Exists("d")) {
133 std::cout << "alphabet2: event d exists" << std::endl;
134 }
135
136
137 // Report
138 std::cout << "################################\n";
139 std::cout << "# tutorial, updated alphabets 1 and 2 \n";
140 alphabet1.DWrite();
141 alphabet2.DWrite();
142 std::cout << "################################\n";
143
144
145 // Set difference
146 EventSet adifference = alphabet1 - alphabet2;
147 std::cout << "################################\n";
148 std::cout << "set difference: " << adifference.ToString() << std::endl;
149 std::cout << "################################\n";
150
151
152 // Set union
153 EventSet aunion = alphabet1 + alphabet2;
154 std::cout << "################################\n";
155 std::cout << "set union: " << aunion.ToString() << std::endl;
156 std::cout << "################################\n";
157
158 // Set intersection
159 EventSet aintersection = alphabet1 * alphabet2;
160 std::cout << "################################\n";
161 std::cout << "set intersection: " << aintersection.ToString() << std::endl;
162 std::cout << "################################\n";
163
164 // Test protocol
165 FAUDES_TEST_DUMP("set difference",adifference);
166 FAUDES_TEST_DUMP("set union",aunion);
167 FAUDES_TEST_DUMP("set intersection",aintersection);
168
169
170 ////////////////////////////////////////////////////
171 // StateSets
172 ////////////////////////////////////////////////////
173
174
175 std::cout << "################################\n";
176 std::cout << "# tutorial, state sets \n";
177
178 // Create a StateSet
179 StateSet stateset1;
180
181 // Introduce states
182 Idx state1 = stateset1.Insert(47);
183 Idx state2 = stateset1.Insert(11);
184 Idx state3 = stateset1.Insert(); // becomes 48
185
186 // Introduce more states
187 for(int i=0; i<25; i++) stateset1.Insert(); // becomes 49 ... 73
188 Idx state4 = stateset1.Insert(100);
189
190 // Iterator usage
191 StateSet::Iterator sit;
192 std::cout << "stateset1: ";
193 for (sit = stateset1.Begin(); sit != stateset1.End(); ++sit) {
194 std::cout << stateset1.Str(*sit) << " ";
195 }
196 std::cout << std::endl;
197
198 // Print as string (using file format)
199 std::cout << "stateset1: " << stateset1.ToString() << std::endl;
200
201 // Write a stateset to file (section defaults to "IndexSet")
202 stateset1.Write("tmp_stateset.txt");
203
204 // Read back from file (section defaults to "current begin token")
205 StateSet stateset2;
206 stateset2.Read("tmp_stateset.txt");
207
208 // Debug output to console
209 stateset2.Write();
210
211 // Delete a state by index
212 stateset2.Erase(state2);
213
214 // Copy a StateSet
215 StateSet stateset3 = stateset1;
216
217 // Clear a StateSet
218 stateset1.Clear();
219
220 // Test existence of state
221 if (stateset3.Exists(state1)) {
222 std::cout << "stateset3: state " << state1 << " exists" << std::endl;
223 }
224
225 std::cout << "################################\n\n";
226
227
228 ////////////////////////////////////////////////////
229 // advanced topic: attributed sets
230 ////////////////////////////////////////////////////
231
232
233 std::cout << "################################\n";
234 std::cout << "# tutorial, attributes \n";
235
236 // Convenience type definition for states with flag attribute (see attributes.h)
237 typedef TaStateSet<AttributeFlags> FStateSet;
238
239 // Construct from a file (read attributes if specified)
240 FStateSet fstateset1("tmp_stateset.txt");
241
242 // Construct from stateset with no attributes
243 FStateSet fstateset3(stateset3);
244
245 // Report
246 std::cout << "fstateset3: " << fstateset3.ToString() << std::endl;
247
248 // Manipulate attribute by state index (this requires the state to exist)
249 fstateset3.Attributep(60)->Set(0xff);
250
251 // Insert new state with attribute
252 AttributeFlags fattr;
253 fattr.Set(0x55);
254 Idx fstate = fstateset3.Insert(fattr);
255
256 // Report
257 std::cout << "fstateset3: attribute of state 60: "
258 << fstateset3.Attribute(60).ToString() << std::endl;
259 std::cout << "fstateset3: attribute of state " << fstate
260 << ": " << fstateset3.Attribute(fstate).ToString() << std::endl;
261 std::cout << "fstateset3: " << fstateset3.ToString() << std::endl;
262
263 // Write to file
264 fstateset3.Write("tmp_fstateset.txt");
265
266 // Convert to set without attributes (drop attributes)
267 stateset3 = fstateset3;
268
269 // Report
270 std::cout << "stateset3: " << stateset3.ToString() << std::endl;
271
272 // Set comparision ignores attributes
273 if(stateset3==fstateset3)
274 std::cout << "stateset3 indeed equals fstateset3 " << std::endl;
275
276 // Explicit equality test shows
277 if(!stateset3.EqualAttributes(fstateset3))
278 std::cout << "stateset3 indeed has different attributes as fstateset3 " << std::endl;
279
280 // Provided that actual types match, attributes are copied even when accesssing
281 // via non attributed StateSet methods
282 FStateSet fstateset4;
283 StateSet& rfstateset3 = fstateset3;
284 StateSet& rfstateset4 = fstateset4;
285 rfstateset4 = rfstateset3;
286
287 // Remove a state with no attribute (provoce deep copy)
288 rfstateset3.Erase(50);
289
290 // Test attribute equality
291 if(fstateset4.EqualAttributes(fstateset3))
292 std::cout << "fstateset4 indeed has equal attributes with fstateset3 " << std::endl;
293 if(rfstateset4.EqualAttributes(rfstateset3))
294 std::cout << "rfstateset4 indeed has equal attributes with rfstateset3 " << std::endl;
295
296 // Report
297 std::cout << "fstateset4: " << fstateset4.ToString() << std::endl;
298 std::cout << "################################\n\n";
299
300 // Test protocol
301 FAUDES_TEST_DUMP("attrbibutes eq0", stateset3 == fstateset3);
302 FAUDES_TEST_DUMP("attrbibutes eq1", stateset3.EqualAttributes(fstateset3));
303 FAUDES_TEST_DUMP("attrbibutes eq2", fstateset4.EqualAttributes(fstateset3));
304 FAUDES_TEST_DUMP("attrbibutes eq3", rfstateset4.EqualAttributes(rfstateset3));
305
306
307 ////////////////////////////////////////////////////
308 // Vectors
309 ////////////////////////////////////////////////////
310
311 std::cout << "################################\n";
312 std::cout << "# tutorial, vectors \n";
313
314 // Have a vector of event sets
315 EventSetVector alphvect;
316
317 // Populate the vector (take copies)
318 alphvect.PushBack(alphabet1);
319 alphvect.PushBack(alphabet2);
320 alphvect.PushBack(alphabet3);
321
322 // Access entries
323 std::cout << "# event set no 1 (counting from 0):\n";
324 alphvect.At(1).Write();
325
326 // Manipulate entries
327 alphvect.At(1).Insert("delta_1");
328
329 // Report
330 std::cout << "# all three event sets:\n";
331 alphvect.Write();
332
333 // Set filenames for convenient token io
334 alphvect.FilenameAt(0,"tmp_alph0.txt");
335 alphvect.FilenameAt(1,"tmp_alph1.txt");
336 alphvect.FilenameAt(2,"tmp_alph2.txt");
337 alphvect.Write("tmp_alphvect.txt");
338
339
340 // query, whether the vector can take an element
341 System cgen;
342 bool vcast = alphvect.ElementTry(cgen);
343 if(vcast)
344 std::cout << "# EventSetVector can take Generator elements [fail]\n";
345 else
346 std::cout << "# EventSetVector cannot take Generator elements [expected]\n";
347
348 // record
349 FAUDES_TEST_DUMP("vect element cast",vcast);
350
351
352 // Done
353 std::cout << "################################\n";
354
355
356 ////////////////////////////////////////////////////
357 // Developper internal: deferred copy stress test
358 ////////////////////////////////////////////////////
359
360
361 std::cout << "################################\n";
362 std::cout << "# tutorial, deferred copy stress test \n";
363
364 // Create state set {1,2,...44}
365 StateSet setA;
366 for(Idx state=1; state<45; state++) {
367 setA.Insert(state);
368 }
369 setA.Write();
370
371 // Have a deferred copy
372 StateSet setB=setA;
373
374 // Test protocol
375 FAUDES_TEST_DUMP("deferred copy A",setA);
376 FAUDES_TEST_DUMP("deferred copy B",setB);
377
378 // Collect iterators
379 std::vector<StateSet::Iterator> edIts;
380
381 // Investigate deferred copy setB
382 StateSet::Iterator cit=setB.Begin();
383 for(;cit!=setB.End(); cit++) {
384 if(*cit % 5 !=0) continue;
385 edIts.push_back(cit);
386 }
387
388 // Test protocol
389 FAUDES_TEST_DUMP("deferred copy A - 2",setA);
390 FAUDES_TEST_DUMP("deferred copy B - 2",setB);
391
392 // setB should share with setA and have quite some iterators
393 setB.DWrite();
394
395 // Trigger detach and lock set B
396 setB.Lock();
397
398 // Further investigate true copy of setB
399 cit=setB.Begin();
400 for(;cit!=setB.End(); cit++) {
401 if(*cit % 5 ==0) continue;
402 if(*cit % 2 !=0) continue;
403 edIts.push_back(cit);
404 }
405
406 // setB neither shares nor track iterators
407 setB.DWrite();
408
409 // Have other deferred copy
410 StateSet setC=setB;
411
412 // Write on the deferred copy to trigger actual copy
413 setC.Insert(77);
414
415 // Perform edit on deferred copy
416 std::vector<StateSet::Iterator>::iterator iit=edIts.begin();
417 for(;iit!=edIts.end(); iit++) {
418 Idx oldstate = **iit;
419 setC.Erase(oldstate);
420 setC.Insert(100+oldstate);
421 }
422
423 // setB should not share and still dont track any iterators
424 setB.Write();
425 setB.DWrite();
426 std::cout << "################################\n";
427
428 // Test protocol
429 FAUDES_TEST_DUMP("deferred copy A - 3",setA);
430 FAUDES_TEST_DUMP("deferred copy B - 3",setB);
431 FAUDES_TEST_DUMP("deferred copy C - 3",setC);
432
433 ////////////////////////////////////////////////////
434 // Developper internal: test for memory leaks
435 ////////////////////////////////////////////////////
436
437 /*
438 EventSet evs2;
439 Generator gsm2;
440 evs2.Insert("alpha");
441 Generator gsm("data/simplemachine.gen");
442 for(int i=0;i<2000000;i++) {
443 for(int j=0;j<20000;j++) {
444 gsm.IsCoaccessible();
445 Deterministic(gsm,gsm2);
446 Project(gsm,evs2,gsm2);
447 }
448 }
449 */
450
451 return 0;
452}
int main()
#define FAUDES_TEST_DUMP(mes, dat)
Definition cfl_utils.h:506
void Set(fType mask)
const std::string & Name(void) const
virtual std::string Str(const Idx &rIndex) const
bool Exists(const Idx &rIndex) const
void SymbolicName(Idx index, const std::string &rName)
bool Insert(const Idx &rIndex)
Idx Index(const std::string &rName) const
virtual bool Erase(const Idx &rIndex)
virtual bool ElementTry(const Type &rElement) const
virtual const T & At(const Position &pos) const
void DWrite(const Type *pContext=0) const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
void Write(const Type *pContext=0) const
void FilenameAt(const Position &pos, const std::string &rFileName)
virtual void PushBack(const Type &rElem)
void Lock(void) const
bool Exists(const T &rElem) const
virtual void Clear(void)
Iterator End(void) const
bool EqualAttributes(const TBaseSet &rOtherSet) const
Iterator Begin(void) const
virtual bool Erase(const T &rElem)
uint32_t Idx

libFAUDES 2.34g --- 2026.03.30 --- c++ api documentaion by doxygen