Storm
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>> {
694 size_t operator()(storm::dft::storage::BEColourClass<ValueType> const& bcc) const {
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 }
719 groupHash |= static_cast<uint_fast64_t>(bcc.nrParents) & eightbitmask;
720 return groupHash;
721 }
722};
723
724} // 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
std::shared_ptr< storm::dft::storage::elements::DFTDependency< ValueType > const > getDependency(size_t index) const
Definition DFT.h:223
std::shared_ptr< storm::dft::storage::elements::DFTBE< ValueType > const > getBasicElement(size_t index) const
Definition DFT.h:209
DFTElementCPointer getElement(size_t index) const
Get a pointer to an element in the DFT.
Definition DFT.h:188
size_t nrElements() const
Definition DFT.h:94
std::shared_ptr< storm::dft::storage::elements::DFTGate< ValueType > const > getGate(size_t index) const
Definition DFT.h:218
bool isDependency(size_t index) const
Definition DFT.h:201
bool isGate(size_t index) const
Definition DFT.h:197
std::shared_ptr< storm::dft::storage::elements::DFTRestriction< ValueType > const > getRestriction(size_t index) const
Definition DFT.h:228
bool isRestriction(size_t index) const
Definition DFT.h:205
bool isBasicElement(size_t index) const
Definition DFT.h:193
Saves isomorphism between subtrees.
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 DFT elements.
Definition DFTElement.h:39
Abstract base class for gates.
Definition DFTGate.h:13
Abstract base class for restrictions.
#define STORM_LOG_TRACE(message)
Definition logging.h:17
#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)
LabParser.cpp.
Definition cli.cpp:18
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