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
77 EventSet::Iterator eit;
78 std::cout << "################################\n";
79 std::cout << "# tutorial, iterators \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
86 // Read an alphabet from generator file
87 alphabet3.Read("data/simplemachine.gen", "Alphabet");
88
89 // Read an alphabet from file at object construction
90 EventSet alphabet4("data/simplemachine.gen", "Alphabet");
91
92 // Write a alphabet to file
93 alphabet2.Write("tmp_alphabet.txt");
94
95 // Report
96 std::cout << "################################\n";
97 std::cout << "# tutorial, alphabets of simple machine \n";
98 alphabet4.DWrite();
99 std::cout << "################################\n";
100
101
102 // Set inclusion by overloaded <= operator
103 if(alphabet1 <= alphabet2) {
104 std::cout << "################################\n";
105 std::cout << "alphabet1 includes alphabet2" << std::endl;
106 std::cout << "################################\n";
107 }
108 else {
109 std::cout << "################################\n";
110 std::cout << "alphabet1 does not include alphabet2" << std::endl;
111 std::cout << "################################\n";
112 }
113
114 // Delete an event by name
115 alphabet2.Erase("e");
116
117 // Delete an event by index
118 alphabet2.Erase(alphabet2.Index("f"));
119
120 // Clear an eventset
121 alphabet4.Clear();
122
123 // Test existence of event
124 if (alphabet2.Exists("d")) {
125 std::cout << "alphabet2: event d exists" << std::endl;
126 }
127
128
129 // Report
130 std::cout << "################################\n";
131 std::cout << "# tutorial, updated alphabets 1 and 2 \n";
132 alphabet1.DWrite();
133 alphabet2.DWrite();
134 std::cout << "################################\n";
135
136
137 // Set difference
138 EventSet adifference = alphabet1 - alphabet2;
139 std::cout << "################################\n";
140 std::cout << "set difference: " << adifference.ToString() << std::endl;
141 std::cout << "################################\n";
142
143
144 // Set union
145 EventSet aunion = alphabet1 + alphabet2;
146 std::cout << "################################\n";
147 std::cout << "set union: " << aunion.ToString() << std::endl;
148 std::cout << "################################\n";
149
150 // Set intersection
151 EventSet aintersection = alphabet1 * alphabet2;
152 std::cout << "################################\n";
153 std::cout << "set intersection: " << aintersection.ToString() << std::endl;
154 std::cout << "################################\n";
155
156 // Test protocol
157 FAUDES_TEST_DUMP("set difference",adifference);
158 FAUDES_TEST_DUMP("set union",aunion);
159 FAUDES_TEST_DUMP("set intersection",aintersection);
160
161
162 ////////////////////////////////////////////////////
163 // StateSets
164 ////////////////////////////////////////////////////
165
166
167 std::cout << "################################\n";
168 std::cout << "# tutorial, state sets \n";
169
170 // Create a StateSet
171 StateSet stateset1;
172
173 // Introduce states
174 Idx state1 = stateset1.Insert(47);
175 Idx state2 = stateset1.Insert(11);
176 Idx state3 = stateset1.Insert(); // becomes 48
177
178 // Introduce more states
179 for(int i=0; i<25; i++) stateset1.Insert(); // becomes 49 ... 73
180 Idx state4 = stateset1.Insert(100);
181
182 // Iterator usage
183 StateSet::Iterator sit;
184 std::cout << "stateset1: ";
185 for (sit = stateset1.Begin(); sit != stateset1.End(); ++sit) {
186 std::cout << stateset1.Str(*sit) << " ";
187 }
188 std::cout << std::endl;
189
190 // Print as string (using file format)
191 std::cout << "stateset1: " << stateset1.ToString() << std::endl;
192
193 // Write a stateset to file (section defaults to "IndexSet")
194 stateset1.Write("tmp_stateset.txt");
195
196 // Read back from file (section defaults to "current begin token")
197 StateSet stateset2;
198 stateset2.Read("tmp_stateset.txt");
199
200 // Debug output to console
201 stateset2.Write();
202
203 // Delete a state by index
204 stateset2.Erase(state2);
205
206 // Copy a StateSet
207 StateSet stateset3 = stateset1;
208
209 // Clear a StateSet
210 stateset1.Clear();
211
212 // Test existence of state
213 if (stateset3.Exists(state1)) {
214 std::cout << "stateset3: state " << state1 << " exists" << std::endl;
215 }
216
217 std::cout << "################################\n\n";
218
219
220 ////////////////////////////////////////////////////
221 // advanced topic: attributed sets
222 ////////////////////////////////////////////////////
223
224
225 std::cout << "################################\n";
226 std::cout << "# tutorial, attributes \n";
227
228 // Convenience type definition for states with flag attribute (see attributes.h)
229 typedef TaStateSet<AttributeFlags> FStateSet;
230
231 // Construct from a file (read attributes if specified)
232 FStateSet fstateset1("tmp_stateset.txt");
233
234 // Construct from stateset with no attributes
235 FStateSet fstateset3(stateset3);
236
237 // Report
238 std::cout << "fstateset3: " << fstateset3.ToString() << std::endl;
239
240 // Manipulate attribute by state index (this requires the state to exist)
241 fstateset3.Attributep(60)->Set(0xff);
242
243 // Insert new state with attribute
244 AttributeFlags fattr;
245 fattr.Set(0x55);
246 Idx fstate = fstateset3.Insert(fattr);
247
248 // Report
249 std::cout << "fstateset3: attribute of state 60: "
250 << fstateset3.Attribute(60).ToString() << std::endl;
251 std::cout << "fstateset3: attribute of state " << fstate
252 << ": " << fstateset3.Attribute(fstate).ToString() << std::endl;
253 std::cout << "fstateset3: " << fstateset3.ToString() << std::endl;
254
255 // Write to file
256 fstateset3.Write("tmp_fstateset.txt");
257
258 // Convert to set without attributes (drop attributes)
259 stateset3 = fstateset3;
260
261 // Report
262 std::cout << "stateset3: " << stateset3.ToString() << std::endl;
263
264 // Set comparision ignores attributes
265 if(stateset3==fstateset3)
266 std::cout << "stateset3 indeed equals fstateset3 " << std::endl;
267
268 // Explicit equality test shows
269 if(!stateset3.EqualAttributes(fstateset3))
270 std::cout << "stateset3 indeed has different attributes as fstateset3 " << std::endl;
271
272 // Provided that actual types match, attributes are copied even when accesssing
273 // via non attributed StateSet methods
274 FStateSet fstateset4;
275 StateSet& rfstateset3 = fstateset3;
276 StateSet& rfstateset4 = fstateset4;
277 rfstateset4 = rfstateset3;
278
279 // Remove a state with no attribute (provoce deep copy)
280 rfstateset3.Erase(50);
281
282 // Test attribute equality
283 if(fstateset4.EqualAttributes(fstateset3))
284 std::cout << "fstateset4 indeed has equal attributes with fstateset3 " << std::endl;
285 if(rfstateset4.EqualAttributes(rfstateset3))
286 std::cout << "rfstateset4 indeed has equal attributes with rfstateset3 " << std::endl;
287
288 // Report
289 std::cout << "fstateset4: " << fstateset4.ToString() << std::endl;
290 std::cout << "################################\n\n";
291
292 // Test protocol
293 FAUDES_TEST_DUMP("attrbibutes eq0", stateset3 == fstateset3);
294 FAUDES_TEST_DUMP("attrbibutes eq1", stateset3.EqualAttributes(fstateset3));
295 FAUDES_TEST_DUMP("attrbibutes eq2", fstateset4.EqualAttributes(fstateset3));
296 FAUDES_TEST_DUMP("attrbibutes eq3", rfstateset4.EqualAttributes(rfstateset3));
297
298
299 ////////////////////////////////////////////////////
300 // Vectors
301 ////////////////////////////////////////////////////
302
303 std::cout << "################################\n";
304 std::cout << "# tutorial, vectors \n";
305
306 // Have a vector of event sets
307 EventSetVector alphvect;
308
309 // Populate the vector (take copies)
310 alphvect.PushBack(alphabet1);
311 alphvect.PushBack(alphabet2);
312 alphvect.PushBack(alphabet3);
313
314 // Access entries
315 std::cout << "# event set no 1 (counting from 0):\n";
316 alphvect.At(1).Write();
317
318 // Manipulate entries
319 alphvect.At(1).Insert("delta_1");
320
321 // Report
322 std::cout << "# all three event sets:\n";
323 alphvect.Write();
324
325 // Set filenames for convenient token io
326 alphvect.FilenameAt(0,"tmp_alph0.txt");
327 alphvect.FilenameAt(1,"tmp_alph1.txt");
328 alphvect.FilenameAt(2,"tmp_alph2.txt");
329 alphvect.Write("tmp_alphvect.txt");
330
331
332 // query, whether the vector can take an element
333 System cgen;
334 bool vcast = alphvect.ElementTry(cgen);
335 if(vcast)
336 std::cout << "# EventSetVector can take Generator elements [fail]\n";
337 else
338 std::cout << "# EventSetVector cannot take Generator elements [expected]\n";
339
340 // record
341 FAUDES_TEST_DUMP("vect element cast",vcast);
342
343
344 // Done
345 std::cout << "################################\n";
346
347
348 ////////////////////////////////////////////////////
349 // Developper internal: deferred copy stress test
350 ////////////////////////////////////////////////////
351
352
353 std::cout << "################################\n";
354 std::cout << "# tutorial, deferred copy stress test \n";
355
356 // Create state set {1,2,...44}
357 StateSet setA;
358 for(Idx state=1; state<45; state++) {
359 setA.Insert(state);
360 }
361 setA.Write();
362
363 // Have a deferred copy
364 StateSet setB=setA;
365
366 // Test protocol
367 FAUDES_TEST_DUMP("deferred copy A",setA);
368 FAUDES_TEST_DUMP("deferred copy B",setB);
369
370 // Collect iterators
371 std::vector<StateSet::Iterator> edIts;
372
373 // Investigate deferred copy setB
374 StateSet::Iterator cit=setB.Begin();
375 for(;cit!=setB.End(); cit++) {
376 if(*cit % 5 !=0) continue;
377 edIts.push_back(cit);
378 }
379
380 // Test protocol
381 FAUDES_TEST_DUMP("deferred copy A - 2",setA);
382 FAUDES_TEST_DUMP("deferred copy B - 2",setB);
383
384 // setB should share with setA and have quite some iterators
385 setB.DWrite();
386
387 // Trigger detach and lock set B
388 setB.Lock();
389
390 // Further investigate true copy of setB
391 cit=setB.Begin();
392 for(;cit!=setB.End(); cit++) {
393 if(*cit % 5 ==0) continue;
394 if(*cit % 2 !=0) continue;
395 edIts.push_back(cit);
396 }
397
398 // setB neither shares nor track iterators
399 setB.DWrite();
400
401 // Have other deferred copy
402 StateSet setC=setB;
403
404 // Write on the deferred copy to trigger actual copy
405 setC.Insert(77);
406
407 // Perform edit on deferred copy
408 std::vector<StateSet::Iterator>::iterator iit=edIts.begin();
409 for(;iit!=edIts.end(); iit++) {
410 Idx oldstate = **iit;
411 setC.Erase(oldstate);
412 setC.Insert(100+oldstate);
413 }
414
415 // setB should not share and still dont track any iterators
416 setB.Write();
417 setB.DWrite();
418 std::cout << "################################\n";
419
420 // Test protocol
421 FAUDES_TEST_DUMP("deferred copy A - 3",setA);
422 FAUDES_TEST_DUMP("deferred copy B - 3",setB);
423 FAUDES_TEST_DUMP("deferred copy C - 3",setC);
424
425 ////////////////////////////////////////////////////
426 // Developper internal: memory leak in BaseSet
427 ////////////////////////////////////////////////////
428
429 /*
430 EventSet evs2;
431 Generator gsm2;
432 evs2.Insert("alpha");
433 Generator gsm("data/simplemachine.gen");
434 for(int i=0;i<2000000;i++) {
435 for(int j=0;j<20000;j++) {
436 gsm.IsCoaccessible();
437 Deterministic(gsm,gsm2);
438 Project(gsm,evs2,gsm2);
439 }
440 }
441 */
442
443 return 0;
444}
int main()
#define FAUDES_TEST_DUMP(mes, dat)
Definition cfl_utils.h:505
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.33k --- 2025.09.16 --- c++ api documentaion by doxygen