Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update .mailmap [ci-skip]
[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
10 using namespace simgrid::mc::udpor;
11
12 TEST_CASE("simgrid::mc::udpor::EventSet: Initial conditions when creating sets")
13 {
14   SECTION("Initialization with no elements")
15   {
16     SECTION("Default initializer")
17     {
18       EventSet event_set;
19       REQUIRE(event_set.size() == 0);
20       REQUIRE(event_set.empty());
21     }
22
23     SECTION("Set initializer")
24     {
25       EventSet event_set({});
26       REQUIRE(event_set.size() == 0);
27       REQUIRE(event_set.empty());
28     }
29
30     SECTION("List initialization")
31     {
32       EventSet event_set{};
33       REQUIRE(event_set.size() == 0);
34       REQUIRE(event_set.empty());
35     }
36   }
37
38   SECTION("Initialization with one or more elements")
39   {
40     UnfoldingEvent e1, e2, e3;
41
42     SECTION("Set initializer")
43     {
44       EventSet event_set({&e1, &e2, &e3});
45       REQUIRE(event_set.size() == 3);
46       REQUIRE(event_set.contains(&e1));
47       REQUIRE(event_set.contains(&e2));
48       REQUIRE(event_set.contains(&e3));
49       REQUIRE_FALSE(event_set.empty());
50     }
51
52     SECTION("List initialization")
53     {
54       UnfoldingEvent e1, e2, e3;
55       EventSet event_set{&e1, &e2, &e3};
56       REQUIRE(event_set.size() == 3);
57       REQUIRE(event_set.contains(&e1));
58       REQUIRE(event_set.contains(&e2));
59       REQUIRE(event_set.contains(&e3));
60       REQUIRE_FALSE(event_set.empty());
61     }
62   }
63 }
64
65 TEST_CASE("simgrid::mc::udpor::EventSet: Insertions")
66 {
67   EventSet event_set;
68   UnfoldingEvent e1, e2, e3;
69
70   SECTION("Inserting unique elements")
71   {
72     event_set.insert(&e1);
73     REQUIRE(event_set.size() == 1);
74     REQUIRE(event_set.contains(&e1));
75     REQUIRE_FALSE(event_set.empty());
76
77     event_set.insert(&e2);
78     REQUIRE(event_set.size() == 2);
79     REQUIRE(event_set.contains(&e2));
80     REQUIRE_FALSE(event_set.empty());
81
82     SECTION("Check contains inserted elements")
83     {
84       REQUIRE(event_set.contains(&e1));
85       REQUIRE(event_set.contains(&e2));
86       REQUIRE_FALSE(event_set.contains(&e3));
87     }
88   }
89
90   SECTION("Inserting duplicate elements")
91   {
92     event_set.insert(&e1);
93     REQUIRE(event_set.size() == 1);
94     REQUIRE(event_set.contains(&e1));
95     REQUIRE_FALSE(event_set.empty());
96
97     event_set.insert(&e1);
98     REQUIRE(event_set.size() == 1);
99     REQUIRE(event_set.contains(&e1));
100     REQUIRE_FALSE(event_set.empty());
101
102     SECTION("Check contains inserted elements")
103     {
104       REQUIRE(event_set.contains(&e1));
105       REQUIRE_FALSE(event_set.contains(&e2));
106       REQUIRE_FALSE(event_set.contains(&e3));
107     }
108   }
109 }
110
111 TEST_CASE("simgrid::mc::udpor::EventSet: Deletions")
112 {
113   UnfoldingEvent e1, e2, e3, e4;
114   EventSet event_set({&e1, &e2, &e3});
115
116   SECTION("Remove an element already present")
117   {
118     REQUIRE(event_set.contains(&e1));
119
120     // event_set = {e2, e3}
121     event_set.remove(&e1);
122
123     // Check that
124     // 1. the size decreases by exactly 1
125     // 2. the set remains unempty
126     // 3. the other elements are still contained in the set
127     REQUIRE(event_set.size() == 2);
128     REQUIRE_FALSE(event_set.contains(&e1));
129     REQUIRE(event_set.contains(&e2));
130     REQUIRE(event_set.contains(&e3));
131     REQUIRE_FALSE(event_set.empty());
132
133     SECTION("Remove a single element more than once")
134     {
135       // event_set = {e2, e3}
136       event_set.remove(&e1);
137       REQUIRE(event_set.size() == 2);
138       REQUIRE_FALSE(event_set.contains(&e1));
139       REQUIRE(event_set.contains(&e2));
140       REQUIRE(event_set.contains(&e3));
141       REQUIRE_FALSE(event_set.empty());
142     }
143
144     SECTION("Remove more than one element")
145     {
146       // event_set = {e3}
147       event_set.remove(&e2);
148
149       REQUIRE(event_set.size() == 1);
150       REQUIRE_FALSE(event_set.contains(&e1));
151       REQUIRE_FALSE(event_set.contains(&e2));
152       REQUIRE(event_set.contains(&e3));
153       REQUIRE_FALSE(event_set.empty());
154
155       // event_set = {}
156       event_set.remove(&e3);
157
158       REQUIRE(event_set.size() == 0);
159       REQUIRE_FALSE(event_set.contains(&e1));
160       REQUIRE_FALSE(event_set.contains(&e2));
161       REQUIRE_FALSE(event_set.contains(&e3));
162       REQUIRE(event_set.empty());
163     }
164   }
165
166   SECTION("Remove an element absent from the set")
167   {
168     REQUIRE_FALSE(event_set.contains(&e4));
169
170     // event_set = {e1, e2, e3}
171     event_set.remove(&e4);
172     REQUIRE(event_set.size() == 3);
173     REQUIRE(event_set.contains(&e1));
174     REQUIRE(event_set.contains(&e2));
175     REQUIRE(event_set.contains(&e3));
176
177     // Ensure e4 isn't somehow added
178     REQUIRE_FALSE(event_set.contains(&e4));
179     REQUIRE_FALSE(event_set.empty());
180   }
181 }
182
183 TEST_CASE("simgrid::mc::udpor::EventSet: Set Equality")
184 {
185   UnfoldingEvent e1, e2, e3, e4;
186   EventSet A{&e1, &e2, &e3}, B{&e1, &e2, &e3}, C{&e1, &e2, &e3};
187
188   SECTION("Equality implies containment")
189   {
190     REQUIRE(A == B);
191
192     for (const auto& e : A) {
193       REQUIRE(B.contains(e));
194     }
195
196     for (const auto& e : B) {
197       REQUIRE(A.contains(e));
198     }
199   }
200
201   SECTION("Containment implies equality")
202   {
203     for (const auto& e : A) {
204       REQUIRE(B.contains(e));
205     }
206
207     for (const auto& e : C) {
208       REQUIRE(C.contains(e));
209     }
210
211     REQUIRE(A == C);
212   }
213
214   SECTION("Equality is an equivalence relation")
215   {
216     // Reflexive
217     REQUIRE(A == A);
218     REQUIRE(B == B);
219     REQUIRE(C == C);
220
221     // Symmetric
222     REQUIRE(A == B);
223     REQUIRE(B == A);
224     REQUIRE(A == C);
225     REQUIRE(C == A);
226     REQUIRE(B == C);
227     REQUIRE(C == B);
228
229     // Transitive
230     REQUIRE(A == B);
231     REQUIRE(B == C);
232     REQUIRE(A == C);
233   }
234
235   SECTION("Equality after copy (assignment + constructor)")
236   {
237     EventSet A_copy = A;
238     EventSet A_copy2(A);
239
240     REQUIRE(A == A_copy);
241     REQUIRE(A == A_copy2);
242   }
243
244   SECTION("Equality after move constructor")
245   {
246     EventSet A_copy = A;
247     EventSet A_move(std::move(A));
248     REQUIRE(A_move == A_copy);
249   }
250
251   SECTION("Equality after move-assignment")
252   {
253     EventSet A_copy = A;
254     EventSet A_move = std::move(A);
255     REQUIRE(A_move == A_copy);
256   }
257 }
258
259 TEST_CASE("simgrid::mc::udpor::EventSet: Set Union Tests")
260 {
261   UnfoldingEvent e1, e2, e3, e4;
262
263   // C = A + B
264   EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e1, &e2, &e3, &e4}, D{&e1, &e3};
265
266   SECTION("Unions with no effect")
267   {
268     EventSet A_copy = A;
269
270     SECTION("Self union")
271     {
272       // A = A union A
273       EventSet A_union = A.make_union(A);
274       REQUIRE(A == A_copy);
275
276       A.form_union(A);
277       REQUIRE(A == A_copy);
278     }
279
280     SECTION("Union with empty set")
281     {
282       // A = A union empty set
283       EventSet A_union = A.make_union(EventSet());
284       REQUIRE(A == A_union);
285
286       A.form_union(EventSet());
287       REQUIRE(A == A_copy);
288     }
289
290     SECTION("Union with an equivalent set")
291     {
292       // A = A union B if B == A
293       EventSet A_equiv{&e1, &e2, &e3};
294       REQUIRE(A == A_equiv);
295
296       EventSet A_union = A.make_union(A_equiv);
297       REQUIRE(A_union == A_copy);
298
299       A.form_union(A_equiv);
300       REQUIRE(A == A_copy);
301     }
302
303     SECTION("Union with a subset")
304     {
305       // A = A union D if D is a subset of A
306       EventSet A_union = A.make_union(D);
307       REQUIRE(A == A_union);
308
309       A.form_union(D);
310       REQUIRE(A == A_copy);
311     }
312   }
313
314   SECTION("Unions with partial overlaps")
315   {
316     EventSet A_union_B = A.make_union(B);
317     REQUIRE(A_union_B == C);
318
319     A.form_union(B);
320     REQUIRE(A == C);
321
322     EventSet B_union_D = B.make_union(D);
323     REQUIRE(B_union_D == C);
324
325     B.form_union(D);
326     REQUIRE(B == C);
327   }
328
329   SECTION("Set union properties")
330   {
331     SECTION("Union operator is symmetric")
332     {
333       EventSet A_union_B = A.make_union(B);
334       EventSet B_union_A = B.make_union(A);
335       REQUIRE(A_union_B == B_union_A);
336     }
337
338     SECTION("Union operator commutes")
339     {
340       // The last SECTION tested pair-wise
341       // equivalence, so we only check
342       // one of each pai
343       EventSet AD = A.make_union(D);
344       EventSet AC = A.make_union(C);
345       EventSet CD = D.make_union(C);
346
347       EventSet ADC = AD.make_union(C);
348       EventSet ACD = AC.make_union(D);
349       EventSet CDA = CD.make_union(A);
350
351       REQUIRE(ADC == ACD);
352       REQUIRE(ACD == CDA);
353
354       // Test `form_union()` in the same way
355
356       EventSet A_copy = A;
357       EventSet C_copy = C;
358       EventSet D_copy = D;
359
360       A.form_union(C_copy);
361       A.form_union(D_copy);
362
363       D.form_union(A_copy);
364       D.form_union(C_copy);
365
366       C.form_union(A);
367       C.form_union(D);
368
369       REQUIRE(A == D);
370       REQUIRE(C == D);
371       REQUIRE(A == C);
372     }
373   }
374 }
375
376 TEST_CASE("simgrid::mc::udpor::EventSet: Set Difference Tests")
377 {
378   UnfoldingEvent e1, e2, e3, e4;
379
380   // C = A + B
381   // A is a subset of C
382   // B is a subset of C
383   // D is a subset of A and C
384   // E is a subset of B and C
385   // F is a subset of A, C, and D
386   EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e1, &e2, &e3, &e4}, D{&e1, &e3}, E{&e4}, F{&e1};
387
388   SECTION("Difference with no effect")
389   {
390     SECTION("Difference with empty set")
391     {
392       EventSet A_copy = A.subtracting(EventSet());
393       REQUIRE(A == A_copy);
394
395       A.subtract(EventSet());
396       REQUIRE(A == A_copy);
397     }
398
399     SECTION("Difference with empty intersection")
400     {
401       // A intersection E = empty set
402       EventSet A_copy = A.subtracting(E);
403       REQUIRE(A == A_copy);
404
405       A.subtract(E);
406       REQUIRE(A == A_copy);
407
408       EventSet D_copy = D.subtracting(E);
409       REQUIRE(D == D_copy);
410
411       D.subtract(E);
412       REQUIRE(D == D_copy);
413     }
414   }
415
416   SECTION("Difference with some overlap")
417   {
418     // A - B = {&e1} = F
419     EventSet A_minus_B = A.subtracting(B);
420     REQUIRE(A_minus_B == F);
421
422     // B - D = {&e2, &e4}
423     EventSet B_minus_D = B.subtracting(D);
424     REQUIRE(B_minus_D == EventSet({&e2, &e4}));
425   }
426
427   SECTION("Difference with complete overlap")
428   {
429     SECTION("Difference with same set gives empty set")
430     {
431       REQUIRE(A.subtracting(A) == EventSet());
432       REQUIRE(B.subtracting(B) == EventSet());
433       REQUIRE(C.subtracting(C) == EventSet());
434       REQUIRE(D.subtracting(D) == EventSet());
435       REQUIRE(E.subtracting(E) == EventSet());
436       REQUIRE(F.subtracting(F) == EventSet());
437     }
438
439     SECTION("Difference with superset gives empty set")
440     {
441       REQUIRE(A.subtracting(C) == EventSet());
442       REQUIRE(B.subtracting(C) == EventSet());
443       REQUIRE(D.subtracting(A) == EventSet());
444       REQUIRE(D.subtracting(C) == EventSet());
445       REQUIRE(E.subtracting(B) == EventSet());
446       REQUIRE(E.subtracting(C) == EventSet());
447       REQUIRE(F.subtracting(A) == EventSet());
448       REQUIRE(F.subtracting(C) == EventSet());
449       REQUIRE(F.subtracting(D) == EventSet());
450     }
451   }
452 }
453
454 TEST_CASE("simgrid::mc::udpor::EventSet: Subset Tests")
455 {
456   UnfoldingEvent e1, e2, e3, e4;
457
458   // A is a subset of C only
459   // B is a subset of C only
460   // D is a subset of C and A
461   // D is NOT a subset of B
462   // B is NOT a subset of D
463   // ...
464   EventSet A{&e1, &e2, &e3}, B{&e2, &e3, &e4}, C{&e1, &e2, &e3, &e4}, D{&e1, &e3}, E{&e2, &e3}, F{&e1, &e2, &e3};
465
466   SECTION("Subset operator properties")
467   {
468     SECTION("Subset operator is not commutative")
469     {
470       REQUIRE(A.is_subset_of(C));
471       REQUIRE_FALSE(C.is_subset_of(A));
472
473       SECTION("Commutativity implies equality and vice versa")
474       {
475         REQUIRE(A.is_subset_of(F));
476         REQUIRE(F.is_subset_of(A));
477         REQUIRE(A == F);
478
479         REQUIRE(C == C);
480         REQUIRE(A.is_subset_of(F));
481         REQUIRE(F.is_subset_of(A));
482       }
483     }
484
485     SECTION("Subset operator is transitive")
486     {
487       REQUIRE(D.is_subset_of(A));
488       REQUIRE(A.is_subset_of(C));
489       REQUIRE(D.is_subset_of(C));
490       REQUIRE(E.is_subset_of(B));
491       REQUIRE(B.is_subset_of(C));
492       REQUIRE(E.is_subset_of(C));
493     }
494
495     SECTION("Subset operator is reflexive")
496     {
497       REQUIRE(A.is_subset_of(A));
498       REQUIRE(B.is_subset_of(B));
499       REQUIRE(C.is_subset_of(C));
500       REQUIRE(D.is_subset_of(D));
501       REQUIRE(E.is_subset_of(E));
502       REQUIRE(F.is_subset_of(F));
503     }
504   }
505 }
506
507 TEST_CASE("simgrid::mc::udpor::EventSet: Testing Configurations")
508 {
509   // The following tests concern the given event structure:
510   //                e1
511   //              /    /
512   //            e2      e5
513   //           /  /      /
514   //          e3  e4     e6
515   // The tests enumerate all possible subsets of the events
516   // in the structure and test whether those subsets are
517   // maximal and/or valid configurations
518   UnfoldingEvent e1;
519   UnfoldingEvent e2{&e1}, e5{&e1};
520   UnfoldingEvent e3{&e2}, e4{&e2};
521   UnfoldingEvent e6{&e5};
522
523   SECTION("Valid Configurations")
524   {
525     SECTION("The empty set is valid")
526     {
527       REQUIRE(EventSet().is_valid_configuration());
528     }
529
530     SECTION("The set with only the root event is valid")
531     {
532       REQUIRE(EventSet({&e1}).is_valid_configuration());
533     }
534
535     SECTION("All sets of maximal events are valid configurations")
536     {
537       REQUIRE(EventSet({&e1}).is_valid_configuration());
538       REQUIRE(EventSet({&e1, &e2}).is_valid_configuration());
539       REQUIRE(EventSet({&e1, &e2, &e3}).is_valid_configuration());
540       REQUIRE(EventSet({&e1, &e2, &e4}).is_valid_configuration());
541       REQUIRE(EventSet({&e1, &e5}).is_valid_configuration());
542       REQUIRE(EventSet({&e1, &e5, &e6}).is_valid_configuration());
543       REQUIRE(EventSet({&e1, &e2, &e5}).is_valid_configuration());
544       REQUIRE(EventSet({&e1, &e2, &e5, &e6}).is_valid_configuration());
545       REQUIRE(EventSet({&e1, &e2, &e3, &e4}).is_valid_configuration());
546       REQUIRE(EventSet({&e1, &e2, &e3, &e5}).is_valid_configuration());
547       REQUIRE(EventSet({&e1, &e2, &e4, &e5}).is_valid_configuration());
548       REQUIRE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_valid_configuration());
549       REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_valid_configuration());
550       REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_valid_configuration());
551     }
552   }
553
554   SECTION("Configuration checks")
555   {
556     // 6 choose 0 = 1 test
557     REQUIRE(EventSet().is_valid_configuration());
558
559     // 6 choose 1 = 6 tests
560     REQUIRE(EventSet({&e1}).is_valid_configuration());
561     REQUIRE_FALSE(EventSet({&e2}).is_valid_configuration());
562     REQUIRE_FALSE(EventSet({&e3}).is_valid_configuration());
563     REQUIRE_FALSE(EventSet({&e4}).is_valid_configuration());
564     REQUIRE_FALSE(EventSet({&e5}).is_valid_configuration());
565     REQUIRE_FALSE(EventSet({&e6}).is_valid_configuration());
566
567     // 6 choose 2 = 15 tests
568     REQUIRE(EventSet({&e1, &e2}).is_valid_configuration());
569     REQUIRE_FALSE(EventSet({&e1, &e3}).is_valid_configuration());
570     REQUIRE_FALSE(EventSet({&e1, &e4}).is_valid_configuration());
571     REQUIRE(EventSet({&e1, &e5}).is_valid_configuration());
572     REQUIRE_FALSE(EventSet({&e1, &e6}).is_valid_configuration());
573     REQUIRE_FALSE(EventSet({&e2, &e3}).is_valid_configuration());
574     REQUIRE_FALSE(EventSet({&e2, &e4}).is_valid_configuration());
575     REQUIRE_FALSE(EventSet({&e2, &e5}).is_valid_configuration());
576     REQUIRE_FALSE(EventSet({&e2, &e6}).is_valid_configuration());
577     REQUIRE_FALSE(EventSet({&e3, &e4}).is_valid_configuration());
578     REQUIRE_FALSE(EventSet({&e3, &e5}).is_valid_configuration());
579     REQUIRE_FALSE(EventSet({&e3, &e6}).is_valid_configuration());
580     REQUIRE_FALSE(EventSet({&e4, &e5}).is_valid_configuration());
581     REQUIRE_FALSE(EventSet({&e4, &e6}).is_valid_configuration());
582     REQUIRE_FALSE(EventSet({&e5, &e6}).is_valid_configuration());
583
584     // 6 choose 3 = 20 tests
585     REQUIRE(EventSet({&e1, &e2, &e3}).is_valid_configuration());
586     REQUIRE(EventSet({&e1, &e2, &e4}).is_valid_configuration());
587     REQUIRE(EventSet({&e1, &e2, &e5}).is_valid_configuration());
588     REQUIRE_FALSE(EventSet({&e1, &e2, &e6}).is_valid_configuration());
589     REQUIRE_FALSE(EventSet({&e1, &e3, &e4}).is_valid_configuration());
590     REQUIRE_FALSE(EventSet({&e1, &e3, &e5}).is_valid_configuration());
591     REQUIRE_FALSE(EventSet({&e1, &e3, &e6}).is_valid_configuration());
592     REQUIRE_FALSE(EventSet({&e1, &e4, &e5}).is_valid_configuration());
593     REQUIRE_FALSE(EventSet({&e1, &e4, &e6}).is_valid_configuration());
594     REQUIRE(EventSet({&e1, &e5, &e6}).is_valid_configuration());
595     REQUIRE_FALSE(EventSet({&e2, &e3, &e4}).is_valid_configuration());
596     REQUIRE_FALSE(EventSet({&e2, &e3, &e5}).is_valid_configuration());
597     REQUIRE_FALSE(EventSet({&e2, &e3, &e6}).is_valid_configuration());
598     REQUIRE_FALSE(EventSet({&e2, &e4, &e5}).is_valid_configuration());
599     REQUIRE_FALSE(EventSet({&e2, &e4, &e6}).is_valid_configuration());
600     REQUIRE_FALSE(EventSet({&e2, &e5, &e6}).is_valid_configuration());
601     REQUIRE_FALSE(EventSet({&e3, &e4, &e5}).is_valid_configuration());
602     REQUIRE_FALSE(EventSet({&e3, &e4, &e6}).is_valid_configuration());
603     REQUIRE_FALSE(EventSet({&e3, &e5, &e6}).is_valid_configuration());
604     REQUIRE_FALSE(EventSet({&e4, &e5, &e6}).is_valid_configuration());
605
606     // 6 choose 4 = 15 tests
607     REQUIRE(EventSet({&e1, &e2, &e3, &e4}).is_valid_configuration());
608     REQUIRE(EventSet({&e1, &e2, &e3, &e5}).is_valid_configuration());
609     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_valid_configuration());
610     REQUIRE(EventSet({&e1, &e2, &e4, &e5}).is_valid_configuration());
611     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_valid_configuration());
612     REQUIRE(EventSet({&e1, &e2, &e5, &e6}).is_valid_configuration());
613     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_valid_configuration());
614     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_valid_configuration());
615     REQUIRE_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_valid_configuration());
616     REQUIRE_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_valid_configuration());
617     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_valid_configuration());
618     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_valid_configuration());
619     REQUIRE_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_valid_configuration());
620     REQUIRE_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_valid_configuration());
621     REQUIRE_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_valid_configuration());
622
623     // 6 choose 5 = 6 tests
624     REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_valid_configuration());
625     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_valid_configuration());
626     REQUIRE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_valid_configuration());
627     REQUIRE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_valid_configuration());
628     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_valid_configuration());
629     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_valid_configuration());
630
631     // 6 choose 6 = 1 test
632     REQUIRE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_valid_configuration());
633   }
634
635   SECTION("Maximal event sets")
636   {
637     // 6 choose 0 = 1 test
638     REQUIRE(EventSet().is_maximal_event_set());
639
640     // 6 choose 1 = 6 tests
641     REQUIRE(EventSet({&e1}).is_maximal_event_set());
642     REQUIRE(EventSet({&e2}).is_maximal_event_set());
643     REQUIRE(EventSet({&e3}).is_maximal_event_set());
644     REQUIRE(EventSet({&e4}).is_maximal_event_set());
645     REQUIRE(EventSet({&e5}).is_maximal_event_set());
646     REQUIRE(EventSet({&e6}).is_maximal_event_set());
647
648     // 6 choose 2 = 15 tests
649     REQUIRE_FALSE(EventSet({&e1, &e2}).is_maximal_event_set());
650     REQUIRE_FALSE(EventSet({&e1, &e3}).is_maximal_event_set());
651     REQUIRE_FALSE(EventSet({&e1, &e4}).is_maximal_event_set());
652     REQUIRE_FALSE(EventSet({&e1, &e5}).is_maximal_event_set());
653     REQUIRE_FALSE(EventSet({&e1, &e6}).is_maximal_event_set());
654     REQUIRE_FALSE(EventSet({&e2, &e3}).is_maximal_event_set());
655     REQUIRE_FALSE(EventSet({&e2, &e4}).is_maximal_event_set());
656     REQUIRE(EventSet({&e2, &e5}).is_maximal_event_set());
657     REQUIRE(EventSet({&e2, &e6}).is_maximal_event_set());
658     REQUIRE(EventSet({&e3, &e4}).is_maximal_event_set());
659     REQUIRE(EventSet({&e3, &e5}).is_maximal_event_set());
660     REQUIRE(EventSet({&e3, &e6}).is_maximal_event_set());
661     REQUIRE(EventSet({&e4, &e5}).is_maximal_event_set());
662     REQUIRE(EventSet({&e4, &e6}).is_maximal_event_set());
663     REQUIRE_FALSE(EventSet({&e5, &e6}).is_maximal_event_set());
664
665     // 6 choose 3 = 20 tests
666     REQUIRE_FALSE(EventSet({&e1, &e2, &e3}).is_maximal_event_set());
667     REQUIRE_FALSE(EventSet({&e1, &e2, &e4}).is_maximal_event_set());
668     REQUIRE_FALSE(EventSet({&e1, &e2, &e5}).is_maximal_event_set());
669     REQUIRE_FALSE(EventSet({&e1, &e2, &e6}).is_maximal_event_set());
670     REQUIRE_FALSE(EventSet({&e1, &e3, &e4}).is_maximal_event_set());
671     REQUIRE_FALSE(EventSet({&e1, &e3, &e5}).is_maximal_event_set());
672     REQUIRE_FALSE(EventSet({&e1, &e3, &e6}).is_maximal_event_set());
673     REQUIRE_FALSE(EventSet({&e1, &e4, &e5}).is_maximal_event_set());
674     REQUIRE_FALSE(EventSet({&e1, &e4, &e6}).is_maximal_event_set());
675     REQUIRE_FALSE(EventSet({&e1, &e5, &e6}).is_maximal_event_set());
676     REQUIRE_FALSE(EventSet({&e2, &e3, &e4}).is_maximal_event_set());
677     REQUIRE_FALSE(EventSet({&e2, &e3, &e5}).is_maximal_event_set());
678     REQUIRE_FALSE(EventSet({&e2, &e3, &e6}).is_maximal_event_set());
679     REQUIRE_FALSE(EventSet({&e2, &e4, &e5}).is_maximal_event_set());
680     REQUIRE_FALSE(EventSet({&e2, &e4, &e6}).is_maximal_event_set());
681     REQUIRE_FALSE(EventSet({&e2, &e5, &e6}).is_maximal_event_set());
682     REQUIRE(EventSet({&e3, &e4, &e5}).is_maximal_event_set());
683     REQUIRE(EventSet({&e3, &e4, &e6}).is_maximal_event_set());
684     REQUIRE_FALSE(EventSet({&e3, &e5, &e6}).is_maximal_event_set());
685     REQUIRE_FALSE(EventSet({&e4, &e5, &e6}).is_maximal_event_set());
686
687     // 6 choose 4 = 15 tests
688     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4}).is_maximal_event_set());
689     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e5}).is_maximal_event_set());
690     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e6}).is_maximal_event_set());
691     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e5}).is_maximal_event_set());
692     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e6}).is_maximal_event_set());
693     REQUIRE_FALSE(EventSet({&e1, &e2, &e5, &e6}).is_maximal_event_set());
694     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5}).is_maximal_event_set());
695     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e6}).is_maximal_event_set());
696     REQUIRE_FALSE(EventSet({&e1, &e3, &e5, &e6}).is_maximal_event_set());
697     REQUIRE_FALSE(EventSet({&e1, &e4, &e5, &e6}).is_maximal_event_set());
698     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5}).is_maximal_event_set());
699     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e6}).is_maximal_event_set());
700     REQUIRE_FALSE(EventSet({&e2, &e3, &e5, &e6}).is_maximal_event_set());
701     REQUIRE_FALSE(EventSet({&e2, &e4, &e5, &e6}).is_maximal_event_set());
702     REQUIRE_FALSE(EventSet({&e3, &e4, &e5, &e6}).is_maximal_event_set());
703
704     // 6 choose 5 = 6 tests
705     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5}).is_maximal_event_set());
706     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e6}).is_maximal_event_set());
707     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e5, &e6}).is_maximal_event_set());
708     REQUIRE_FALSE(EventSet({&e1, &e2, &e4, &e5, &e6}).is_maximal_event_set());
709     REQUIRE_FALSE(EventSet({&e1, &e3, &e4, &e5, &e6}).is_maximal_event_set());
710     REQUIRE_FALSE(EventSet({&e2, &e3, &e4, &e5, &e6}).is_maximal_event_set());
711
712     // 6 choose 6 = 1 test
713     REQUIRE_FALSE(EventSet({&e1, &e2, &e3, &e4, &e5, &e6}).is_maximal_event_set());
714   }
715 }