#pragma once #include "DFTGate.h" namespace storm { namespace storage { template class DFTSpare : public DFTGate { public: DFTSpare(size_t id, std::string const& name, std::vector>> const& children = {}) : DFTGate(id, name, children) {} std::string typestring() const override { return "SPARE"; } virtual DFTElementType type() const override { return DFTElementType::SPARE; } bool isSpareGate() const override { return true; } void fail(DFTState& state, DFTStateSpaceGenerationQueues& queues) const { DFTGate::fail(state, queues); state.finalizeUses(this->mId); } void failsafe(DFTState& state, DFTStateSpaceGenerationQueues& queues) const { DFTGate::failsafe(state, queues); state.finalizeUses(this->mId); } bool checkDontCareAnymore(storm::storage::DFTState& state, DFTStateSpaceGenerationQueues& queues) const override { if (DFTGate::checkDontCareAnymore(state, queues)) { state.finalizeUses(this->mId); return true; } return false; } void checkFails(storm::storage::DFTState& state, DFTStateSpaceGenerationQueues& queues) const override { if(state.isOperational(this->mId)) { size_t uses = state.uses(this->mId); if(!state.isOperational(uses)) { bool claimingSuccessful = state.claimNew(this->mId, uses, this->mChildren); if(!claimingSuccessful) { this->fail(state, queues); } } } } void checkFailsafe(storm::storage::DFTState& state, DFTStateSpaceGenerationQueues& queues) const override { if(state.isOperational(this->mId)) { if(state.isFailsafe(state.uses(this->mId))) { this->failsafe(state, queues); this->childrenDontCare(state, queues); } } } std::vector independentSubDft(bool blockParents, bool sparesAsLeaves = false) const override { auto prelRes = DFTElement::independentSubDft(blockParents); if(prelRes.empty()) { // No elements (especially not this->id) in the prelimanry result, so we know already that it is not a subdft. return prelRes; } std::set unit(prelRes.begin(), prelRes.end()); std::vector pids = this->parentIds(); if (!sparesAsLeaves) { for(auto const& child : this->mChildren) { child->extendSubDft(unit, pids, blockParents, sparesAsLeaves); if(unit.empty()) { // Parent in the subdft, ie it is *not* a subdft break; } } } return std::vector(unit.begin(), unit.end()); } void extendSubDft(std::set& elemsInSubtree, std::vector const& parentsOfSubRoot, bool blockParents, bool sparesAsLeaves) const override { if(elemsInSubtree.count(this->id()) > 0) return; DFTElement::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents, sparesAsLeaves); if(elemsInSubtree.empty()) { // Parent in the subdft, ie it is *not* a subdft return; } if (!sparesAsLeaves) { for(auto const& child : this->mChildren) { child->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents, sparesAsLeaves); if(elemsInSubtree.empty()) { // Parent in the subdft, ie it is *not* a subdft return; } } } } }; } }