#ifndef DFT_H #define DFT_H #include #include #include #include #include #include "DFTElements.h" #include "elements/DFTRestriction.h" #include "../BitVector.h" #include "SymmetricUnits.h" #include "../../utility/math.h" #include "src/utility/macros.h" namespace storm { namespace storage { template struct DFTElementSort { bool operator()(std::shared_ptr> const& a, std::shared_ptr> const& b) const { if (a->rank() == 0 && b->rank() == 0) { return a->isConstant(); } else { return a->rank() < b->rank(); } } }; // Forward declarations template class DFTColouring; class DFTStateGenerationInfo { private: const size_t mUsageInfoBits; std::map mSpareUsageIndex; // id spare -> index first bit in state std::map mSpareActivationIndex; // id spare representative -> index in state std::vector mIdToStateIndex; // id -> index first bit in state std::vector>> mSymmetries; // pair (lenght of symmetry group, vector indicating the starting points of the symmetry groups) public: DFTStateGenerationInfo(size_t nrElements, size_t maxSpareChildCount) : mUsageInfoBits(storm::utility::math::uint64_log2(maxSpareChildCount) + 1), mIdToStateIndex(nrElements) { assert(maxSpareChildCount < pow(2, mUsageInfoBits)); } size_t usageInfoBits() const { return mUsageInfoBits; } void addStateIndex(size_t id, size_t index) { assert(id < mIdToStateIndex.size()); mIdToStateIndex[id] = index; } void addSpareActivationIndex(size_t id, size_t index) { mSpareActivationIndex[id] = index; } void addSpareUsageIndex(size_t id, size_t index) { mSpareUsageIndex[id] = index; } size_t getStateIndex(size_t id) const { assert(id < mIdToStateIndex.size()); return mIdToStateIndex[id]; } size_t getSpareUsageIndex(size_t id) const { assert(mSpareUsageIndex.count(id) > 0); return mSpareUsageIndex.at(id); } size_t getSpareActivationIndex(size_t id) const { assert(mSpareActivationIndex.count(id) > 0); return mSpareActivationIndex.at(id); } void addSymmetry(size_t length, std::vector& startingIndices) { mSymmetries.push_back(std::make_pair(length, startingIndices)); } size_t getSymmetrySize() const { return mSymmetries.size(); } size_t getSymmetryLength(size_t pos) const { assert(pos < mSymmetries.size()); return mSymmetries[pos].first; } std::vector const& getSymmetryIndices(size_t pos) const { assert(pos < mSymmetries.size()); return mSymmetries[pos].second; } friend std::ostream& operator<<(std::ostream& os, DFTStateGenerationInfo const& info) { os << "Id to state index:" << std::endl; for (size_t id = 0; id < info.mIdToStateIndex.size(); ++id) { os << id << " -> " << info.getStateIndex(id) << std::endl; } os << "Spare usage index with usage InfoBits of size " << info.mUsageInfoBits << ":" << std::endl; for (auto pair : info.mSpareUsageIndex) { os << pair.first << " -> " << pair.second << std::endl; } os << "Spare activation index:" << std::endl; for (auto pair : info.mSpareActivationIndex) { os << pair.first << " -> " << pair.second << std::endl; } os << "Symmetries:" << std::endl; for (auto pair : info.mSymmetries) { os << "Length: " << pair.first << ", starting indices: "; for (size_t index : pair.second) { os << index << ", "; } os << std::endl; } return os; } }; /** * Represents a Dynamic Fault Tree */ template class DFT { using DFTElementPointer = std::shared_ptr>; using DFTElementCPointer = std::shared_ptr const>; using DFTElementVector = std::vector; using DFTGatePointer = std::shared_ptr>; using DFTGateVector = std::vector; using DFTStatePointer = std::shared_ptr>; private: DFTElementVector mElements; size_t mNrOfBEs; size_t mNrOfSpares; size_t mTopLevelIndex; size_t mStateVectorSize; size_t mMaxSpareChildCount; std::map> mSpareModules; std::vector mDependencies; std::vector mTopModule; std::map mRepresentants; // id element -> id representative std::vector> 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& visitQueue, storm::storage::BitVector& visited, size_t stateIndex) 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; } size_t getMaxSpareChildCount() const { return mMaxSpareChildCount; } std::vector getSpareIndices() const { std::vector indices; for(auto const& elem : mElements) { if(elem->isSpareGate()) { indices.push_back(elem->id()); } } return indices; } std::vector const& module(size_t representativeId) const { if(representativeId == mTopLevelIndex) { return mTopModule; } else { assert(mSpareModules.count(representativeId)>0); return mSpareModules.find(representativeId)->second; } } std::vector const& getDependencies() const { return mDependencies; } std::vector nonColdBEs() const { std::vector result; for(DFTElementPointer elem : mElements) { if(elem->isBasicElement() && !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(); } std::shared_ptr const> getBasicElement(size_t index) const { assert(isBasicElement(index)); return std::static_pointer_cast const>(mElements[index]); } std::shared_ptr const> getGate(size_t index) const { assert(isGate(index)); return std::static_pointer_cast const>(mElements[index]); } std::shared_ptr const> getDependency(size_t index) const { assert(isDependency(index)); return std::static_pointer_cast const>(mElements[index]); } std::vector>> getBasicElements() const { std::vector>> elements; for (DFTElementPointer elem : mElements) { if (elem->isBasicElement()) { elements.push_back(std::static_pointer_cast>(elem)); } } return elements; } 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::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::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 getIndependentSubDftRoots(size_t index) const; DFTColouring colourDFT() const; DFTIndependentSymmetries findSymmetries(DFTColouring const& colouring) const; std::vector immediateFailureCauses(size_t index) const; private: std::pair, std::vector> 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 */