3#include <unordered_map>
25 uint_fast64_t groupHash =
static_cast<uint_fast64_t
>(1) << 63;
27 groupHash |= (
static_cast<uint_fast64_t
>(rank) &
fivebitmask) << (62 - 5);
29 groupHash |= (
static_cast<uint_fast64_t
>(nrChildren) &
eightbitmask) << (62 - 5 - 8);
31 groupHash |= (
static_cast<uint_fast64_t
>(nrParents) &
fivebitmask) << (62 - 5 - 8 - 5);
33 groupHash |= (
static_cast<uint_fast64_t
>(nrPDEPs) &
fivebitmask) << (62 - 5 - 8 - 5 - 5);
35 groupHash |= (
static_cast<uint_fast64_t
>(nrPDEPs) &
fivebitmask) << (62 - 5 - 8 - 5 - 5 - 5);
37 groupHash |= (
static_cast<uint_fast64_t
>(type) &
fivebitmask) << (62 - 5 - 8 - 5 - 5 - 5 - 5);
42template<
typename ValueType>
61 "Unexpected type " <<
type);
81template<
typename ValueType>
103 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"BE of type '" << lhs.
type <<
"' is not known.");
108template<
typename ValueType>
111 std::unordered_map<BEColourClass<ValueType>, std::vector<size_t>>
beCandidates;
126 res += x.second.size();
134 res += x.second.size();
142 res += x.second.size();
150 res += x.second.size();
157 for (
auto const& ind : x.second) {
167 for (
auto const& ind : x.second) {
177 for (
auto const& ind : x.second) {
187 for (
auto const& ind : x.second) {
195 bool has(
size_t index)
const {
202 if (x.second.size() == 1)
211 if (x.second.size() == 1)
218template<
typename ValueType>
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;
229 for (
size_t id = 0;
id < dft.nrElements(); ++id) {
230 if (dft.isBasicElement(
id)) {
232 }
else if (dft.isGate(
id)) {
234 }
else if (dft.isDependency(
id)) {
244 return beColour.at(index1) == beColour.at(index2);
249 for (
size_t index : subDftIndices) {
250 if (dft.isBasicElement(index)) {
253 it->second.push_back(index);
255 res.
beCandidates[beColour.at(index)] = std::vector<size_t>({index});
257 }
else if (dft.isGate(index)) {
260 it->second.push_back(index);
262 res.
gateCandidates[gateColour.at(index)] = std::vector<size_t>({index});
264 }
else if (dft.isDependency(index)) {
267 it->second.push_back(index);
269 res.
pdepCandidates[depColour.at(index)] = std::vector<size_t>({index});
275 it->second.push_back(index);
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());
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());
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());
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());
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());
321 auto beWeibull = std::static_pointer_cast<storm::dft::storage::elements::BEWeibull<ValueType>
const>(be);
322 beColour[beWeibull->id()] =
324 beWeibull->nrOutgoingDependencies(), beWeibull->nrIngoingDependencies(), beWeibull->nrRestrictions());
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());
334 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"BE of type '" << be->beType() <<
"' is not known.");
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()] <<
".");
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()] <<
".");
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()] <<
".");
362template<
typename ValueType>
369 bool candidatesCompatible =
true;
371 std::map<size_t, size_t> bijection;
379 : bleft(left), bright(right), dft(dft) {
380 candidatesCompatible = checkCompatibility();
388 return candidatesCompatible;
406 if (!candidatesCompatible) {
409 if (bijection.empty()) {
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.");
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());
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());
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());
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());
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);
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);
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);
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);
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))) {
521 if (dft.getElement(indexpair.first)->isRelevant() || dft.getElement(indexpair.second)->isRelevant()) {
525 if (dft.isGate(indexpair.first)) {
527 auto const& lGate = dft.getGate(indexpair.first);
528 auto const& rGate = dft.getGate(indexpair.second);
530 if (!checkChildren(lGate->children(), rGate->children(), !lGate->isStaticElement())) {
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);
538 if (bijection.at(lDep->triggerEvent()->id()) != rDep->triggerEvent()->id()) {
542 if (!checkChildren(lDep->dependentEvents(), rDep->dependentEvents(),
false)) {
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())) {
557 STORM_LOG_ASSERT(dft.isBasicElement(indexpair.second),
"Element is no BE.");
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()) {
578 for (
auto const& gc : left) {
579 auto it = right.find(gc.first);
580 if (it == right.end()) {
583 }
else if (it->second.size() != gc.second.size()) {
597 bool checkCompatibility() {
598 if (!checkCompatibility(bleft.gateCandidates, bright.gateCandidates)) {
601 if (!checkCompatibility(bleft.beCandidates, bright.beCandidates)) {
604 if (!checkCompatibility(bleft.pdepCandidates, bright.pdepCandidates)) {
607 if (!checkCompatibility(bleft.restrictionCandidates, bright.restrictionCandidates)) {
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);
624 std::sort(it.first->second.begin(), it.first->second.end());
625 zipVectorsIntoMap(left.at(colour.first), it.first->second, bijection);
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();
637 void zipVectorsIntoMap(std::vector<size_t>
const& a, std::vector<size_t>
const& b, std::map<size_t, size_t>& map)
const {
640 auto it = b.cbegin();
641 for (
size_t lIndex : a) {
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 {
653 for (
size_t i = 0;
i < left.size(); ++
i) {
654 if (bleft.has(left[i]->id())) {
655 mappedId = bijection.at(left[i]->
id());
659 if (bright.has(right[i]->id())) {
660 rightId = right[
i]->id();
664 if (mappedId != rightId) {
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());
678 for (
auto const& r : right) {
679 if (bright.has(r->id())) {
680 rightIds.insert(r->id());
683 return mappedIds != rightIds;
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);
704 groupHash |= (
static_cast<uint_fast64_t
>(bcc.
failed) & fortybitmask) << 8;
710 groupHash |= ((hasher(bcc.
valueA) ^ hasher(bcc.
valueB)) & fortybitmask) << 8;
713 groupHash |= ((hasher(bcc.
valueA) ^ hasher(bcc.
valueB) ^
static_cast<uint_fast64_t
>(bcc.
phases)) & fortybitmask) << 8;
719 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"BE of type '" << bcc.
type <<
"' is not known.");
721 groupHash |=
static_cast<uint_fast64_t
>(bcc.
nrParents) & eightbitmask;
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.
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.
Dependency gate with probability p.
Abstract base class for gates.
Abstract base class for restrictions.
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
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
bool has(size_t index) const
bool hasBE(size_t index) const
size_t nrRestrictions() const
bool hasDep(size_t index) const
bool hasGate(size_t index) const
size_t trivialGateGroups() const
size_t trivialBEGroups() const
bool hasRestriction(size_t index) const
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