Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
DFTIsomorphism.h
Go to the documentation of this file.
1#pragma once
2
3#include <unordered_map>
4#include <utility>
5#include <vector>
6
11
12namespace storm::dft {
13namespace storage {
14
16 static constexpr uint_fast64_t fivebitmask = (1 << 6) - 1;
17 static constexpr uint_fast64_t eightbitmask = (1 << 9) - 1;
18
22 uint_fast64_t operator()(storm::dft::storage::elements::DFTElementType type, size_t nrChildren, size_t nrParents, size_t nrPDEPs, size_t nrRestrictions,
23 size_t rank) const {
24 // Sets first bit to 1
25 uint_fast64_t groupHash = static_cast<uint_fast64_t>(1) << 63;
26 // Assumes 5 bits for the rank,
27 groupHash |= (static_cast<uint_fast64_t>(rank) & fivebitmask) << (62 - 5);
28 // 8 bits for the nrChildren
29 groupHash |= (static_cast<uint_fast64_t>(nrChildren) & eightbitmask) << (62 - 5 - 8);
30 // 5 bits for nrParents
31 groupHash |= (static_cast<uint_fast64_t>(nrParents) & fivebitmask) << (62 - 5 - 8 - 5);
32 // 5 bits for nrPDEPs
33 groupHash |= (static_cast<uint_fast64_t>(nrPDEPs) & fivebitmask) << (62 - 5 - 8 - 5 - 5);
34 // 5 bits for nrRestrictions
35 groupHash |= (static_cast<uint_fast64_t>(nrPDEPs) & fivebitmask) << (62 - 5 - 8 - 5 - 5 - 5);
36 // 5 bits for the type
37 groupHash |= (static_cast<uint_fast64_t>(type) & fivebitmask) << (62 - 5 - 8 - 5 - 5 - 5 - 5);
38 return groupHash;
39 }
40};
41
42template<typename ValueType>
44 BEColourClass() = default;
45
50
55
63
64 BEColourClass(storm::dft::storage::elements::BEType type, ValueType valA, ValueType valB, size_t phases, size_t nrParents, size_t nrOutDep, size_t nrInDep,
65 size_t nrRestrictions)
67 STORM_LOG_ASSERT(type == storm::dft::storage::elements::BEType::ERLANG, "Expected type ERLANG but got type " << type);
68 }
69
71 size_t nrParents;
72 size_t nrOutDep;
73 size_t nrInDep;
75 ValueType valueA; // Meaning of value depends on type (active rate/probability, mean, shape)
76 ValueType valueB; // Meaning of value depends on type (passive rate/probability, stddev, rate)
77 bool failed; // For constant BE
78 size_t phases; // For Erlang BE
79};
80
81template<typename ValueType>
83 if (lhs.type != rhs.type) {
84 return false;
85 }
86 if (lhs.nrParents != rhs.nrParents || lhs.nrOutDep != rhs.nrOutDep || lhs.nrInDep != rhs.nrInDep || lhs.nrRestrictions != rhs.nrRestrictions) {
87 return false;
88 }
89 switch (lhs.type) {
91 return lhs.failed == rhs.failed;
96 return lhs.valueA == rhs.valueA && lhs.valueB == rhs.valueB;
98 return lhs.valueA == rhs.valueA && lhs.valueA == rhs.valueB && lhs.phases == rhs.phases;
100 // Samples are not compared and always assumed to be non-symmetric
101 return false;
102 default:
103 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "BE of type '" << lhs.type << "' is not known.");
104 break;
105 }
106}
107
108template<typename ValueType>
110 std::unordered_map<size_t, std::vector<size_t>> gateCandidates;
111 std::unordered_map<BEColourClass<ValueType>, std::vector<size_t>> beCandidates;
112 std::unordered_map<size_t, std::vector<size_t>> pdepCandidates;
113 std::unordered_map<size_t, std::vector<size_t>> restrictionCandidates;
114
115 size_t nrGroups() const {
116 return gateCandidates.size() + beCandidates.size() + pdepCandidates.size() + restrictionCandidates.size();
117 }
118
119 size_t size() const {
120 return nrGates() + nrBEs() + nrDeps() + nrRestrictions();
121 }
122
123 size_t nrGates() const {
124 size_t res = 0;
125 for (auto const& x : gateCandidates) {
126 res += x.second.size();
127 }
128 return res;
129 }
130
131 size_t nrBEs() const {
132 size_t res = 0;
133 for (auto const& x : beCandidates) {
134 res += x.second.size();
135 }
136 return res;
137 }
138
139 size_t nrDeps() const {
140 size_t res = 0;
141 for (auto const& x : pdepCandidates) {
142 res += x.second.size();
143 }
144 return res;
145 }
146
147 size_t nrRestrictions() const {
148 size_t res = 0;
149 for (auto const& x : restrictionCandidates) {
150 res += x.second.size();
151 }
152 return res;
153 }
154
155 bool hasGate(size_t index) const {
156 for (auto const& x : gateCandidates) {
157 for (auto const& ind : x.second) {
158 if (index == ind) {
159 return true;
160 }
161 }
162 }
163 return false;
164 }
165
166 bool hasBE(size_t index) const {
167 for (auto const& x : beCandidates) {
168 for (auto const& ind : x.second) {
169 if (index == ind) {
170 return true;
171 }
172 }
173 }
174 return false;
175 }
176
177 bool hasDep(size_t index) const {
178 for (auto const& x : pdepCandidates) {
179 for (auto const& ind : x.second) {
180 if (index == ind) {
181 return true;
182 }
183 }
184 }
185 return false;
186 }
187
188 bool hasRestriction(size_t index) const {
189 for (auto const& x : restrictionCandidates) {
190 for (auto const& ind : x.second) {
191 if (index == ind) {
192 return true;
193 }
194 }
195 }
196 return false;
197 }
198
199 bool has(size_t index) const {
200 return hasGate(index) || hasBE(index) || hasDep(index) || hasRestriction(index);
201 }
202
203 size_t trivialGateGroups() const {
204 size_t res = 0;
205 for (auto const& x : gateCandidates) {
206 if (x.second.size() == 1) {
207 ++res;
208 }
209 }
210 return res;
211 }
212
213 size_t trivialBEGroups() const {
214 size_t res = 0;
215 for (auto const& x : beCandidates) {
216 if (x.second.size() == 1) {
217 ++res;
218 }
219 }
220 return res;
221 }
222};
223
224template<typename ValueType>
226 DFT<ValueType> const& dft;
227 std::unordered_map<size_t, size_t> gateColour;
228 std::unordered_map<size_t, BEColourClass<ValueType>> beColour;
229 std::unordered_map<size_t, size_t> depColour;
230 std::unordered_map<size_t, size_t> restrictionColour;
231 GateGroupToHash gateColourizer;
232
233 public:
234 DFTColouring(DFT<ValueType> const& ft) : dft(ft) {
235 for (size_t id = 0; id < dft.nrElements(); ++id) {
236 if (dft.isBasicElement(id)) {
237 colourize(dft.getBasicElement(id));
238 } else if (dft.isGate(id)) {
239 colourize(dft.getGate(id));
240 } else if (dft.isDependency(id)) {
241 colourize(dft.getDependency(id));
242 } else {
243 STORM_LOG_ASSERT(dft.isRestriction(id), "Element is no restriction.");
244 colourize(dft.getRestriction(id));
245 }
246 }
247 }
248
249 bool hasSameColour(size_t index1, size_t index2) const {
250 return beColour.at(index1) == beColour.at(index2);
251 }
252
253 BijectionCandidates<ValueType> colourSubdft(std::vector<size_t> const& subDftIndices) const {
255 for (size_t index : subDftIndices) {
256 if (dft.isBasicElement(index)) {
257 auto it = res.beCandidates.find(beColour.at(index));
258 if (it != res.beCandidates.end()) {
259 it->second.push_back(index);
260 } else {
261 res.beCandidates[beColour.at(index)] = std::vector<size_t>({index});
262 }
263 } else if (dft.isGate(index)) {
264 auto it = res.gateCandidates.find(gateColour.at(index));
265 if (it != res.gateCandidates.end()) {
266 it->second.push_back(index);
267 } else {
268 res.gateCandidates[gateColour.at(index)] = std::vector<size_t>({index});
269 }
270 } else if (dft.isDependency(index)) {
271 auto it = res.pdepCandidates.find(depColour.at(index));
272 if (it != res.pdepCandidates.end()) {
273 it->second.push_back(index);
274 } else {
275 res.pdepCandidates[depColour.at(index)] = std::vector<size_t>({index});
276 }
277 } else {
278 STORM_LOG_ASSERT(dft.isRestriction(index), "Element is no restriction.");
279 auto it = res.restrictionCandidates.find(restrictionColour.at(index));
280 if (it != res.restrictionCandidates.end()) {
281 it->second.push_back(index);
282 } else {
283 res.restrictionCandidates[restrictionColour.at(index)] = std::vector<size_t>({index});
284 }
285 }
286 }
287 return res;
288 }
289
290 protected:
291 void colourize(std::shared_ptr<const storm::dft::storage::elements::DFTBE<ValueType>> const& be) {
292 switch (be->beType()) {
294 auto beConst = std::static_pointer_cast<storm::dft::storage::elements::BEConst<ValueType> const>(be);
295 beColour[beConst->id()] =
296 BEColourClass<ValueType>(beConst->beType(), beConst->failed(), beConst->nrParents(), beConst->nrOutgoingDependencies(),
297 beConst->nrIngoingDependencies(), beConst->nrRestrictions());
298 break;
299 }
301 auto beProb = std::static_pointer_cast<storm::dft::storage::elements::BEProbability<ValueType> const>(be);
302 beColour[beProb->id()] =
303 BEColourClass<ValueType>(beProb->beType(), beProb->activeFailureProbability(), beProb->passiveFailureProbability(), beProb->nrParents(),
304 beProb->nrOutgoingDependencies(), beProb->nrIngoingDependencies(), beProb->nrRestrictions());
305 break;
306 }
308 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType> const>(be);
309 beColour[beExp->id()] = BEColourClass<ValueType>(beExp->beType(), beExp->activeFailureRate(), beExp->passiveFailureRate(), beExp->nrParents(),
310 beExp->nrOutgoingDependencies(), beExp->nrIngoingDependencies(), beExp->nrRestrictions());
311 break;
312 }
314 auto beErlang = std::static_pointer_cast<storm::dft::storage::elements::BEErlang<ValueType> const>(be);
315 beColour[beErlang->id()] = BEColourClass<ValueType>(beErlang->beType(), beErlang->activeFailureRate(), beErlang->passiveFailureRate(),
316 beErlang->phases(), beErlang->nrParents(), beErlang->nrOutgoingDependencies(),
317 beErlang->nrIngoingDependencies(), beErlang->nrRestrictions());
318 break;
319 }
321 auto beLog = std::static_pointer_cast<storm::dft::storage::elements::BELogNormal<ValueType> const>(be);
322 beColour[beLog->id()] = BEColourClass<ValueType>(beLog->beType(), beLog->mean(), beLog->standardDeviation(), beLog->nrParents(),
323 beLog->nrOutgoingDependencies(), beLog->nrIngoingDependencies(), beLog->nrRestrictions());
324 break;
325 }
327 auto beWeibull = std::static_pointer_cast<storm::dft::storage::elements::BEWeibull<ValueType> const>(be);
328 beColour[beWeibull->id()] =
329 BEColourClass<ValueType>(beWeibull->beType(), beWeibull->shape(), beWeibull->rate(), beWeibull->nrParents(),
330 beWeibull->nrOutgoingDependencies(), beWeibull->nrIngoingDependencies(), beWeibull->nrRestrictions());
331 break;
332 }
334 auto beSamples = std::static_pointer_cast<storm::dft::storage::elements::BESamples<ValueType> const>(be);
335 beColour[beSamples->id()] = BEColourClass<ValueType>(beSamples->beType(), beSamples->nrParents(), beSamples->nrOutgoingDependencies(),
336 beSamples->nrIngoingDependencies(), beSamples->nrRestrictions());
337 break;
338 }
339 default:
340 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "BE of type '" << be->beType() << "' is not known.");
341 break;
342 }
343 }
344
345 void colourize(std::shared_ptr<const storm::dft::storage::elements::DFTGate<ValueType>> const& gate) {
346 STORM_LOG_TRACE("Colour " << gate->id() << ": " << gate->type() << " " << gate->nrChildren() << " " << gate->rank() << ".");
347 gateColour[gate->id()] =
348 gateColourizer(gate->type(), gate->nrChildren(), gate->nrParents(), gate->nrOutgoingDependencies(), gate->nrRestrictions(), gate->rank());
349 STORM_LOG_TRACE("Coloured " << gate->id() << " with " << gateColour[gate->id()] << ".");
350 }
351
353 STORM_LOG_TRACE("Colour " << dep->id() << ": " << dep->type() << " " << (1 + dep->dependentEvents().size()) << " " << dep->rank() << ".");
354 depColour[dep->id()] = gateColourizer(dep->type(), (1 + dep->dependentEvents().size()), 0, 0, 0, dep->rank());
355 STORM_LOG_TRACE("Coloured " << dep->id() << " with " << restrictionColour[dep->id()] << ".");
356 }
357
358 void colourize(std::shared_ptr<const storm::dft::storage::elements::DFTRestriction<ValueType>> const& restr) {
359 STORM_LOG_TRACE("Colour " << restr->id() << ": " << restr->type() << " " << restr->nrChildren() << " " << restr->rank() << ".");
360 restrictionColour[restr->id()] = gateColourizer(restr->type(), restr->nrChildren(), 0, 0, 0, restr->rank());
361 STORM_LOG_TRACE("Coloured " << restr->id() << " with " << restrictionColour[restr->id()] << ".");
362 }
363};
364
368template<typename ValueType>
373 BijectionCandidates<ValueType> const& bright;
375 bool candidatesCompatible = true;
377 std::map<size_t, size_t> bijection;
380 BijectionCandidates<ValueType> currentPermutations;
381 DFT<ValueType> const& dft;
382
383 public:
385 : bleft(left), bright(right), dft(dft) {
386 candidatesCompatible = checkCompatibility();
387 }
388
393 bool compatible() {
394 return candidatesCompatible;
395 }
396
402 std::map<size_t, size_t> const& getIsomorphism() const {
403 return bijection;
404 }
405
412 if (!candidatesCompatible) {
413 return false;
414 }
415 if (bijection.empty()) {
417 } else {
418 if (!findNextBijection()) {
419 return false;
420 }
421 }
422 while (!check()) {
423 // continue our search
424 if (!findNextBijection()) {
425 // No further bijections to check, no is
426 return false;
427 }
428 }
429 return true;
430 }
431
432 protected:
437 STORM_LOG_ASSERT(candidatesCompatible, "Candidates are not compatible.");
438 // We first construct the currentPermutations, which helps to determine the current state of the check.
439 initializePermutationsAndTreatTrivialGroups(bleft.beCandidates, bright.beCandidates, currentPermutations.beCandidates);
440 initializePermutationsAndTreatTrivialGroups(bleft.gateCandidates, bright.gateCandidates, currentPermutations.gateCandidates);
441 initializePermutationsAndTreatTrivialGroups(bleft.pdepCandidates, bright.pdepCandidates, currentPermutations.pdepCandidates);
442 initializePermutationsAndTreatTrivialGroups(bleft.restrictionCandidates, bright.restrictionCandidates, currentPermutations.restrictionCandidates);
443 STORM_LOG_TRACE(bijection.size() << " vs. " << bleft.size() << " vs. " << bright.size());
444 STORM_LOG_ASSERT(bijection.size() == bleft.size(), "No. of bijection elements do not match.");
445 }
446
452 STORM_LOG_ASSERT(candidatesCompatible, "Candidates are not compatible.");
453 bool foundNext = false;
454 if (!currentPermutations.beCandidates.empty()) {
455 auto it = currentPermutations.beCandidates.begin();
456 while (!foundNext && it != currentPermutations.beCandidates.end()) {
457 foundNext = std::next_permutation(it->second.begin(), it->second.end());
458 ++it;
459 }
460 }
461 if (!foundNext && !currentPermutations.gateCandidates.empty()) {
462 auto it = currentPermutations.gateCandidates.begin();
463 while (!foundNext && it != currentPermutations.gateCandidates.end()) {
464 foundNext = std::next_permutation(it->second.begin(), it->second.end());
465 ++it;
466 }
467 }
468
469 if (!foundNext && !currentPermutations.pdepCandidates.empty()) {
470 auto it = currentPermutations.pdepCandidates.begin();
471 while (!foundNext && it != currentPermutations.pdepCandidates.end()) {
472 foundNext = std::next_permutation(it->second.begin(), it->second.end());
473 ++it;
474 }
475 }
476
477 if (!foundNext && !currentPermutations.restrictionCandidates.empty()) {
478 auto it = currentPermutations.restrictionCandidates.begin();
479 while (!foundNext && it != currentPermutations.restrictionCandidates.end()) {
480 foundNext = std::next_permutation(it->second.begin(), it->second.end());
481 ++it;
482 }
483 }
484
485 if (foundNext) {
486 for (auto const& colour : bleft.beCandidates) {
487 if (colour.second.size() > 1) {
488 STORM_LOG_ASSERT(currentPermutations.beCandidates.find(colour.first) != currentPermutations.beCandidates.end(), "Colour not found.");
489 zipVectorsIntoMap(colour.second, currentPermutations.beCandidates.find(colour.first)->second, bijection);
490 }
491 }
492
493 for (auto const& colour : bleft.gateCandidates) {
494 if (colour.second.size() > 1) {
495 STORM_LOG_ASSERT(currentPermutations.gateCandidates.find(colour.first) != currentPermutations.gateCandidates.end(), "Colour not found.");
496 zipVectorsIntoMap(colour.second, currentPermutations.gateCandidates.find(colour.first)->second, bijection);
497 }
498 }
499
500 for (auto const& colour : bleft.pdepCandidates) {
501 if (colour.second.size() > 1) {
502 STORM_LOG_ASSERT(currentPermutations.pdepCandidates.find(colour.first) != currentPermutations.pdepCandidates.end(), "Colour not found.");
503 zipVectorsIntoMap(colour.second, currentPermutations.pdepCandidates.find(colour.first)->second, bijection);
504 }
505 }
506
507 for (auto const& colour : bleft.restrictionCandidates) {
508 if (colour.second.size() > 1) {
509 STORM_LOG_ASSERT(currentPermutations.restrictionCandidates.find(colour.first) != currentPermutations.restrictionCandidates.end(),
510 "Colour not found.");
511 zipVectorsIntoMap(colour.second, currentPermutations.restrictionCandidates.find(colour.first)->second, bijection);
512 }
513 }
514 }
515
516 return foundNext;
517 }
518
519 bool check() const {
520 // Perform additional checks not yet covered by the colouring
521 STORM_LOG_ASSERT(bijection.size() == bleft.size(), "No. of bijection elements do not match.");
522 for (auto const& indexpair : bijection) {
523 if (!dft.getElement(indexpair.first)->isTypeEqualTo(*dft.getElement(indexpair.second))) {
524 // In-depth type check failed, e.g. voting thresholds do not match
525 return false;
526 }
527 if (dft.getElement(indexpair.first)->isRelevant() || dft.getElement(indexpair.second)->isRelevant()) {
528 // Relevant events are not symmetric
529 return false;
530 }
531 if (dft.isGate(indexpair.first)) {
532 STORM_LOG_ASSERT(dft.isGate(indexpair.second), "Element is no gate.");
533 auto const& lGate = dft.getGate(indexpair.first);
534 auto const& rGate = dft.getGate(indexpair.second);
535 // Compare children for gates
536 if (!checkChildren(lGate->children(), rGate->children(), !lGate->isStaticElement())) {
537 return false;
538 }
539 } else if (dft.isDependency(indexpair.first)) {
540 STORM_LOG_ASSERT(dft.isDependency(indexpair.second), "Element is no dependency.");
541 auto const& lDep = dft.getDependency(indexpair.first);
542 auto const& rDep = dft.getDependency(indexpair.second);
543
544 if (bijection.at(lDep->triggerEvent()->id()) != rDep->triggerEvent()->id()) {
545 // Symmetric dependencies must have the same trigger event
546 return false;
547 }
548 if (!checkChildren(lDep->dependentEvents(), rDep->dependentEvents(), false)) {
549 // Symmetric dependencies must have the same dependent events
550 return false;
551 }
552 } else if (dft.isRestriction(indexpair.first)) {
553 STORM_LOG_ASSERT(dft.isRestriction(indexpair.second), "Element is no restriction.");
554 auto const& lRestr = dft.getRestriction(indexpair.first);
555 auto const& rRestr = dft.getRestriction(indexpair.second);
556 if (!checkChildren(lRestr->children(), rRestr->children(), lRestr->isSeqEnforcer())) {
557 // Symmetric restrictions must have the same children
558 // Order must be preserved for SEQ but not for MUTEX
559 return false;
560 }
561 } else {
562 STORM_LOG_ASSERT(dft.isBasicElement(indexpair.first), "Element is no BE.");
563 STORM_LOG_ASSERT(dft.isBasicElement(indexpair.second), "Element is no BE.");
564 // No operations required.
565 }
566 }
567 return true;
568 }
569
570 private:
577 template<typename ColourType>
578 bool checkCompatibility(std::unordered_map<ColourType, std::vector<size_t>> const& left, std::unordered_map<ColourType, std::vector<size_t>> const& right) {
579 if (left.size() != right.size()) {
580 // Different number of colour classes
581 return false;
582 }
583
584 for (auto const& gc : left) {
585 auto it = right.find(gc.first);
586 if (it == right.end()) {
587 // No corresponding colour
588 return false;
589 } else if (it->second.size() != gc.second.size()) {
590 // Corresponding colour classes have different number of elements
591 return false;
592 }
593 }
594 return true;
595 }
596
603 bool checkCompatibility() {
604 if (!checkCompatibility(bleft.gateCandidates, bright.gateCandidates)) {
605 return false;
606 }
607 if (!checkCompatibility(bleft.beCandidates, bright.beCandidates)) {
608 return false;
609 }
610 if (!checkCompatibility(bleft.pdepCandidates, bright.pdepCandidates)) {
611 return false;
612 }
613 if (!checkCompatibility(bleft.restrictionCandidates, bright.restrictionCandidates)) {
614 return false;
615 }
616 return true;
617 }
618
622 template<typename ColourType>
623 void initializePermutationsAndTreatTrivialGroups(std::unordered_map<ColourType, std::vector<size_t>> const& left,
624 std::unordered_map<ColourType, std::vector<size_t>> const& right,
625 std::unordered_map<ColourType, std::vector<size_t>>& permutations) {
626 for (auto const& colour : right) {
627 if (colour.second.size() > 1) {
628 auto it = permutations.insert(colour);
629 STORM_LOG_ASSERT(it.second, "Element already contained.");
630 std::sort(it.first->second.begin(), it.first->second.end());
631 zipVectorsIntoMap(left.at(colour.first), it.first->second, bijection);
632 } else {
633 STORM_LOG_ASSERT(colour.second.size() == 1, "No elements for colour.");
634 STORM_LOG_ASSERT(bijection.count(left.at(colour.first).front()) == 0, "Element already contained.");
635 bijection[left.at(colour.first).front()] = colour.second.front();
636 }
637 }
638 }
639
643 void zipVectorsIntoMap(std::vector<size_t> const& a, std::vector<size_t> const& b, std::map<size_t, size_t>& map) const {
644 // Assert should pass due to compatibility check
645 STORM_LOG_ASSERT(a.size() == b.size(), "Sizes do not match.");
646 auto it = b.cbegin();
647 for (size_t lIndex : a) {
648 map[lIndex] = *it;
649 ++it;
650 }
651 }
652
653 bool checkChildren(std::vector<std::shared_ptr<storm::dft::storage::elements::DFTElement<ValueType>>> const& left,
654 std::vector<std::shared_ptr<storm::dft::storage::elements::DFTElement<ValueType>>> const& right, bool ensureOrder) const {
655 if (ensureOrder) {
656 // Observe order of entries
657 size_t mappedId;
658 size_t rightId;
659 for (size_t i = 0; i < left.size(); ++i) {
660 if (bleft.has(left[i]->id())) {
661 mappedId = bijection.at(left[i]->id());
662 } else {
663 mappedId = -1;
664 }
665 if (bright.has(right[i]->id())) {
666 rightId = right[i]->id();
667 } else {
668 rightId = -1;
669 }
670 if (mappedId != rightId) {
671 return false;
672 }
673 }
674 return true;
675 } else {
676 // Order is irrelevant
677 std::set<size_t> mappedIds;
678 std::set<size_t> rightIds;
679 for (auto const& l : left) {
680 if (bleft.has(l->id())) {
681 mappedIds.insert(l->id());
682 }
683 }
684 for (auto const& r : right) {
685 if (bright.has(r->id())) {
686 rightIds.insert(r->id());
687 }
688 }
689 return mappedIds != rightIds;
690 }
691 }
692};
693
694} // namespace storage
695} // namespace storm::dft
696
697namespace std {
698template<typename ValueType>
699struct hash<storm::dft::storage::BEColourClass<ValueType>> {
701 constexpr uint_fast64_t fivebitmask = (1ul << 6) - 1ul;
702 constexpr uint_fast64_t eightbitmask = (1ul << 9) - 1ul;
703 constexpr uint_fast64_t fortybitmask = (1ul << 41) - 1ul;
704 std::hash<ValueType> hasher;
705 uint_fast64_t groupHash = static_cast<uint_fast64_t>(1) << 63;
706 groupHash |= (static_cast<uint_fast64_t>(bcc.type) & fivebitmask) << (62 - 5);
707
708 switch (bcc.type) {
710 groupHash |= (static_cast<uint_fast64_t>(bcc.failed) & fortybitmask) << 8;
711 break;
716 groupHash |= ((hasher(bcc.valueA) ^ hasher(bcc.valueB)) & fortybitmask) << 8;
717 break;
719 groupHash |= ((hasher(bcc.valueA) ^ hasher(bcc.valueB) ^ static_cast<uint_fast64_t>(bcc.phases)) & fortybitmask) << 8;
720 break;
722 // Samples have no dedicated hashing
723 break;
724 default:
725 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "BE of type '" << bcc.type << "' is not known.");
726 }
727 groupHash |= static_cast<uint_fast64_t>(bcc.nrParents) & eightbitmask;
728 return groupHash;
729 }
730};
731
732} // namespace std
void colourize(std::shared_ptr< const storm::dft::storage::elements::DFTDependency< ValueType > > const &dep)
void colourize(std::shared_ptr< const storm::dft::storage::elements::DFTGate< ValueType > > const &gate)
bool hasSameColour(size_t index1, size_t index2) const
DFTColouring(DFT< ValueType > const &ft)
void colourize(std::shared_ptr< const storm::dft::storage::elements::DFTRestriction< ValueType > > const &restr)
void colourize(std::shared_ptr< const storm::dft::storage::elements::DFTBE< ValueType > > const &be)
BijectionCandidates< ValueType > colourSubdft(std::vector< size_t > const &subDftIndices) const
Represents a Dynamic Fault Tree.
Definition DFT.h:49
bool compatible()
Checks whether the candidates are compatible, that is, checks the colours and the number of members f...
void constructInitialBijection()
Construct the initial bijection.
std::map< size_t, size_t > const & getIsomorphism() const
Returns the isomorphism Can only be called after the findIsomorphism procedure returned that an isomo...
bool findNextIsomorphism()
Check whether another isomorphism exists.
bool findNextBijection()
Construct the next bijection.
DFTIsomorphismCheck(BijectionCandidates< ValueType > const &left, BijectionCandidates< ValueType > const &right, DFT< ValueType > const &dft)
Abstract base class for basic events (BEs) in DFTs.
Definition DFTBE.h:14
Dependency gate with probability p.
Abstract base class for gates.
Definition DFTGate.h:13
Abstract base class for restrictions.
#define STORM_LOG_TRACE(message)
Definition logging.h:15
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
DFTElementType
Element types in a DFT.
bool operator==(BEColourClass< ValueType > const &lhs, BEColourClass< ValueType > const &rhs)
size_t operator()(storm::dft::storage::BEColourClass< ValueType > const &bcc) const
BEColourClass(storm::dft::storage::elements::BEType type, size_t nrParents, size_t nrOutDep, size_t nrInDep, size_t nrRestrictions)
BEColourClass(storm::dft::storage::elements::BEType type, ValueType valA, ValueType valB, size_t phases, size_t nrParents, size_t nrOutDep, size_t nrInDep, size_t nrRestrictions)
BEColourClass(storm::dft::storage::elements::BEType type, ValueType valA, ValueType valB, size_t nrParents, size_t nrOutDep, size_t nrInDep, size_t nrRestrictions)
storm::dft::storage::elements::BEType type
BEColourClass(storm::dft::storage::elements::BEType type, bool fail, size_t nrParents, size_t nrOutDep, size_t nrInDep, size_t nrRestrictions)
std::unordered_map< size_t, std::vector< size_t > > pdepCandidates
std::unordered_map< size_t, std::vector< size_t > > restrictionCandidates
std::unordered_map< size_t, std::vector< size_t > > gateCandidates
std::unordered_map< BEColourClass< ValueType >, std::vector< size_t > > beCandidates
static constexpr uint_fast64_t eightbitmask
uint_fast64_t operator()(storm::dft::storage::elements::DFTElementType type, size_t nrChildren, size_t nrParents, size_t nrPDEPs, size_t nrRestrictions, size_t rank) const
Hash function, which ensures that the colours are sorted according to their rank.
static constexpr uint_fast64_t fivebitmask