Browse Source

update dft towards cnt.abst

Former-commit-id: bce7a7a566
main
sjunges 9 years ago
parent
commit
0a9f68ed74
  1. 40
      src/storage/dft/DFT.cpp
  2. 10
      src/storage/dft/DFT.h
  3. 205
      src/storage/dft/DFTIsomorphism.h
  4. 13
      src/utility/iota_n.h

40
src/storage/dft/DFT.cpp

@ -3,6 +3,9 @@
#include "DFT.h"
#include "src/exceptions/NotSupportedException.h"
#include "DFTIsomorphism.h"
#include "utility/iota_n.h"
namespace storm {
namespace storage {
@ -168,6 +171,43 @@ namespace storm {
return ISD;
}
template<typename ValueType>
DFTColouring<ValueType> DFT<ValueType>::colourDFT() const {
return DFTColouring<ValueType>(*this);
}
template<typename ValueType>
std::vector<std::vector<size_t>> DFT<ValueType>::findSymmetries(DFTColouring<ValueType> const& colouring) const {
std::vector<size_t> vec;
vec.reserve(nrElements());
storm::utility::iota_n(std::back_inserter(vec), 14, 0);
BijectionCandidates<ValueType> completeCategories = colouring.colourSubdft(vec);
std::vector<std::vector<size_t>> res;
for(auto const& colourClass : completeCategories.gateCandidates) {
if(colourClass.second.size() > 1) {
for(auto it1 = colourClass.second.cbegin(); it1 != colourClass.second.cend(); ++it1) {
std::vector<size_t> sortedParent1Ids = getGate(*it1)->parentIds();
std::sort(sortedParent1Ids.begin(), sortedParent1Ids.end());
auto it2 = it1;
for(++it2; it2 != colourClass.second.cend(); ++it2) {
std::vector<size_t> sortedParent2Ids = getGate(*it2)->parentIds();
std::sort(sortedParent2Ids.begin(), sortedParent2Ids.end());
if(sortedParent1Ids == sortedParent2Ids) {
std::cout << "Considering ids " << *it1 << ", " << *it2 << " for isomorphism." << std::endl;
std::vector<size_t> isubdft1 = getGate(*it1)->independentSubDft();
std::vector<size_t> isubdft2 = getGate(*it2)->independentSubDft();
if(!isubdft1.empty() && !isubdft2.empty() && isubdft1.size() == isubdft2.size()) {
std::cout << "Checking subdfts from " << *it1 << ", " << *it2 << " for isomorphism." << std::endl;
}
}
}
}
}
}
return res;
}
// Explicitly instantiate the class.
template class DFT<double>;

10
src/storage/dft/DFT.h

@ -29,6 +29,11 @@ namespace storm {
}
};
// Forward declarations
template<typename T> class DFTColouring;
/**
* Represents a Dynamic Fault Tree
*/
@ -222,6 +227,11 @@ namespace storm {
std::string getStateString(DFTStatePointer const& state) const;
std::vector<size_t> getIndependentSubDftRoots(size_t index) const;
DFTColouring<ValueType> colourDFT() const;
std::vector<std::vector<size_t>> findSymmetries(DFTColouring<ValueType> const& colouring) const;
private:
bool elementIndicesCorrect() const {
for(size_t i = 0; i < mElements.size(); ++i) {

205
src/storage/dft/DFTIsomorphism.h

@ -1,9 +1,12 @@
#pragma once
#include <cassert>
#include <vector>
#include <unordered_map>
#include <utility>
#include "DFTElementType.h"
#include "DFTElements.h"
#include "DFT.h"
namespace storm {
namespace storage {
@ -34,14 +37,102 @@ namespace storage {
};
template<typename ValueType>
struct BEColourClass {
BEColourClass() = default;
BEColourClass(ValueType a, ValueType p, size_t h) : aRate(a), pRate(p), hash(h) {}
ValueType aRate;
ValueType pRate;
size_t hash;
};
template<typename ValueType>
bool operator==(BEColourClass<ValueType> const& lhs, BEColourClass<ValueType> const& rhs) {
return lhs.hash == rhs.hash && lhs.aRate == rhs.aRate && lhs.pRate == rhs.pRate;
}
/**
*
*/
template<typename ValueType>
class BijectionCandidates {
std::unordered_map<size_t, std::vector<size_t>> groupCandidates;
std::unordered_map<std::pair<ValueType, ValueType>, std::vector<size_t>> beCandidates;
struct BijectionCandidates {
std::unordered_map<size_t, std::vector<size_t>> gateCandidates;
std::unordered_map<BEColourClass<ValueType>, std::vector<size_t>> beCandidates;
std::unordered_map<std::pair<ValueType, ValueType>, std::vector<size_t>> pdepCandidates;
};
template<typename ValueType>
class DFTColouring {
DFT<ValueType> const& dft;
std::unordered_map<size_t, size_t> gateColour;
std::unordered_map<size_t, BEColourClass<ValueType>> beColour;
std::unordered_map<size_t, std::pair<ValueType, ValueType>> depColour;
GateGroupToHash gateColourizer;
public:
DFTColouring(DFT<ValueType> const& ft) : dft(ft) {
for(size_t id = 0; id < dft.nrElements(); ++id ) {
if(dft.isBasicElement(id)) {
colourize(dft.getBasicElement(id));
} else if(dft.isGate(id)) {
colourize(dft.getGate(id));
} else {
assert(dft.isDependency(id));
colourize(dft.getDependency(id));
}
}
}
BijectionCandidates<ValueType> colourSubdft(std::vector<size_t> const& subDftIndices) const {
BijectionCandidates<ValueType> res;
for (size_t index : subDftIndices) {
if(dft.isBasicElement(index)) {
auto it = res.beCandidates.find(beColour.at(index));
if(it != res.beCandidates.end()) {
it->second.push_back(index);
} else {
res.beCandidates[beColour.at(index)] = std::vector<size_t>({index});
}
} else if(dft.isGate(index)) {
auto it = res.gateCandidates.find(gateColour.at(index));
if(it != res.gateCandidates.end()) {
it->second.push_back(index);
} else {
res.gateCandidates[gateColour.at(index)] = std::vector<size_t>({index});
}
} else {
assert(dft.isDependency(index));
auto it = res.pdepCandidates.find(depColour.at(index));
if(it != res.pdepCandidates.end()) {
it->second.push_back(index);
} else {
res.pdepCandidates[depColour.at(index)] = std::vector<size_t>({index});
}
}
}
return res;
}
protected:
void colourize(std::shared_ptr<const DFTBE<ValueType>> const& be) {
beColour[be->id()] = BEColourClass<ValueType>(be->activeFailureRate(), be->passiveFailureRate(), be->nrParents());
}
void colourize(std::shared_ptr<const DFTGate<ValueType>> const& gate) {
gateColour[gate->id()] = gateColourizer(gate->type(), gate->nrChildren(), gate->nrParents(), 0, gate->rank());
}
void colourize(std::shared_ptr<const DFTDependency<ValueType>> const& dep) {
depColour[dep->id()] = std::pair<ValueType, ValueType>(dep->probability(), dep->dependentEvent()->activeFailureRate());
}
};
@ -107,36 +198,61 @@ namespace storage {
}
protected:
/**
* Construct the initial bijection.
*/
void constructInitialBijection() {
assert(candidatesCompatible);
// We first construct the currentPermutations, which helps to determine the current state of the check.
for(auto const& colour : bright.beCandidates) {
if(colour.second.size()>1) {
currentPermutations.beCandidates.insert(colour);
initializePermutationsAndTreatTrivialGroups(bleft.beCandidates, bright.beCandidates, currentPermutations.beCandidates);
initializePermutationsAndTreatTrivialGroups(bleft.gateCandidates, bright.gateCandidates, currentPermutations.gateCandidates);
initializePermutationsAndTreatTrivialGroups(bleft.pdepCandidates, bright.pdepCandidates, currentPermutations.pdepCandidates);
}
/**
* Construct the next bijection
* @return true if a next bijection exists.
*/
bool findNextBijection() {
bool foundNext = false;
if(!currentPermutations.beCandidates.empty()) {
auto it = currentPermutations.beCandidates.begin();
while(!foundNext && it == currentPermutations.beCandidates.end()) {
foundNext = std::next_permutation(it->second.begin(), it->second.end());
++it;
}
}
for(auto const& colour : bright.groupCandidates) {
if(colour.second.size()>1) {
currentPermutations.groupCandidates.insert(colour);
if(!foundNext && !currentPermutations.gateCandidates.empty()) {
auto it = currentPermutations.gateCandidates.begin();
while(!foundNext && it == currentPermutations.beCandidates.end()) {
foundNext = std::next_permutation(it->second.begin(), it->second.end());
++it;
}
}
// Constructing the initial homomorphism based on the right hand side instead of the current permutations allows us
// to treat trivial and non-trivial classes in one go.
for(auto const& colour : bleft.beCandidates) {
zipVectorsIntoMap(colour.second, bright.beCandidates.find(colour.first)->second, bijection);
if(!foundNext && !currentPermutations.pdepCandidates.empty()) {
auto it = currentPermutations.pdepCandidates.begin();
while(!foundNext && it == currentPermutations.pdepCandidates.end()) {
foundNext = std::next_permutation(it->second.begin(), it->second.end());
++it;
}
}
for(auto const& colour : bleft.groupCandidates) {
zipVectorsIntoMap(colour.second, bright.groupCandidates.find(colour.first)->second, bijection);
}
if(foundNext) {
for(auto const& colour : bleft.beCandidates) {
zipVectorsIntoMap(colour.second, currentPermutations.beCandidates.find(colour.first)->second, bijection);
}
}
for(auto const& colour : bleft.gateCandidates) {
zipVectorsIntoMap(colour.second, currentPermutations.gateCandidates.find(colour.first)->second, bijection);
}
bool findNextBijection() {
return false;
for(auto const& colour : bleft.pdepCandidates) {
zipVectorsIntoMap(colour.second, currentPermutations.pdepCandidates.find(colour.first)->second, bijection);
}
}
return foundNext;
}
@ -152,21 +268,21 @@ namespace storage {
* Returns true if the colours are compatible.
*/
bool checkCompatibility() {
if(bleft.groupCandidates.size() != bright.groupCandidates.size()) {
if(bleft.gateCandidates.size() != bright.gateCandidates.size()) {
candidatesCompatible = false;
}
else if(bleft.beCandidates.size() != bright.beCandidates.size()) {
candidatesCompatible = false;
}
else {
for (auto const &gc : bleft.groupCandidates) {
if (bright.groupCandidates.count(gc.first) == 0) {
for (auto const &gc : bleft.gateCandidates) {
if (bright.gateCandidates.count(gc.first) == 0) {
candidatesCompatible = false;
break;
}
}
if(candidatesCompatible) {
for(auto const& bc : bleft.groupCandidates) {
for(auto const& bc : bleft.gateCandidates) {
if(bright.beCandidates.count(bc.first) == 0) {
candidatesCompatible = false;
break;
@ -176,6 +292,26 @@ namespace storage {
}
}
/**
*
*/
template<typename ColourType>
void initializePermutationsAndTreatTrivialGroups(std::unordered_map<ColourType, std::vector<size_t>> const& left,
std::unordered_map<ColourType, std::vector<size_t>> const& right,
std::unordered_map<ColourType, std::vector<size_t>>& permutations) {
for(auto const& colour : right) {
if(colour.second.size()>1) {
auto it = permutations.insert(colour);
std::sort(it->second.begin(), it->second.end());
zipVectorsIntoMap(colour.second, permutations.find(colour.first)->second, bijection);
} else {
assert(colour.second.size() == 1);
assert(bijection.count(left[colour.first].front()) == 0);
bijection[left[colour.first].front()] = colour.second.front();
}
}
}
/**
* Local helper function for the creation of bijections, should be hidden from api.
*/
@ -184,7 +320,6 @@ namespace storage {
assert(a.size() == b.size());
auto it = b.cbegin();
for(size_t lIndex : a) {
assert(map.count(lIndex) == 0);
map[lIndex] = *it;
++it;
}
@ -199,3 +334,21 @@ namespace storage {
} // namespace storm::dft
} // namespace storm
namespace std {
template<typename ValueType>
struct hash<storm::storage::BEColourClass<ValueType>> {
size_t operator()(storm::storage::BEColourClass<ValueType> const& bcc) const {
std::hash<ValueType> hasher;
return (hasher(bcc.aRate) ^ hasher(bcc.pRate) << 8) | bcc.hash;
}
};
template<typename ValueType>
struct hash<std::pair<ValueType, ValueType>> {
size_t operator()(std::pair<ValueType, ValueType> const& p) const {
std::hash<ValueType> hasher;
return hasher(p.first) ^ hasher(p.second);
}
};
}

13
src/utility/iota_n.h

@ -0,0 +1,13 @@
#pragma once
namespace storm {
namespace utility {
template<class OutputIterator, class Size, class Assignable>
void iota_n(OutputIterator first, Size n, Assignable value)
{
std::generate_n(first, n, [&value]() {
return value++;
});
}
}
}
Loading…
Cancel
Save