Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add preliminary tests for checking event conflicts
[simgrid.git] / src / mc / explo / udpor / EventSet_test.cpp
1 /* Copyright (c) 2017-2023. The SimGrid Team. All rights reserved.               */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "src/3rd-party/catch.hpp"
7 #include "src/mc/explo/udpor/EventSet.hpp"
8 #include "src/mc/explo/udpor/UnfoldingEvent.hpp"
9 #include "src/mc/transition/Transition.hpp"
10
11 using namespace simgrid::mc;
12 using namespace simgrid::mc::udpor;
13
14 TEST_CASE("simgrid::mc::udpor::EventSet: Initial conditions when creating sets")
15 {
16   SECTION("Initialization with no elements")
17   {
18     SECTION("Default initializer")
19     {
20       EventSet event_set;
21       REQUIRE(event_set.size() == 0);
22       REQUIRE(event_set.empty());
23     }
24
25     SECTION("Set initializer")
26     {
27       EventSet event_set({});
28       REQUIRE(event_set.size() == 0);
29       REQUIRE(event_set.empty());
30     }
31
32     SECTION("List initialization")
33     {
34       EventSet event_set{};
35       REQUIRE(event_set.size() == 0);
36       REQUIRE(event_set.empty());
37     }
38   }
39
40   SECTION("Initialization with one or more elements")
41   {
42     UnfoldingEvent e1, e2, e3;
43
44     SECTION("Set initializer")
45     {
46       EventSet event_set({&e1, &e2, &e3});
47       REQUIRE(event_set.size() == 3);
48       REQUIRE(event_set.contains(&e1));
49       REQUIRE(event_set.contains(&e2));
50       REQUIRE(event_set.contains(&e3));
51       REQUIRE_FALSE(event_set.empty());
52     }
53
54     SECTION("List initialization")
55     {
56       EventSet event_set{&e1, &e2, &e3};
57       REQUIRE(event_set.size() == 3);
58       REQUIRE(event_set.contains(&e1));
59       REQUIRE(event_set.contains(&e2));
60       REQUIRE(event_set.contains(&e3));
61       REQUIRE_FALSE(event_set.empty());
62     }
63   }
64 }
65
66 TEST_CASE("simgrid::mc::udpor::EventSet: Insertions")
67 {
68   EventSet event_set;
69   UnfoldingEvent e1, e2, e3;
70
71   SECTION("Inserting unique elements")
72   {
73     event_set.insert(&e1);
74     REQUIRE(event_set.size() == 1);
75     REQUIRE(event_set.contains(&e1));
76     REQUIRE_FALSE(event_set.empty());
77
78     event_set.insert(&e2);
79     REQUIRE(event_set.size() == 2);
80     REQUIRE(event_set.contains(&e2));
81     REQUIRE_FALSE(event_set.empty());
82
83     SECTION("Check contains inserted elements")
84     {
85       REQUIRE(event_set.contains(&e1));
86       REQUIRE(event_set.contains(&e2));
87       REQUIRE_FALSE(event_set.contains(&e3));
88     }
89   }
90
91   SECTION("Inserting duplicate elements")
92   {
93     event_set.insert(&e1);
94     REQUIRE(event_set.size() == 1);
95     REQUIRE(event_set.contains(&e1));
96     REQUIRE_FALSE(event_set.empty());
97
98     event_set.insert(&e1);
99     REQUIRE(event_set.size() == 1);
100     REQUIRE(event_set.contains(&e1));
101     REQUIRE_FALSE(event_set.empty());
102
103     SECTION("Check contains inserted elements")
104     {
105       REQUIRE(event_set.contains(&e1));
106       REQUIRE_FALSE(event_set.contains(&e2));
107       REQUIRE_FALSE(event_set.contains(&e3));
108     }
109   }
110 }
111
112 TEST_CASE("simgrid::mc::udpor::EventSet: Deletions")
113 {
114   UnfoldingEvent e1;
115   UnfoldingEvent e2;
116   UnfoldingEvent e3;
117   UnfoldingEvent e4;
118   EventSet event_set({&e1, &e2, &e3});
119
120   SECTION("Remove an element already present")
121   {
122     REQUIRE(event_set.contains(&e1));
123
124     // Recall that event_set = {e2, e3}
125     event_set.remove(&e1);
126
127     // Check that
128     // 1. the size decreases by exactly 1
129     // 2. the set remains unempty
130     // 3. the other elements are still contained in the set
131     REQUIRE(event_set.size() == 2);
132     REQUIRE_FALSE(event_set.contains(&e1));
133     REQUIRE(event_set.contains(&e2));
134     REQUIRE(event_set.contains(&e3));
135     REQUIRE_FALSE(event_set.empty());
136
137     SECTION("Remove a single element more than once")
138     {
139       // Recall that event_set = {e2, e3}
140       event_set.remove(&e1);
141       REQUIRE(event_set.size() == 2);
142       REQUIRE_FALSE(event_set.contains(&e1));
143       REQUIRE(event_set.contains(&e2));
144       REQUIRE(event_set.contains(&e3));
145       REQUIRE_FALSE(event_set.empty());
146     }
147
148     SECTION("Remove more than one element")
149     {
150       // Recall that event_set = {e3}
151       event_set.remove(&e2);
152
153       REQUIRE(event_set.size() == 1);
154       REQUIRE_FALSE(event_set.contains(&e1));
155       REQUIRE_FALSE(event_set.contains(&e2));
156       REQUIRE(event_set.contains(&e3));
157       REQUIRE_FALSE(event_set.empty());
158
159       // Recall that event_set = {}
160       event_set.remove(&e3);
161
162       REQUIRE(event_set.size() == 0);
163       REQUIRE_FALSE(event_set.contains(&e1));
164       REQUIRE_FALSE(event_set.contains(&e2));
165       REQUIRE_FALSE(event_set.contains(&e3));
166       REQUIRE(event_set.empty());
167     }
168   }
169
170   SECTION("Remove an element absent from the set")
171   {
172     REQUIRE_FALSE(event_set.contains(&e4));
173
174     // Recall that event_set = {e1, e2, e3}
175     event_set.remove(&e4);
176     REQUIRE(event_set.size() == 3);
177     REQUIRE(event_set.contains(&e1));
178     REQUIRE(event_set.contains(&e2));
179     REQUIRE(event_set.contains(&e3));
180
181     // Ensure e4 isn't somehow added
182     REQUIRE_FALSE(event_set.contains(&e4));
183     REQUIRE_FALSE(event_set.empty());
184   }
185 }
186
187 TEST_CASE("simgrid::mc::udpor::EventSet: Set Equality")
188 {
189   UnfoldingEvent e1;
190   UnfoldingEvent e2;
191   UnfoldingEvent e3;
192   UnfoldingEvent e4;
193   EventSet A{&e1, &e2, &e3}, B{&e1, &e2, &e3}, C{&e1, &e2, &e3};
194
195   SECTION("Equality implies containment")
196   {
197     REQUIRE(A == B);
198
199     for (const auto& e : A) {
200       REQUIRE(B.contains(e));
201     }
202
203     for (const auto& e : B) {
204       REQUIRE(A.contains(e));
205     }
206   }
207
208   SECTION("Containment implies equality")
209   {
210     for (const auto& e : A) {
211       REQUIRE(B.contains(e));
212     }
213
214     for (const auto& e : C) {
215       REQUIRE(C.contains(e));
216     }
217
218     REQUIRE(A == C);
219   }
220
221   SECTION("Equality is an equivalence relation")
222   {
223     // Reflexive
224     REQUIRE(A == A);
225     REQUIRE(B == B);
226     REQUIRE(C == C);
227
228     // Symmetric
229     REQUIRE(A == B);
230     REQUIRE(B == A);
231     REQUIRE(A == C);
232     REQUIRE(C == A);
233     REQUIRE(B == C);
234     REQUIRE(C == B);
235
236     // Transitive
237     REQUIRE(A == B);
238     REQUIRE(B == C);
239     REQUIRE(A == C);
240   }
241
242   SECTION("Equality after copy (assignment + constructor)")
243   {
244     EventSet A_copy = A;
245     EventSet A_copy2(A);
246
247     REQUIRE(A == A_copy);
248     REQUIRE(A == A_copy2);
249   }
250
251   SECTION("Equality after move constructor")
252   {
253     EventSet A_copy = A;
254     EventSet A_move(std::move(A));
255     REQUIRE(A_move == A_copy);
256   }
257
258   SECTION("Equality after move-assignment")
259   {
260     EventSet A_copy = A;
261     EventSet A_move = std::move(A);
262     REQUIRE(A_move == A_copy);
263   }
264 }
265
266 TEST_CASE("simgrid::mc::udpor::EventSet: Set Union Tests")
267 {
268   UnfoldingEvent e1, e2, e3, e4;
269
270   // C = A + B
271   EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e1, &e2, &e3, &e4}, D{&e1, &e3};
272
273   SECTION("Unions with no effect")
274   {
275     EventSet A_copy = A;
276
277     SECTION("Self union")
278     {
279       // A = A union A
280       EventSet A_union = A.make_union(A);
281       REQUIRE(A == A_copy);
282
283       A.form_union(A);
284       REQUIRE(A == A_copy);
285     }
286
287     SECTION("Union with empty set")
288     {
289       // A = A union empty set
290       EventSet A_union = A.make_union(EventSet());
291       REQUIRE(A == A_union);
292
293       A.form_union(EventSet());
294       REQUIRE(A == A_copy);
295     }
296
297     SECTION("Union with an equivalent set")
298     {
299       // A = A union B if B == A
300       EventSet A_equiv{&e1, &e2, &e3};
301       REQUIRE(A == A_equiv);
302
303       EventSet A_union = A.make_union(A_equiv);
304       REQUIRE(A_union == A_copy);
305
306       A.form_union(A_equiv);
307       REQUIRE(A == A_copy);
308     }
309
310     SECTION("Union with a subset")
311     {
312       // A = A union D if D is a subset of A
313       EventSet A_union = A.make_union(D);
314       REQUIRE(A == A_union);
315
316       A.form_union(D);
317       REQUIRE(A == A_copy);
318     }
319   }
320
321   SECTION("Unions with partial overlaps")
322   {
323     EventSet A_union_B = A.make_union(B);
324     REQUIRE(A_union_B == C);
325
326     A.form_union(B);
327     REQUIRE(A == C);
328
329     EventSet B_union_D = B.make_union(D);
330     REQUIRE(B_union_D == C);
331
332     B.form_union(D);
333     REQUIRE(B == C);
334   }
335
336   SECTION("Set union properties")
337   {
338     SECTION("Union operator is symmetric")
339     {
340       EventSet A_union_B = A.make_union(B);
341       EventSet B_union_A = B.make_union(A);
342       REQUIRE(A_union_B == B_union_A);
343     }
344
345     SECTION("Union operator commutes")
346     {
347       // The last SECTION tested pair-wise
348       // equivalence, so we only check
349       // one of each pai
350       EventSet AD = A.make_union(D);
351       EventSet AC = A.make_union(C);
352       EventSet CD = D.make_union(C);
353
354       EventSet ADC = AD.make_union(C);
355       EventSet ACD = AC.make_union(D);
356       EventSet CDA = CD.make_union(A);
357
358       REQUIRE(ADC == ACD);
359       REQUIRE(ACD == CDA);
360
361       // Test `form_union()` in the same way
362
363       EventSet A_copy = A;
364       EventSet C_copy = C;
365       EventSet D_copy = D;
366
367       A.form_union(C_copy);
368       A.form_union(D_copy);
369
370       D.form_union(A_copy);
371       D.form_union(C_copy);
372
373       C.form_union(A);
374       C.form_union(D);
375
376       REQUIRE(A == D);
377       REQUIRE(C == D);
378       REQUIRE(A == C);
379     }
380   }
381 }
382
383 TEST_CASE("simgrid::mc::udpor::EventSet: Set Difference Tests")
384 {
385   UnfoldingEvent e1;
386   UnfoldingEvent e2;
387   UnfoldingEvent e3;
388   UnfoldingEvent e4;
389
390   // C = A + B
391   // A is a subset of C
392   // B is a subset of C
393   // D is a subset of A and C
394   // E is a subset of B and C
395   // F is a subset of A, C, and D
396   EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e1, &e2, &e3, &e4}, D{&e1, &e3}, E{&e4}, F{&e1};
397
398   SECTION("Difference with no effect")
399   {
400     SECTION("Difference with empty set")
401     {
402       EventSet A_copy = A.subtracting(EventSet());
403       REQUIRE(A == A_copy);
404
405       A.subtract(EventSet());
406       REQUIRE(A == A_copy);
407     }
408
409     SECTION("Difference with empty intersection")
410     {
411       // A intersection E = empty set
412       EventSet A_copy = A.subtracting(E);
413       REQUIRE(A == A_copy);
414
415       A.subtract(E);
416       REQUIRE(A == A_copy);
417
418       EventSet D_copy = D.subtracting(E);
419       REQUIRE(D == D_copy);
420
421       D.subtract(E);
422       REQUIRE(D == D_copy);
423     }
424   }
425
426   SECTION("Difference with some overlap")
427   {
428     // A - B = {&e1} = F
429     EventSet A_minus_B = A.subtracting(B);
430     REQUIRE(A_minus_B == F);
431
432     // B - D = {&e2, &e4}
433     EventSet B_minus_D = B.subtracting(D);
434     REQUIRE(B_minus_D == EventSet({&e2, &e4}));
435   }
436
437   SECTION("Difference with complete overlap")
438   {
439     SECTION("Difference with same set gives empty set")
440     {
441       REQUIRE(A.subtracting(A) == EventSet());
442       REQUIRE(B.subtracting(B) == EventSet());
443       REQUIRE(C.subtracting(C) == EventSet());
444       REQUIRE(D.subtracting(D) == EventSet());
445       REQUIRE(E.subtracting(E) == EventSet());
446       REQUIRE(F.subtracting(F) == EventSet());
447     }
448
449     SECTION("Difference with superset gives empty set")
450     {
451       REQUIRE(A.subtracting(C) == EventSet());
452       REQUIRE(B.subtracting(C) == EventSet());
453       REQUIRE(D.subtracting(A) == EventSet());
454       REQUIRE(D.subtracting(C) == EventSet());
455       REQUIRE(E.subtracting(B) == EventSet());
456       REQUIRE(E.subtracting(C) == EventSet());
457       REQUIRE(F.subtracting(A) == EventSet());
458       REQUIRE(F.subtracting(C) == EventSet());
459       REQUIRE(F.subtracting(D) == EventSet());
460     }
461   }
462 }
463
464 TEST_CASE("simgrid::mc::udpor::EventSet: Subset Tests")
465 {
466   UnfoldingEvent e1, e2, e3, e4;
467
468   // A is a subset of C only
469   // B is a subset of C only
470   // D is a subset of C and A
471   // D is NOT a subset of B
472   // B is NOT a subset of D
473   // ...
474   EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e1, &e2, &e3, &e4}, D{&e1, &e3}, E{&e2, &e3}, F{&e1, &e2, &e3};
475
476   SECTION("Subset operator properties")
477   {
478     SECTION("Subset operator is not commutative")
479     {
480       REQUIRE(A.is_subset_of(C));
481       REQUIRE_FALSE(C.is_subset_of(A));
482
483       SECTION("Commutativity implies equality and vice versa")
484       {
485         REQUIRE(A.is_subset_of(F));
486         REQUIRE(F.is_subset_of(A));
487         REQUIRE(A == F);
488
489         REQUIRE(C == C);
490         REQUIRE(A.is_subset_of(F));
491         REQUIRE(F.is_subset_of(A));
492       }
493     }
494
495     SECTION("Subset operator is transitive")
496     {
497       REQUIRE(D.is_subset_of(A));
498       REQUIRE(A.is_subset_of(C));
499       REQUIRE(D.is_subset_of(C));
500       REQUIRE(E.is_subset_of(B));
501       REQUIRE(B.is_subset_of(C));
502       REQUIRE(E.is_subset_of(C));
503     }
504
505     SECTION("Subset operator is reflexive")
506     {
507       REQUIRE(A.is_subset_of(A));
508       REQUIRE(B.is_subset_of(B));
509       REQUIRE(C.is_subset_of(C));
510       REQUIRE(D.is_subset_of(D));
511       REQUIRE(E.is_subset_of(E));
512       REQUIRE(F.is_subset_of(F));
513     }
514   }
515 }
516
517 TEST_CASE("simgrid::mc::udpor::EventSet: Testing Configurations")
518 {
519   // The following tests concern the given event structure:
520   //                e1
521   //              /    /
522   //            e2      e5
523   //           /  /      /
524   //          e3  e4     e6
525   // The tests enumerate all possible subsets of the events
526   // in the structure and test whether those subsets are
527   // maximal and/or valid configurations
528   UnfoldingEvent e1;
529   UnfoldingEvent e2{&e1};
530   UnfoldingEvent e3{&e2};
531   UnfoldingEvent e4{&e2};
532   UnfoldingEvent e5{&e1};
533   UnfoldingEvent e6{&e5};
534
535   SECTION("Valid Configurations")
536   {
537     SECTION("The empty set is valid")
538     {
539       REQUIRE(EventSet().is_valid_configuration());
540     }
541
542     SECTION("The set with only the root event is valid")
543     {
544       REQUIRE(EventSet({&e1}).is_valid_configuration());
545     }
546
547     SECTION("All sets of maximal events are valid configurations")
548     {
549       REQUIRE(EventSet({&e1}).is_valid_configuration());
550       REQUIRE(EventSet({&e1, &e2}).is_valid_configuration());
551       REQUIRE(EventSet({&e1, &e2, &e3}).is_valid_configuration());
552       REQUIRE(EventSet({&e1, &e2, &e4}).is_valid_configuration());
553       REQUIRE(EventSet({&e1, &e5}).is_valid_configuration());
554       REQUIRE(EventSet({&e1, &e5, &e6}).is_valid_configuration());
555       REQUIRE(EventSet({&e1, &e2, &e5}).is_valid_configuration());
556       REQUIRE(EventSet({&e1, &e2, &e5, &e6}).is_valid_configuration());
557       REQUIRE(EventSet({&e1, &e2, &e3, &e4}).is_valid_configuration());
558       REQUIRE(EventSet({&e1, &e2, &e3, &e5}).is_valid_configuration());
559       REQUIRE(EventSet({&e1, &e2, &e4, &e5}).is_valid_configuration());
560       REQUIRE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_valid_configuration());
561       REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_valid_configuration());
562       REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_valid_configuration());
563     }
564   }
565
566   SECTION("Configuration checks")
567   {
568     // 6 choose 0 = 1 test
569     REQUIRE(EventSet().is_valid_configuration());
570
571     // 6 choose 1 = 6 tests
572     REQUIRE(EventSet({&e1}).is_valid_configuration());
573     REQUIRE_FALSE(EventSet({&e2}).is_valid_configuration());
574     REQUIRE_FALSE(EventSet({&e3}).is_valid_configuration());
575     REQUIRE_FALSE(EventSet({&e4}).is_valid_configuration());
576     REQUIRE_FALSE(EventSet({&e5}).is_valid_configuration());
577     REQUIRE_FALSE(EventSet({&e6}).is_valid_configuration());
578
579     // 6 choose 2 = 15 tests
580     REQUIRE(EventSet({&e1, &e2}).is_valid_configuration());
581     REQUIRE_FALSE(EventSet({&e1, &e3}).is_valid_configuration());
582     REQUIRE_FALSE(EventSet({&e1, &e4}).is_valid_configuration());
583     REQUIRE(EventSet({&e1, &e5}).is_valid_configuration());
584     REQUIRE_FALSE(EventSet({&e1, &e6}).is_valid_configuration());
585     REQUIRE_FALSE(EventSet({&e2, &e3}).is_valid_configuration());
586     REQUIRE_FALSE(EventSet({&e2, &e4}).is_valid_configuration());
587     REQUIRE_FALSE(EventSet({&e2, &e5}).is_valid_configuration());
588     REQUIRE_FALSE(EventSet({&e2, &e6}).is_valid_configuration());
589     REQUIRE_FALSE(EventSet({&e3, &e4}).is_valid_configuration());
590     REQUIRE_FALSE(EventSet({&e3, &e5}).is_valid_configuration());
591     REQUIRE_FALSE(EventSet({&e3, &e6}).is_valid_configuration());
592     REQUIRE_FALSE(EventSet({&e4, &e5}).is_valid_configuration());
593     REQUIRE_FALSE(EventSet({&e4, &e6}).is_valid_configuration());
594     REQUIRE_FALSE(EventSet({&e5, &e6}).is_valid_configuration());
595
596     // 6 choose 3 = 20 tests
597     REQUIRE(EventSet({&e1, &e2, &e3}).is_valid_configuration());
598     REQUIRE(EventSet({&e1, &e2, &e4}).is_valid_configuration());
599     REQUIRE(EventSet({&e1, &e2, &e5}).is_valid_configuration());
600     REQUIRE_FALSE(EventSet({&e1, &e2, &e6}).is_valid_configuration());
601     REQUIRE_FALSE(EventSet({&e1, &e3, &e4}).is_valid_configuration());
602     REQUIRE_FALSE(EventSet({&e1, &e3, &e5}).is_valid_configuration());
603     REQUIRE_FALSE(EventSet({&e1, &e3, &e6}).is_valid_configuration());
604     REQUIRE_FALSE(EventSet({&e1, &e4, &e5}).is_valid_configuration());
605     REQUIRE_FALSE(EventSet({&e1, &e4, &e6}).is_valid_configuration());
606     REQUIRE(EventSet({&e1, &e5, &e6}).is_valid_configuration());
607     REQUIRE_FALSE(EventSet({&e2, &e3, &e4}).is_valid_configuration());
608     REQUIRE_FALSE(EventSet({&e2, &e3, &e5}).is_valid_configuration());
609     REQUIRE_FALSE(EventSet({&e2, &e3, &e6}).is_valid_configuration());
610     REQUIRE_FALSE(EventSet({&e2, &e4, &e5}).is_valid_configuration());
611     REQUIRE_FALSE(EventSet({&e2, &e4, &e6}).is_valid_configuration());
612     REQUIRE_FALSE(EventSet({&e2, &e5, &e6}).is_valid_configuration());
613     REQUIRE_FALSE(EventSet({&e3, &e4, &e5}).is_valid_configuration());
614     REQUIRE_FALSE(EventSet({&e3, &e4, &e6}).is_valid_configuration());
615     REQUIRE_FALSE(EventSet({&e3, &e5, &e6}).is_valid_configuration());
616     REQUIRE_FALSE(EventSet({&e4, &e5, &e6}).is_valid_configuration());
617
618     // 6 choose 4 = 15 tests
619     REQUIRE(EventSet({&e1, &e2, &e3, &e4}).is_valid_configuration());
620     REQUIRE(EventSet({&e1, &e2, &e3, &e5}).is_valid_configuration());
621     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_valid_configuration());
622     REQUIRE(EventSet({&e1, &e2, &e4, &e5}).is_valid_configuration());
623     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_valid_configuration());
624     REQUIRE(EventSet({&e1, &e2, &e5, &e6}).is_valid_configuration());
625     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_valid_configuration());
626     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_valid_configuration());
627     REQUIRE_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_valid_configuration());
628     REQUIRE_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_valid_configuration());
629     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_valid_configuration());
630     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_valid_configuration());
631     REQUIRE_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_valid_configuration());
632     REQUIRE_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_valid_configuration());
633     REQUIRE_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_valid_configuration());
634
635     // 6 choose 5 = 6 tests
636     REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_valid_configuration());
637     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_valid_configuration());
638     REQUIRE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_valid_configuration());
639     REQUIRE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_valid_configuration());
640     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_valid_configuration());
641     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_valid_configuration());
642
643     // 6 choose 6 = 1 test
644     REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_valid_configuration());
645   }
646
647   SECTION("Maximal event sets")
648   {
649     // 6 choose 0 = 1 test
650     REQUIRE(EventSet().is_maximal());
651
652     // 6 choose 1 = 6 tests
653     REQUIRE(EventSet({&e1}).is_maximal());
654     REQUIRE(EventSet({&e2}).is_maximal());
655     REQUIRE(EventSet({&e3}).is_maximal());
656     REQUIRE(EventSet({&e4}).is_maximal());
657     REQUIRE(EventSet({&e5}).is_maximal());
658     REQUIRE(EventSet({&e6}).is_maximal());
659
660     // 6 choose 2 = 15 tests
661     REQUIRE_FALSE(EventSet({&e1, &e2}).is_maximal());
662     REQUIRE_FALSE(EventSet({&e1, &e3}).is_maximal());
663     REQUIRE_FALSE(EventSet({&e1, &e4}).is_maximal());
664     REQUIRE_FALSE(EventSet({&e1, &e5}).is_maximal());
665     REQUIRE_FALSE(EventSet({&e1, &e6}).is_maximal());
666     REQUIRE_FALSE(EventSet({&e2, &e3}).is_maximal());
667     REQUIRE_FALSE(EventSet({&e2, &e4}).is_maximal());
668     REQUIRE(EventSet({&e2, &e5}).is_maximal());
669     REQUIRE(EventSet({&e2, &e6}).is_maximal());
670     REQUIRE(EventSet({&e3, &e4}).is_maximal());
671     REQUIRE(EventSet({&e3, &e5}).is_maximal());
672     REQUIRE(EventSet({&e3, &e6}).is_maximal());
673     REQUIRE(EventSet({&e4, &e5}).is_maximal());
674     REQUIRE(EventSet({&e4, &e6}).is_maximal());
675     REQUIRE_FALSE(EventSet({&e5, &e6}).is_maximal());
676
677     // 6 choose 3 = 20 tests
678     REQUIRE_FALSE(EventSet({&e1, &e2, &e3}).is_maximal());
679     REQUIRE_FALSE(EventSet({&e1, &e2, &e4}).is_maximal());
680     REQUIRE_FALSE(EventSet({&e1, &e2, &e5}).is_maximal());
681     REQUIRE_FALSE(EventSet({&e1, &e2, &e6}).is_maximal());
682     REQUIRE_FALSE(EventSet({&e1, &e3, &e4}).is_maximal());
683     REQUIRE_FALSE(EventSet({&e1, &e3, &e5}).is_maximal());
684     REQUIRE_FALSE(EventSet({&e1, &e3, &e6}).is_maximal());
685     REQUIRE_FALSE(EventSet({&e1, &e4, &e5}).is_maximal());
686     REQUIRE_FALSE(EventSet({&e1, &e4, &e6}).is_maximal());
687     REQUIRE_FALSE(EventSet({&e1, &e5, &e6}).is_maximal());
688     REQUIRE_FALSE(EventSet({&e2, &e3, &e4}).is_maximal());
689     REQUIRE_FALSE(EventSet({&e2, &e3, &e5}).is_maximal());
690     REQUIRE_FALSE(EventSet({&e2, &e3, &e6}).is_maximal());
691     REQUIRE_FALSE(EventSet({&e2, &e4, &e5}).is_maximal());
692     REQUIRE_FALSE(EventSet({&e2, &e4, &e6}).is_maximal());
693     REQUIRE_FALSE(EventSet({&e2, &e5, &e6}).is_maximal());
694     REQUIRE(EventSet({&e3, &e4, &e5}).is_maximal());
695     REQUIRE(EventSet({&e3, &e4, &e6}).is_maximal());
696     REQUIRE_FALSE(EventSet({&e3, &e5, &e6}).is_maximal());
697     REQUIRE_FALSE(EventSet({&e4, &e5, &e6}).is_maximal());
698
699     // 6 choose 4 = 15 tests
700     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4}).is_maximal());
701     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e5}).is_maximal());
702     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_maximal());
703     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e5}).is_maximal());
704     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_maximal());
705     REQUIRE_FALSE(EventSet({&e1, &e2, &e5, &e6}).is_maximal());
706     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_maximal());
707     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_maximal());
708     REQUIRE_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_maximal());
709     REQUIRE_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_maximal());
710     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_maximal());
711     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_maximal());
712     REQUIRE_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_maximal());
713     REQUIRE_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_maximal());
714     REQUIRE_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_maximal());
715
716     // 6 choose 5 = 6 tests
717     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_maximal());
718     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_maximal());
719     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_maximal());
720     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_maximal());
721     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_maximal());
722     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_maximal());
723
724     // 6 choose 6 = 1 test
725     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_maximal());
726   }
727 }
728
729 TEST_CASE("simgrid::mc::udpor::EventSet: Moving into a collection")
730 {
731   UnfoldingEvent e1;
732   UnfoldingEvent e2;
733   UnfoldingEvent e3;
734   UnfoldingEvent e4;
735
736   EventSet A({&e1});
737   EventSet B({&e1, &e2});
738   EventSet C({&e1, &e2, &e3});
739   EventSet D({&e1, &e2, &e3, &e4});
740
741   EventSet A_copy = A;
742   EventSet B_copy = B;
743   EventSet C_copy = C;
744   EventSet D_copy = D;
745
746   std::vector<const UnfoldingEvent*> actual_A = std::move(A).move_into_vector();
747   std::vector<const UnfoldingEvent*> actual_B = std::move(B).move_into_vector();
748   std::vector<const UnfoldingEvent*> actual_C = std::move(C).move_into_vector();
749   std::vector<const UnfoldingEvent*> actual_D = std::move(D).move_into_vector();
750
751   EventSet A_copy_remade(std::move(actual_A));
752   EventSet B_copy_remade(std::move(actual_B));
753   EventSet C_copy_remade(std::move(actual_C));
754   EventSet D_copy_remade(std::move(actual_D));
755
756   REQUIRE(A_copy == A_copy_remade);
757   REQUIRE(B_copy == B_copy_remade);
758   REQUIRE(C_copy == C_copy_remade);
759   REQUIRE(D_copy == D_copy_remade);
760 }
761
762 TEST_CASE("simgrid::mc::udpor::EventSet: Checking conflicts")
763 {
764   struct IndependentAction : public Transition {
765     // Independent with everyone else
766     bool depends(const Transition* other) const override { return false; }
767   };
768
769   struct DependentAction : public Transition {
770     // Dependent with everyone else (except IndependentAction)
771     bool depends(const Transition* other) const override
772     {
773       return dynamic_cast<const IndependentAction*>(other) == nullptr;
774     }
775   };
776
777   struct ConditionallyDependentAction : public Transition {
778     // Dependent only with DependentAction (i.e. not itself)
779     bool depends(const Transition* other) const override
780     {
781       return dynamic_cast<const DependentAction*>(other) != nullptr;
782     }
783   };
784
785   // The following tests concern the given event structure:
786   //                e1
787   //              /    /
788   //            e2      e5
789   //           /  /      /
790   //          e3  e4     e6
791   // The tests enumerate all possible subsets of the events
792   // in the structure and test whether those subsets contain
793   // conflicts.
794   //
795   // Each test assigns different transitions to each event to
796   // make the scenarios more interesting
797
798   SECTION("No conflicts throughout the whole structure with independent actions")
799   {
800     UnfoldingEvent e1(EventSet(), std::make_shared<IndependentAction>());
801     UnfoldingEvent e2(EventSet({&e1}), std::make_shared<IndependentAction>());
802     UnfoldingEvent e3(EventSet({&e2}), std::make_shared<IndependentAction>());
803     UnfoldingEvent e4(EventSet({&e2}), std::make_shared<IndependentAction>());
804     UnfoldingEvent e5(EventSet({&e1}), std::make_shared<IndependentAction>());
805     UnfoldingEvent e6(EventSet({&e5}), std::make_shared<IndependentAction>());
806
807     // 6 choose 0 = 1 test
808     CHECK(EventSet().is_conflict_free());
809
810     // 6 choose 1 = 6 tests
811     CHECK(EventSet({&e1}).is_conflict_free());
812     CHECK(EventSet({&e2}).is_conflict_free());
813     CHECK(EventSet({&e3}).is_conflict_free());
814     CHECK(EventSet({&e4}).is_conflict_free());
815     CHECK(EventSet({&e5}).is_conflict_free());
816     CHECK(EventSet({&e6}).is_conflict_free());
817
818     // 6 choose 2 = 15 tests
819     CHECK(EventSet({&e1, &e2}).is_conflict_free());
820     CHECK(EventSet({&e1, &e3}).is_conflict_free());
821     CHECK(EventSet({&e1, &e4}).is_conflict_free());
822     CHECK(EventSet({&e1, &e5}).is_conflict_free());
823     CHECK(EventSet({&e1, &e6}).is_conflict_free());
824     CHECK(EventSet({&e2, &e3}).is_conflict_free());
825     CHECK(EventSet({&e2, &e4}).is_conflict_free());
826     CHECK(EventSet({&e2, &e5}).is_conflict_free());
827     CHECK(EventSet({&e2, &e6}).is_conflict_free());
828     CHECK(EventSet({&e3, &e4}).is_conflict_free());
829     CHECK(EventSet({&e3, &e5}).is_conflict_free());
830     CHECK(EventSet({&e3, &e6}).is_conflict_free());
831     CHECK(EventSet({&e4, &e5}).is_conflict_free());
832     CHECK(EventSet({&e4, &e6}).is_conflict_free());
833     CHECK(EventSet({&e5, &e6}).is_conflict_free());
834
835     // 6 choose 3 = 20 tests
836     CHECK(EventSet({&e1, &e2, &e3}).is_conflict_free());
837     CHECK(EventSet({&e1, &e2, &e4}).is_conflict_free());
838     CHECK(EventSet({&e1, &e2, &e5}).is_conflict_free());
839     CHECK(EventSet({&e1, &e2, &e6}).is_conflict_free());
840     CHECK(EventSet({&e1, &e3, &e4}).is_conflict_free());
841     CHECK(EventSet({&e1, &e3, &e5}).is_conflict_free());
842     CHECK(EventSet({&e1, &e3, &e6}).is_conflict_free());
843     CHECK(EventSet({&e1, &e4, &e5}).is_conflict_free());
844     CHECK(EventSet({&e1, &e4, &e6}).is_conflict_free());
845     CHECK(EventSet({&e1, &e5, &e6}).is_conflict_free());
846     CHECK(EventSet({&e2, &e3, &e4}).is_conflict_free());
847     CHECK(EventSet({&e2, &e3, &e5}).is_conflict_free());
848     CHECK(EventSet({&e2, &e3, &e6}).is_conflict_free());
849     CHECK(EventSet({&e2, &e4, &e5}).is_conflict_free());
850     CHECK(EventSet({&e2, &e4, &e6}).is_conflict_free());
851     CHECK(EventSet({&e2, &e5, &e6}).is_conflict_free());
852     CHECK(EventSet({&e3, &e4, &e5}).is_conflict_free());
853     CHECK(EventSet({&e3, &e4, &e6}).is_conflict_free());
854     CHECK(EventSet({&e3, &e5, &e6}).is_conflict_free());
855     CHECK(EventSet({&e4, &e5, &e6}).is_conflict_free());
856
857     // 6 choose 4 = 15 tests
858     CHECK(EventSet({&e1, &e2, &e3, &e4}).is_conflict_free());
859     CHECK(EventSet({&e1, &e2, &e3, &e5}).is_conflict_free());
860     CHECK(EventSet({&e1, &e2, &e3, &e6}).is_conflict_free());
861     CHECK(EventSet({&e1, &e2, &e4, &e5}).is_conflict_free());
862     CHECK(EventSet({&e1, &e2, &e4, &e6}).is_conflict_free());
863     CHECK(EventSet({&e1, &e2, &e5, &e6}).is_conflict_free());
864     CHECK(EventSet({&e1, &e3, &e4, &e5}).is_conflict_free());
865     CHECK(EventSet({&e1, &e3, &e4, &e6}).is_conflict_free());
866     CHECK(EventSet({&e1, &e3, &e5, &e6}).is_conflict_free());
867     CHECK(EventSet({&e1, &e4, &e5, &e6}).is_conflict_free());
868     CHECK(EventSet({&e2, &e3, &e4, &e5}).is_conflict_free());
869     CHECK(EventSet({&e2, &e3, &e4, &e6}).is_conflict_free());
870     CHECK(EventSet({&e2, &e3, &e5, &e6}).is_conflict_free());
871     CHECK(EventSet({&e2, &e4, &e5, &e6}).is_conflict_free());
872     CHECK(EventSet({&e3, &e4, &e5, &e6}).is_conflict_free());
873
874     // 6 choose 5 = 6 tests
875     CHECK(EventSet({&e1, &e2, &e3, &e4, &e5}).is_conflict_free());
876     CHECK(EventSet({&e1, &e2, &e3, &e4, &e6}).is_conflict_free());
877     CHECK(EventSet({&e1, &e2, &e3, &e5, &e6}).is_conflict_free());
878     CHECK(EventSet({&e1, &e2, &e4, &e5, &e6}).is_conflict_free());
879     CHECK(EventSet({&e1, &e3, &e4, &e5, &e6}).is_conflict_free());
880     CHECK(EventSet({&e2, &e3, &e4, &e5, &e6}).is_conflict_free());
881
882     // 6 choose 6 = 1 test
883     CHECK(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_conflict_free());
884   }
885
886   SECTION("Conflicts throughout the whole structure with dependent actions (except with DFS sets)")
887   {
888     // Since all actions are dependent, if a set contains a "fork" or divergent histories,
889     // we expect the collections to contain conflicts
890     UnfoldingEvent e1(EventSet(), std::make_shared<DependentAction>());
891     UnfoldingEvent e2(EventSet({&e1}), std::make_shared<DependentAction>());
892     UnfoldingEvent e3(EventSet({&e2}), std::make_shared<DependentAction>());
893     UnfoldingEvent e4(EventSet({&e2}), std::make_shared<DependentAction>());
894     UnfoldingEvent e5(EventSet({&e1}), std::make_shared<DependentAction>());
895     UnfoldingEvent e6(EventSet({&e5}), std::make_shared<DependentAction>());
896
897     // 6 choose 0 = 1 test
898     // There are no events even to be in conflict with
899     CHECK(EventSet().is_conflict_free());
900
901     // 6 choose 1 = 6 tests
902     // Sets of size 1 should have no conflicts
903     CHECK(EventSet({&e1}).is_conflict_free());
904     CHECK(EventSet({&e2}).is_conflict_free());
905     CHECK(EventSet({&e3}).is_conflict_free());
906     CHECK(EventSet({&e4}).is_conflict_free());
907     CHECK(EventSet({&e5}).is_conflict_free());
908     CHECK(EventSet({&e6}).is_conflict_free());
909
910     // 6 choose 2 = 15 tests
911     CHECK(EventSet({&e1, &e2}).is_conflict_free());
912     CHECK(EventSet({&e1, &e3}).is_conflict_free());
913     CHECK(EventSet({&e1, &e4}).is_conflict_free());
914     CHECK(EventSet({&e1, &e5}).is_conflict_free());
915     CHECK(EventSet({&e1, &e6}).is_conflict_free());
916     CHECK(EventSet({&e2, &e3}).is_conflict_free());
917     CHECK(EventSet({&e2, &e4}).is_conflict_free());
918     CHECK_FALSE(EventSet({&e2, &e5}).is_conflict_free());
919     CHECK_FALSE(EventSet({&e2, &e6}).is_conflict_free());
920     CHECK_FALSE(EventSet({&e3, &e4}).is_conflict_free());
921     CHECK_FALSE(EventSet({&e3, &e5}).is_conflict_free());
922     CHECK_FALSE(EventSet({&e3, &e6}).is_conflict_free());
923     CHECK_FALSE(EventSet({&e4, &e5}).is_conflict_free());
924     CHECK_FALSE(EventSet({&e4, &e6}).is_conflict_free());
925     CHECK(EventSet({&e5, &e6}).is_conflict_free());
926
927     // 6 choose 3 = 20 tests
928     CHECK(EventSet({&e1, &e2, &e3}).is_conflict_free());
929     CHECK(EventSet({&e1, &e2, &e4}).is_conflict_free());
930     CHECK_FALSE(EventSet({&e1, &e2, &e5}).is_conflict_free());
931     CHECK_FALSE(EventSet({&e1, &e2, &e6}).is_conflict_free());
932     CHECK_FALSE(EventSet({&e1, &e3, &e4}).is_conflict_free());
933     CHECK_FALSE(EventSet({&e1, &e3, &e5}).is_conflict_free());
934     CHECK_FALSE(EventSet({&e1, &e3, &e6}).is_conflict_free());
935     CHECK_FALSE(EventSet({&e1, &e4, &e5}).is_conflict_free());
936     CHECK_FALSE(EventSet({&e1, &e4, &e6}).is_conflict_free());
937     CHECK(EventSet({&e1, &e5, &e6}).is_conflict_free());
938     CHECK_FALSE(EventSet({&e2, &e3, &e4}).is_conflict_free());
939     CHECK_FALSE(EventSet({&e2, &e3, &e5}).is_conflict_free());
940     CHECK_FALSE(EventSet({&e2, &e3, &e6}).is_conflict_free());
941     CHECK_FALSE(EventSet({&e2, &e4, &e5}).is_conflict_free());
942     CHECK_FALSE(EventSet({&e2, &e4, &e6}).is_conflict_free());
943     CHECK_FALSE(EventSet({&e2, &e5, &e6}).is_conflict_free());
944     CHECK_FALSE(EventSet({&e3, &e4, &e5}).is_conflict_free());
945     CHECK_FALSE(EventSet({&e3, &e4, &e6}).is_conflict_free());
946     CHECK_FALSE(EventSet({&e3, &e5, &e6}).is_conflict_free());
947     CHECK_FALSE(EventSet({&e4, &e5, &e6}).is_conflict_free());
948
949     // 6 choose 4 = 15 tests
950     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4}).is_conflict_free());
951     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e5}).is_conflict_free());
952     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_conflict_free());
953     CHECK_FALSE(EventSet({&e1, &e2, &e4, &e5}).is_conflict_free());
954     CHECK_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_conflict_free());
955     CHECK_FALSE(EventSet({&e1, &e2, &e5, &e6}).is_conflict_free());
956     CHECK_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_conflict_free());
957     CHECK_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_conflict_free());
958     CHECK_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_conflict_free());
959     CHECK_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_conflict_free());
960     CHECK_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_conflict_free());
961     CHECK_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_conflict_free());
962     CHECK_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_conflict_free());
963     CHECK_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_conflict_free());
964     CHECK_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_conflict_free());
965
966     // 6 choose 5 = 6 tests
967     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_conflict_free());
968     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_conflict_free());
969     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_conflict_free());
970     CHECK_FALSE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_conflict_free());
971     CHECK_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_conflict_free());
972     CHECK_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_conflict_free());
973
974     // 6 choose 6 = 1 test
975     CHECK_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_conflict_free());
976   }
977 }