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) {
168 for (
auto const& ind : x.second) {
179 for (
auto const& ind : x.second) {
190 for (
auto const& ind : x.second) {
199 bool has(
size_t index)
const {
206 if (x.second.size() == 1) {
216 if (x.second.size() == 1) {
224template<
typename ValueType>
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;
235 for (
size_t id = 0;
id < dft.nrElements(); ++id) {
236 if (dft.isBasicElement(
id)) {
238 }
else if (dft.isGate(
id)) {
240 }
else if (dft.isDependency(
id)) {
250 return beColour.at(index1) == beColour.at(index2);
255 for (
size_t index : subDftIndices) {
256 if (dft.isBasicElement(index)) {
259 it->second.push_back(index);
261 res.
beCandidates[beColour.at(index)] = std::vector<size_t>({index});
263 }
else if (dft.isGate(index)) {
266 it->second.push_back(index);
268 res.
gateCandidates[gateColour.at(index)] = std::vector<size_t>({index});
270 }
else if (dft.isDependency(index)) {
273 it->second.push_back(index);
275 res.
pdepCandidates[depColour.at(index)] = std::vector<size_t>({index});
281 it->second.push_back(index);
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());
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());
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());
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());
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());
327 auto beWeibull = std::static_pointer_cast<storm::dft::storage::elements::BEWeibull<ValueType>
const>(be);
328 beColour[beWeibull->id()] =
330 beWeibull->nrOutgoingDependencies(), beWeibull->nrIngoingDependencies(), beWeibull->nrRestrictions());
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());
340 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"BE of type '" << be->beType() <<
"' is not known.");
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()] <<
".");
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()] <<
".");
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()] <<
".");
368template<
typename ValueType>
375 bool candidatesCompatible =
true;
377 std::map<size_t, size_t> bijection;
385 : bleft(left), bright(right), dft(dft) {
386 candidatesCompatible = checkCompatibility();
394 return candidatesCompatible;
412 if (!candidatesCompatible) {
415 if (bijection.empty()) {
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.");
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());
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());
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());
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());
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);
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);
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);
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);
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))) {
527 if (dft.getElement(indexpair.first)->isRelevant() || dft.getElement(indexpair.second)->isRelevant()) {
531 if (dft.isGate(indexpair.first)) {
533 auto const& lGate = dft.getGate(indexpair.first);
534 auto const& rGate = dft.getGate(indexpair.second);
536 if (!checkChildren(lGate->children(), rGate->children(), !lGate->isStaticElement())) {
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);
544 if (bijection.at(lDep->triggerEvent()->id()) != rDep->triggerEvent()->id()) {
548 if (!checkChildren(lDep->dependentEvents(), rDep->dependentEvents(),
false)) {
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())) {
563 STORM_LOG_ASSERT(dft.isBasicElement(indexpair.second),
"Element is no BE.");
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()) {
584 for (
auto const& gc : left) {
585 auto it = right.find(gc.first);
586 if (it == right.end()) {
589 }
else if (it->second.size() != gc.second.size()) {
603 bool checkCompatibility() {
604 if (!checkCompatibility(bleft.gateCandidates, bright.gateCandidates)) {
607 if (!checkCompatibility(bleft.beCandidates, bright.beCandidates)) {
610 if (!checkCompatibility(bleft.pdepCandidates, bright.pdepCandidates)) {
613 if (!checkCompatibility(bleft.restrictionCandidates, bright.restrictionCandidates)) {
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);
630 std::sort(it.first->second.begin(), it.first->second.end());
631 zipVectorsIntoMap(left.at(colour.first), it.first->second, bijection);
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();
643 void zipVectorsIntoMap(std::vector<size_t>
const& a, std::vector<size_t>
const& b, std::map<size_t, size_t>& map)
const {
646 auto it = b.cbegin();
647 for (
size_t lIndex : a) {
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 {
659 for (
size_t i = 0;
i < left.size(); ++
i) {
660 if (bleft.has(left[i]->id())) {
661 mappedId = bijection.at(left[i]->
id());
665 if (bright.has(right[i]->id())) {
666 rightId = right[
i]->id();
670 if (mappedId != rightId) {
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());
684 for (
auto const& r : right) {
685 if (bright.has(r->id())) {
686 rightIds.insert(r->id());
689 return mappedIds != rightIds;
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);
710 groupHash |= (
static_cast<uint_fast64_t
>(bcc.
failed) & fortybitmask) << 8;
716 groupHash |= ((hasher(bcc.
valueA) ^ hasher(bcc.
valueB)) & fortybitmask) << 8;
719 groupHash |= ((hasher(bcc.
valueA) ^ hasher(bcc.
valueB) ^
static_cast<uint_fast64_t
>(bcc.
phases)) & fortybitmask) << 8;
725 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"BE of type '" << bcc.
type <<
"' is not known.");
727 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