276 lines
10 KiB
276 lines
10 KiB
|
|
#ifndef DFT_H
|
|
#define DFT_H
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <list>
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
#include <boost/iterator/counting_iterator.hpp>
|
|
|
|
#include "DFTElements.h"
|
|
#include "elements/DFTRestriction.h"
|
|
#include "../BitVector.h"
|
|
#include "SymmetricUnits.h"
|
|
#include "../../utility/math.h"
|
|
#include "src/utility/macros.h"
|
|
#include "DFTStateGenerationInfo.h"
|
|
|
|
namespace storm {
|
|
namespace storage {
|
|
|
|
template<typename ValueType>
|
|
struct DFTElementSort {
|
|
bool operator()(std::shared_ptr<DFTElement<ValueType>> const& a, std::shared_ptr<DFTElement<ValueType>> const& b) const {
|
|
if (a->rank() == 0 && b->rank() == 0) {
|
|
return a->isConstant();
|
|
} else {
|
|
return a->rank() < b->rank();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
// Forward declarations
|
|
template<typename T> class DFTColouring;
|
|
|
|
template<typename T> class DFTBuilder;
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Represents a Dynamic Fault Tree
|
|
*/
|
|
template<typename ValueType>
|
|
class DFT {
|
|
|
|
using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>;
|
|
using DFTElementCPointer = std::shared_ptr<DFTElement<ValueType> const>;
|
|
using DFTElementVector = std::vector<DFTElementPointer>;
|
|
using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
|
|
using DFTGateVector = std::vector<DFTGatePointer>;
|
|
using DFTStatePointer = std::shared_ptr<DFTState<ValueType>>;
|
|
|
|
private:
|
|
DFTElementVector mElements;
|
|
size_t mNrOfBEs;
|
|
size_t mNrOfSpares;
|
|
size_t mTopLevelIndex;
|
|
size_t mStateVectorSize;
|
|
size_t mMaxSpareChildCount;
|
|
std::map<size_t, std::vector<size_t>> mSpareModules;
|
|
std::vector<size_t> mDependencies;
|
|
std::vector<size_t> mTopModule;
|
|
std::map<size_t, size_t> mRepresentants; // id element -> id representative
|
|
std::vector<std::vector<size_t>> mSymmetries;
|
|
|
|
public:
|
|
DFT(DFTElementVector const& elements, DFTElementPointer const& tle);
|
|
|
|
DFTStateGenerationInfo buildStateGenerationInfo(storm::storage::DFTIndependentSymmetries const& symmetries) const;
|
|
|
|
size_t generateStateInfo(DFTStateGenerationInfo& generationInfo, size_t id, storm::storage::BitVector& visited, size_t stateIndex) const;
|
|
|
|
size_t performStateGenerationInfoDFS(DFTStateGenerationInfo& generationInfo, std::queue<size_t>& visitQueue, storm::storage::BitVector& visited, size_t stateIndex) const;
|
|
|
|
DFT<ValueType> optimize() const;
|
|
|
|
void copyElements(std::vector<size_t> elements, DFTBuilder<ValueType> builder) const;
|
|
|
|
size_t stateVectorSize() const {
|
|
return mStateVectorSize;
|
|
}
|
|
|
|
size_t nrElements() const {
|
|
return mElements.size();
|
|
}
|
|
|
|
size_t nrBasicElements() const {
|
|
return mNrOfBEs;
|
|
}
|
|
|
|
size_t getTopLevelIndex() const {
|
|
return mTopLevelIndex;
|
|
}
|
|
|
|
DFTElementType topLevelType() const {
|
|
return mElements[getTopLevelIndex()]->type();
|
|
}
|
|
|
|
size_t getMaxSpareChildCount() const {
|
|
return mMaxSpareChildCount;
|
|
}
|
|
|
|
std::vector<size_t> getSpareIndices() const {
|
|
std::vector<size_t> indices;
|
|
for(auto const& elem : mElements) {
|
|
if(elem->isSpareGate()) {
|
|
indices.push_back(elem->id());
|
|
}
|
|
}
|
|
return indices;
|
|
}
|
|
|
|
std::vector<size_t> const& module(size_t representativeId) const {
|
|
if(representativeId == mTopLevelIndex) {
|
|
return mTopModule;
|
|
} else {
|
|
assert(mSpareModules.count(representativeId)>0);
|
|
return mSpareModules.find(representativeId)->second;
|
|
}
|
|
}
|
|
|
|
std::vector<size_t> const& getDependencies() const {
|
|
return mDependencies;
|
|
}
|
|
|
|
std::vector<size_t> nonColdBEs() const {
|
|
std::vector<size_t> result;
|
|
for(DFTElementPointer elem : mElements) {
|
|
if(elem->isBasicElement() && std::static_pointer_cast<DFTBE<ValueType>>(elem)->canFail() && !elem->isColdBasicElement()) {
|
|
result.push_back(elem->id());
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get a pointer to an element in the DFT
|
|
* @param index The id of the element
|
|
*/
|
|
DFTElementCPointer getElement(size_t index) const {
|
|
assert(index < nrElements());
|
|
return mElements[index];
|
|
}
|
|
|
|
bool isBasicElement(size_t index) const {
|
|
return getElement(index)->isBasicElement();
|
|
}
|
|
|
|
bool isGate(size_t index) const {
|
|
return getElement(index)->isGate();
|
|
}
|
|
|
|
bool isDependency(size_t index) const {
|
|
return getElement(index)->isDependency();
|
|
}
|
|
|
|
bool isRestriction(size_t index) const {
|
|
return getElement(index)->isRestriction();
|
|
}
|
|
|
|
std::shared_ptr<DFTBE<ValueType> const> getBasicElement(size_t index) const {
|
|
assert(isBasicElement(index));
|
|
return std::static_pointer_cast<DFTBE<ValueType> const>(mElements[index]);
|
|
}
|
|
|
|
std::shared_ptr<DFTGate<ValueType> const> getTopLevelGate() const {
|
|
return getGate(mTopLevelIndex);
|
|
}
|
|
|
|
std::shared_ptr<DFTGate<ValueType> const> getGate(size_t index) const {
|
|
assert(isGate(index));
|
|
return std::static_pointer_cast<DFTGate<ValueType> const>(mElements[index]);
|
|
}
|
|
|
|
std::shared_ptr<DFTDependency<ValueType> const> getDependency(size_t index) const {
|
|
assert(isDependency(index));
|
|
return std::static_pointer_cast<DFTDependency<ValueType> const>(mElements[index]);
|
|
}
|
|
|
|
std::shared_ptr<DFTRestriction<ValueType> const> getRestriction(size_t index) const {
|
|
assert(isRestriction(index));
|
|
return std::static_pointer_cast<DFTRestriction<ValueType> const>(mElements[index]);
|
|
}
|
|
|
|
std::vector<std::shared_ptr<DFTBE<ValueType>>> getBasicElements() const {
|
|
std::vector<std::shared_ptr<DFTBE<ValueType>>> elements;
|
|
for (DFTElementPointer elem : mElements) {
|
|
if (elem->isBasicElement()) {
|
|
elements.push_back(std::static_pointer_cast<DFTBE<ValueType>>(elem));
|
|
}
|
|
}
|
|
return elements;
|
|
}
|
|
|
|
std::vector<DFT<ValueType>> topModularisation() const;
|
|
|
|
bool isRepresentative(size_t id) const {
|
|
for (auto const& parent : getElement(id)->parents()) {
|
|
if (parent->isSpareGate()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool hasRepresentant(size_t id) const {
|
|
return mRepresentants.find(id) != mRepresentants.end();
|
|
}
|
|
|
|
DFTElementCPointer getRepresentant(size_t id) const {
|
|
assert(hasRepresentant(id));
|
|
return getElement(mRepresentants.find(id)->second);
|
|
}
|
|
|
|
bool hasFailed(DFTStatePointer const& state) const {
|
|
return state->hasFailed(mTopLevelIndex);
|
|
}
|
|
|
|
bool hasFailed(storm::storage::BitVector const& state, DFTStateGenerationInfo const& stateGenerationInfo) const {
|
|
return storm::storage::DFTState<ValueType>::hasFailed(state, stateGenerationInfo.getStateIndex(mTopLevelIndex));
|
|
}
|
|
|
|
bool isFailsafe(DFTStatePointer const& state) const {
|
|
return state->isFailsafe(mTopLevelIndex);
|
|
}
|
|
|
|
bool isFailsafe(storm::storage::BitVector const& state, DFTStateGenerationInfo const& stateGenerationInfo) const {
|
|
return storm::storage::DFTState<ValueType>::isFailsafe(state, stateGenerationInfo.getStateIndex(mTopLevelIndex));
|
|
}
|
|
|
|
size_t getChild(size_t spareId, size_t nrUsedChild) const;
|
|
|
|
size_t getNrChild(size_t spareId, size_t childId) const;
|
|
|
|
std::string getElementsString() const;
|
|
|
|
std::string getInfoString() const;
|
|
|
|
std::string getSpareModulesString() const;
|
|
|
|
std::string getElementsWithStateString(DFTStatePointer const& state) const;
|
|
|
|
std::string getStateString(DFTStatePointer const& state) const;
|
|
|
|
std::vector<size_t> getIndependentSubDftRoots(size_t index) const;
|
|
|
|
DFTColouring<ValueType> colourDFT() const;
|
|
|
|
std::map<size_t, size_t> findBijection(size_t index1, size_t index2, DFTColouring<ValueType> const& colouring, bool sparesAsLeaves) const;
|
|
|
|
DFTIndependentSymmetries findSymmetries(DFTColouring<ValueType> const& colouring) const;
|
|
|
|
std::vector<size_t> immediateFailureCauses(size_t index) const;
|
|
|
|
std::vector<size_t> findModularisationRewrite() const;
|
|
|
|
private:
|
|
std::pair<std::vector<size_t>, std::vector<size_t>> getSortedParentAndOutDepIds(size_t index) const;
|
|
|
|
bool elementIndicesCorrect() const {
|
|
for(size_t i = 0; i < mElements.size(); ++i) {
|
|
if(mElements[i]->id() != i) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
}
|
|
#endif /* DFT_H */
|
|
|