Storm 1.13.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 return false;
163 }
164
165 bool hasBE(size_t index) const {
166 for (auto const& x : beCandidates) {
167 for (auto const& ind : x.second) {
168 if (index == ind)
169 return true;
170 }
171 }
172 return false;
173 }
174
175 bool hasDep(size_t index) const {
176 for (auto const& x : pdepCandidates) {
177 for (auto const& ind : x.second) {
178 if (index == ind)
179 return true;
180 }
181 }
182 return false;
183 }
184
185 bool hasRestriction(size_t index) const {
186 for (auto const& x : restrictionCandidates) {
187 for (auto const& ind : x.second) {
188 if (index == ind)
189 return true;
190 }
191 }
192 return false;
193 }
194
195 bool has(size_t index) const {
196 return hasGate(index) || hasBE(index) || hasDep(index) || hasRestriction(index);
197 }
198
199 size_t trivialGateGroups() const {
200 size_t res = 0;
201 for (auto const& x : gateCandidates) {
202 if (x.second.size() == 1)
203 ++res;
204 }
205 return res;
206 }
207
208 size_t trivialBEGroups() const {
209 size_t res = 0;
210 for (auto const& x : beCandidates) {
211 if (x.second.size() == 1)
212 ++res;
213 }
214 return res;
215 }
216};
217
218template<typename ValueType>
220 DFT<ValueType> const& dft;
221 std::unordered_map<size_t, size_t> gateColour;
222 std::unordered_map<size_t, BEColourClass<ValueType>> beColour;
223 std::unordered_map<size_t, size_t> depColour;
224 std::unordered_map<size_t, size_t> restrictionColour;
225 GateGroupToHash gateColourizer;
226
227 public:
228 DFTColouring(DFT<ValueType> const& ft) : dft(ft) {
229 for (size_t id = 0; id < dft.nrElements(); ++id) {
230 if (dft.isBasicElement(id)) {
231 colourize(dft.getBasicElement(id));
232 } else if (dft.isGate(id)) {
233 colourize(dft.getGate(id));
234 } else if (dft.isDependency(id)) {
235 colourize(dft.getDependency(id));
236 } else {
237 STORM_LOG_ASSERT(dft.isRestriction(id), "Element is no restriction.");
238 colourize(dft.getRestriction(id));
239 }
240 }
241 }
242
243 bool hasSameColour(size_t index1, size_t index2) const {
244 return beColour.at(index1) == beColour.at(index2);
245 }
246
247 BijectionCandidates<ValueType> colourSubdft(std::vector<size_t> const& subDftIndices) const {
249 for (size_t index : subDftIndices) {
250 if (dft.isBasicElement(index)) {
251 auto it = res.beCandidates.find(beColour.at(index));
252 if (it != res.beCandidates.end()) {
253 it->second.push_back(index);
254 } else {
255 res.beCandidates[beColour.at(index)] = std::vector<size_t>({index});
256 }
257 } else if (dft.isGate(index)) {
258 auto it = res.gateCandidates.find(gateColour.at(index));
259 if (it != res.gateCandidates.end()) {
260 it->second.push_back(index);
261 } else {
262 res.gateCandidates[gateColour.at(index)] = std::vector<size_t>({index});
263 }
264 } else if (dft.isDependency(index)) {
265 auto it = res.pdepCandidates.find(depColour.at(index));
266 if (it != res.pdepCandidates.end()) {
267 it->second.push_back(index);
268 } else {
269 res.pdepCandidates[depColour.at(index)] = std::vector<size_t>({index});
270 }
271 } else {
272 STORM_LOG_ASSERT(dft.isRestriction(index), "Element is no restriction.");
273 auto it = res.restrictionCandidates.find(restrictionColour.at(index));
274 if (it != res.restrictionCandidates.end()) {
275 it->second.push_back(index);
276 } else {
277 res.restrictionCandidates[restrictionColour.at(index)] = std::vector<size_t>({index});
278 }
279 }
280 }
281 return res;
282 }
283
284 protected:
285 void colourize(std::shared_ptr<const storm::dft::storage::elements::DFTBE<ValueType>> const& be) {
286 switch (be->beType()) {
288 auto beConst = std::static_pointer_cast<storm::dft::storage::elements::BEConst<ValueType> const>(be);
289 beColour[beConst->id()] =
290 BEColourClass<ValueType>(beConst->beType(), beConst->failed(), beConst->nrParents(), beConst->nrOutgoingDependencies(),
291 beConst->nrIngoingDependencies(), beConst->nrRestrictions());
292 break;
293 }
295 auto beProb = std::static_pointer_cast<storm::dft::storage::elements::BEProbability<ValueType> const>(be);
296 beColour[beProb->id()] =
297 BEColourClass<ValueType>(beProb->beType(), beProb->activeFailureProbability(), beProb->passiveFailureProbability(), beProb->nrParents(),
298 beProb->nrOutgoingDependencies(), beProb->nrIngoingDependencies(), beProb->nrRestrictions());
299 break;
300 }
302 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType> const>(be);
303 beColour[beExp->id()] = BEColourClass<ValueType>(beExp->beType(), beExp->activeFailureRate(), beExp->passiveFailureRate(), beExp->nrParents(),
304 beExp->nrOutgoingDependencies(), beExp->nrIngoingDependencies(), beExp->nrRestrictions());
305 break;
306 }
308 auto beErlang = std::static_pointer_cast<storm::dft::storage::elements::BEErlang<ValueType> const>(be);
309 beColour[beErlang->id()] = BEColourClass<ValueType>(beErlang->beType(), beErlang->activeFailureRate(), beErlang->passiveFailureRate(),
310 beErlang->phases(), beErlang->nrParents(), beErlang->nrOutgoingDependencies(),
311 beErlang->nrIngoingDependencies(), beErlang->nrRestrictions());
312 break;
313 }
315 auto beLog = std::static_pointer_cast<storm::dft::storage::elements::BELogNormal<ValueType> const>(be);
316 beColour[beLog->id()] = BEColourClass<ValueType>(beLog->beType(), beLog->mean(), beLog->standardDeviation(), beLog->nrParents(),
317 beLog->nrOutgoingDependencies(), beLog->nrIngoingDependencies(), beLog->nrRestrictions());
318 break;
319 }
321 auto beWeibull = std::static_pointer_cast<storm::dft::storage::elements::BEWeibull<ValueType> const>(be);
322 beColour[beWeibull->id()] =
323 BEColourClass<ValueType>(beWeibull->beType(), beWeibull->shape(), beWeibull->rate(), beWeibull->nrParents(),
324 beWeibull->nrOutgoingDependencies(), beWeibull->nrIngoingDependencies(), beWeibull->nrRestrictions());
325 break;
326 }
328 auto beSamples = std::static_pointer_cast<storm::dft::storage::elements::BESamples<ValueType> const>(be);
329 beColour[beSamples->id()] = BEColourClass<ValueType>(beSamples->beType(), beSamples->nrParents(), beSamples->nrOutgoingDependencies(),
330 beSamples->nrIngoingDependencies(), beSamples->nrRestrictions());
331 break;
332 }
333 default:
334 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "BE of type '" << be->beType() << "' is not known.");
335 break;
336 }
337 }
338
339 void colourize(std::shared_ptr<const storm::dft::storage::elements::DFTGate<ValueType>> const& gate) {
340 STORM_LOG_TRACE("Colour " << gate->id() << ": " << gate->type() << " " << gate->nrChildren() << " " << gate->rank() << ".");
341 gateColour[gate->id()] =
342 gateColourizer(gate->type(), gate->nrChildren(), gate->nrParents(), gate->nrOutgoingDependencies(), gate->nrRestrictions(), gate->rank());
343 STORM_LOG_TRACE("Coloured " << gate->id() << " with " << gateColour[gate->id()] << ".");
344 }
345
347 STORM_LOG_TRACE("Colour " << dep->id() << ": " << dep->type() << " " << (1 + dep->dependentEvents().size()) << " " << dep->rank() << ".");
348 depColour[dep->id()] = gateColourizer(dep->type(), (1 + dep->dependentEvents().size()), 0, 0, 0, dep->rank());
349 STORM_LOG_TRACE("Coloured " << dep->id() << " with " << restrictionColour[dep->id()] << ".");
350 }
351
352 void colourize(std::shared_ptr<const storm::dft::storage::elements::DFTRestriction<ValueType>> const& restr) {
353 STORM_LOG_TRACE("Colour " << restr->id() << ": " << restr->type() << " " << restr->nrChildren() << " " << restr->rank() << ".");
354 restrictionColour[restr->id()] = gateColourizer(restr->type(), restr->nrChildren(), 0, 0, 0, restr->rank());
355 STORM_LOG_TRACE("Coloured " << restr->id() << " with " << restrictionColour[restr->id()] << ".");
356 }
357};
358
362template<typename ValueType>
367 BijectionCandidates<ValueType> const& bright;
369 bool candidatesCompatible = true;
371 std::map<size_t, size_t> bijection;
374 BijectionCandidates<ValueType> currentPermutations;
375 DFT<ValueType> const& dft;
376
377 public:
379 : bleft(left), bright(right), dft(dft) {
380 candidatesCompatible = checkCompatibility();
381 }
382
387 bool compatible() {
388 return candidatesCompatible;
389 }
390
396 std::map<size_t, size_t> const& getIsomorphism() const {
397 return bijection;
398 }
399
406 if (!candidatesCompatible) {
407 return false;
408 }
409 if (bijection.empty()) {
411 } else {
412 if (!findNextBijection()) {
413 return false;
414 }
415 }
416 while (!check()) {
417 // continue our search
418 if (!findNextBijection()) {
419 // No further bijections to check, no is
420 return false;
421 }
422 }
423 return true;
424 }
425
426 protected:
431 STORM_LOG_ASSERT(candidatesCompatible, "Candidates are not compatible.");
432 // We first construct the currentPermutations, which helps to determine the current state of the check.
433 initializePermutationsAndTreatTrivialGroups(bleft.beCandidates, bright.beCandidates, currentPermutations.beCandidates);
434 initializePermutationsAndTreatTrivialGroups(bleft.gateCandidates, bright.gateCandidates, currentPermutations.gateCandidates);
435 initializePermutationsAndTreatTrivialGroups(bleft.pdepCandidates, bright.pdepCandidates, currentPermutations.pdepCandidates);
436 initializePermutationsAndTreatTrivialGroups(bleft.restrictionCandidates, bright.restrictionCandidates, currentPermutations.restrictionCandidates);
437 STORM_LOG_TRACE(bijection.size() << " vs. " << bleft.size() << " vs. " << bright.size());
438 STORM_LOG_ASSERT(bijection.size() == bleft.size(), "No. of bijection elements do not match.");
439 }
440
446 STORM_LOG_ASSERT(candidatesCompatible, "Candidates are not compatible.");
447 bool foundNext = false;
448 if (!currentPermutations.beCandidates.empty()) {
449 auto it = currentPermutations.beCandidates.begin();
450 while (!foundNext && it != currentPermutations.beCandidates.end()) {
451 foundNext = std::next_permutation(it->second.begin(), it->second.end());
452 ++it;
453 }
454 }
455 if (!foundNext && !currentPermutations.gateCandidates.empty()) {
456 auto it = currentPermutations.gateCandidates.begin();
457 while (!foundNext && it != currentPermutations.gateCandidates.end()) {
458 foundNext = std::next_permutation(it->second.begin(), it->second.end());
459 ++it;
460 }
461 }
462
463 if (!foundNext && !currentPermutations.pdepCandidates.empty()) {
464 auto it = currentPermutations.pdepCandidates.begin();
465 while (!foundNext && it != currentPermutations.pdepCandidates.end()) {
466 foundNext = std::next_permutation(it->second.begin(), it->second.end());
467 ++it;
468 }
469 }
470
471 if (!foundNext && !currentPermutations.restrictionCandidates.empty()) {
472 auto it = currentPermutations.restrictionCandidates.begin();
473 while (!foundNext && it != currentPermutations.restrictionCandidates.end()) {
474 foundNext = std::next_permutation(it->second.begin(), it->second.end());
475 ++it;
476 }
477 }
478
479 if (foundNext) {
480 for (auto const& colour : bleft.beCandidates) {
481 if (colour.second.size() > 1) {
482 STORM_LOG_ASSERT(currentPermutations.beCandidates.find(colour.first) != currentPermutations.beCandidates.end(), "Colour not found.");
483 zipVectorsIntoMap(colour.second, currentPermutations.beCandidates.find(colour.first)->second, bijection);
484 }
485 }
486
487 for (auto const& colour : bleft.gateCandidates) {
488 if (colour.second.size() > 1) {
489 STORM_LOG_ASSERT(currentPermutations.gateCandidates.find(colour.first) != currentPermutations.gateCandidates.end(), "Colour not found.");
490 zipVectorsIntoMap(colour.second, currentPermutations.gateCandidates.find(colour.first)->second, bijection);
491 }
492 }
493
494 for (auto const& colour : bleft.pdepCandidates) {
495 if (colour.second.size() > 1) {
496 STORM_LOG_ASSERT(currentPermutations.pdepCandidates.find(colour.first) != currentPermutations.pdepCandidates.end(), "Colour not found.");
497 zipVectorsIntoMap(colour.second, currentPermutations.pdepCandidates.find(colour.first)->second, bijection);
498 }
499 }
500
501 for (auto const& colour : bleft.restrictionCandidates) {
502 if (colour.second.size() > 1) {
503 STORM_LOG_ASSERT(currentPermutations.restrictionCandidates.find(colour.first) != currentPermutations.restrictionCandidates.end(),
504 "Colour not found.");
505 zipVectorsIntoMap(colour.second, currentPermutations.restrictionCandidates.find(colour.first)->second, bijection);
506 }
507 }
508 }
509
510 return foundNext;
511 }
512
513 bool check() const {
514 // Perform additional checks not yet covered by the colouring
515 STORM_LOG_ASSERT(bijection.size() == bleft.size(), "No. of bijection elements do not match.");
516 for (auto const& indexpair : bijection) {
517 if (!dft.getElement(indexpair.first)->isTypeEqualTo(*dft.getElement(indexpair.second))) {
518 // In-depth type check failed, e.g. voting thresholds do not match
519 return false;
520 }
521 if (dft.getElement(indexpair.first)->isRelevant() || dft.getElement(indexpair.second)->isRelevant()) {
522 // Relevant events are not symmetric
523 return false;
524 }
525 if (dft.isGate(indexpair.first)) {
526 STORM_LOG_ASSERT(dft.isGate(indexpair.second), "Element is no gate.");
527 auto const& lGate = dft.getGate(indexpair.first);
528 auto const& rGate = dft.getGate(indexpair.second);
529 // Compare children for gates
530 if (!checkChildren(lGate->children(), rGate->children(), !lGate->isStaticElement())) {
531 return false;
532 }
533 } else if (dft.isDependency(indexpair.first)) {
534 STORM_LOG_ASSERT(dft.isDependency(indexpair.second), "Element is no dependency.");
535 auto const& lDep = dft.getDependency(indexpair.first);
536 auto const& rDep = dft.getDependency(indexpair.second);
537
538 if (bijection.at(lDep->triggerEvent()->id()) != rDep->triggerEvent()->id()) {
539 // Symmetric dependencies must have the same trigger event
540 return false;
541 }
542 if (!checkChildren(lDep->dependentEvents(), rDep->dependentEvents(), false)) {
543 // Symmetric dependencies must have the same dependent events
544 return false;
545 }
546 } else if (dft.isRestriction(indexpair.first)) {
547 STORM_LOG_ASSERT(dft.isRestriction(indexpair.second), "Element is no restriction.");
548 auto const& lRestr = dft.getRestriction(indexpair.first);
549 auto const& rRestr = dft.getRestriction(indexpair.second);
550 if (!checkChildren(lRestr->children(), rRestr->children(), lRestr->isSeqEnforcer())) {
551 // Symmetric restrictions must have the same children
552 // Order must be preserved for SEQ but not for MUTEX
553 return false;
554 }
555 } else {
556 STORM_LOG_ASSERT(dft.isBasicElement(indexpair.first), "Element is no BE.");
557 STORM_LOG_ASSERT(dft.isBasicElement(indexpair.second), "Element is no BE.");
558 // No operations required.
559 }
560 }
561 return true;
562 }
563
564 private:
571 template<typename ColourType>
572 bool checkCompatibility(std::unordered_map<ColourType, std::vector<size_t>> const& left, std::unordered_map<ColourType, std::vector<size_t>> const& right) {
573 if (left.size() != right.size()) {
574 // Different number of colour classes
575 return false;
576 }
577
578 for (auto const& gc : left) {
579 auto it = right.find(gc.first);
580 if (it == right.end()) {
581 // No corresponding colour
582 return false;
583 } else if (it->second.size() != gc.second.size()) {
584 // Corresponding colour classes have different number of elements
585 return false;
586 }
587 }
588 return true;
589 }
590
597 bool checkCompatibility() {
598 if (!checkCompatibility(bleft.gateCandidates, bright.gateCandidates)) {
599 return false;
600 }
601 if (!checkCompatibility(bleft.beCandidates, bright.beCandidates)) {
602 return false;
603 }
604 if (!checkCompatibility(bleft.pdepCandidates, bright.pdepCandidates)) {
605 return false;
606 }
607 if (!checkCompatibility(bleft.restrictionCandidates, bright.restrictionCandidates)) {
608 return false;
609 }
610 return true;
611 }
612
616 template<typename ColourType>
617 void initializePermutationsAndTreatTrivialGroups(std::unordered_map<ColourType, std::vector<size_t>> const& left,
618 std::unordered_map<ColourType, std::vector<size_t>> const& right,
619 std::unordered_map<ColourType, std::vector<size_t>>& permutations) {
620 for (auto const& colour : right) {
621 if (colour.second.size() > 1) {
622 auto it = permutations.insert(colour);
623 STORM_LOG_ASSERT(it.second, "Element already contained.");
624 std::sort(it.first->second.begin(), it.first->second.end());
625 zipVectorsIntoMap(left.at(colour.first), it.first->second, bijection);
626 } else {
627 STORM_LOG_ASSERT(colour.second.size() == 1, "No elements for colour.");
628 STORM_LOG_ASSERT(bijection.count(left.at(colour.first).front()) == 0, "Element already contained.");
629 bijection[left.at(colour.first).front()] = colour.second.front();
630 }
631 }
632 }
633
637 void zipVectorsIntoMap(std::vector<size_t> const& a, std::vector<size_t> const& b, std::map<size_t, size_t>& map) const {
638 // Assert should pass due to compatibility check
639 STORM_LOG_ASSERT(a.size() == b.size(), "Sizes do not match.");
640 auto it = b.cbegin();
641 for (size_t lIndex : a) {
642 map[lIndex] = *it;
643 ++it;
644 }
645 }
646
647 bool checkChildren(std::vector<std::shared_ptr<storm::dft::storage::elements::DFTElement<ValueType>>> const& left,
648 std::vector<std::shared_ptr<storm::dft::storage::elements::DFTElement<ValueType>>> const& right, bool ensureOrder) const {
649 if (ensureOrder) {
650 // Observe order of entries
651 size_t mappedId;
652 size_t rightId;
653 for (size_t i = 0; i < left.size(); ++i) {
654 if (bleft.has(left[i]->id())) {
655 mappedId = bijection.at(left[i]->id());
656 } else {
657 mappedId = -1;
658 }
659 if (bright.has(right[i]->id())) {
660 rightId = right[i]->id();
661 } else {
662 rightId = -1;
663 }
664 if (mappedId != rightId) {
665 return false;
666 }
667 }
668 return true;
669 } else {
670 // Order is irrelevant
671 std::set<size_t> mappedIds;
672 std::set<size_t> rightIds;
673 for (auto const& l : left) {
674 if (bleft.has(l->id())) {
675 mappedIds.insert(l->id());
676 }
677 }
678 for (auto const& r : right) {
679 if (bright.has(r->id())) {
680 rightIds.insert(r->id());
681 }
682 }
683 return mappedIds != rightIds;
684 }
685 }
686};
687
688} // namespace storage
689} // namespace storm::dft
690
691namespace std {
692template<typename ValueType>
693struct hash<storm::dft::storage::BEColourClass<ValueType>> {
695 constexpr uint_fast64_t fivebitmask = (1ul << 6) - 1ul;
696 constexpr uint_fast64_t eightbitmask = (1ul << 9) - 1ul;
697 constexpr uint_fast64_t fortybitmask = (1ul << 41) - 1ul;
698 std::hash<ValueType> hasher;
699 uint_fast64_t groupHash = static_cast<uint_fast64_t>(1) << 63;
700 groupHash |= (static_cast<uint_fast64_t>(bcc.type) & fivebitmask) << (62 - 5);
701
702 switch (bcc.type) {
704 groupHash |= (static_cast<uint_fast64_t>(bcc.failed) & fortybitmask) << 8;
705 break;
710 groupHash |= ((hasher(bcc.valueA) ^ hasher(bcc.valueB)) & fortybitmask) << 8;
711 break;
713 groupHash |= ((hasher(bcc.valueA) ^ hasher(bcc.valueB) ^ static_cast<uint_fast64_t>(bcc.phases)) & fortybitmask) << 8;
714 break;
716 // Samples have no dedicated hashing
717 break;
718 default:
719 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "BE of type '" << bcc.type << "' is not known.");
720 }
721 groupHash |= static_cast<uint_fast64_t>(bcc.nrParents) & eightbitmask;
722 return groupHash;
723 }
724};
725
726} // 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:52
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:12
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
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