You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
939 lines
33 KiB
939 lines
33 KiB
#ifndef DFTELEMENTS_H
|
|
#define DFTELEMENTS_H
|
|
|
|
#include <set>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <functional>
|
|
|
|
#include "DFTElementType.h"
|
|
#include "DFTState.h"
|
|
#include "DFTStateSpaceGenerationQueues.h"
|
|
#include "src/utility/constants.h"
|
|
#include "src/adapters/CarlAdapter.h"
|
|
|
|
using std::size_t;
|
|
|
|
namespace storm {
|
|
namespace storage {
|
|
|
|
template<typename ValueType>
|
|
class DFTGate;
|
|
|
|
template<typename ValueType>
|
|
class DFTDependency;
|
|
|
|
template<typename ValueType>
|
|
class DFTElement {
|
|
|
|
using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
|
|
using DFTGateVector = std::vector<DFTGatePointer>;
|
|
using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
|
|
using DFTDependencyVector = std::vector<DFTDependencyPointer>;
|
|
|
|
|
|
protected:
|
|
size_t mId;
|
|
std::string mName;
|
|
size_t mRank = -1;
|
|
DFTGateVector mParents;
|
|
DFTDependencyVector dependencies;
|
|
|
|
public:
|
|
DFTElement(size_t id, std::string const& name) :
|
|
mId(id), mName(name)
|
|
{}
|
|
|
|
virtual ~DFTElement() {}
|
|
|
|
/**
|
|
* Returns the id
|
|
*/
|
|
virtual size_t id() const {
|
|
return mId;
|
|
}
|
|
|
|
virtual DFTElementType type() const = 0;
|
|
|
|
virtual void setRank(size_t rank) {
|
|
mRank = rank;
|
|
}
|
|
|
|
virtual size_t rank() const {
|
|
return mRank;
|
|
}
|
|
|
|
virtual bool isConstant() const {
|
|
return false;
|
|
}
|
|
|
|
virtual bool isGate() const {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the element is a BE
|
|
*/
|
|
virtual bool isBasicElement() const {
|
|
return false;
|
|
}
|
|
|
|
virtual bool isColdBasicElement() const {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the element is a spare gate
|
|
*/
|
|
virtual bool isSpareGate() const {
|
|
return false;
|
|
}
|
|
|
|
virtual bool isDependency() const {
|
|
return false;
|
|
}
|
|
|
|
virtual void setId(size_t newId) {
|
|
mId = newId;
|
|
}
|
|
|
|
/**
|
|
* Returns the name
|
|
*/
|
|
virtual std::string const& name() const {
|
|
return mName;
|
|
}
|
|
|
|
bool addParent(DFTGatePointer const& e) {
|
|
if(std::find(mParents.begin(), mParents.end(), e) != mParents.end()) {
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
mParents.push_back(e);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool hasOnlyStaticParents() const {
|
|
for(auto const& parent : mParents) {
|
|
if(!isStaticGateType(parent->type())) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
bool hasParents() const {
|
|
return !mParents.empty();
|
|
}
|
|
|
|
size_t nrParents() const {
|
|
return mParents.size();
|
|
}
|
|
|
|
DFTGateVector const& parents() const {
|
|
return mParents;
|
|
}
|
|
|
|
std::vector<size_t> parentIds() const {
|
|
std::vector<size_t> res;
|
|
for(auto parent : parents()) {
|
|
res.push_back(parent->id());
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool addDependency(DFTDependencyPointer const& e) {
|
|
if(std::find(dependencies.begin(), dependencies.end(), e) != dependencies.end()) {
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
dependencies.push_back(e);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool hasDependencies() const {
|
|
return !dependencies.empty();
|
|
}
|
|
|
|
size_t nrDependencies() const {
|
|
return dependencies.size();
|
|
}
|
|
|
|
DFTDependencyVector const& getDependencies() const {
|
|
return dependencies;
|
|
}
|
|
|
|
virtual void extendSpareModule(std::set<size_t>& elementsInModule) const;
|
|
|
|
virtual size_t nrChildren() const = 0;
|
|
|
|
virtual std::string toString() const = 0;
|
|
|
|
virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const;
|
|
|
|
/**
|
|
* Computes the independent unit of this element, that is, all elements which are direct or indirect successors of an element.
|
|
*/
|
|
virtual std::vector<size_t> independentUnit() const;
|
|
|
|
/**
|
|
* Helper to independent unit computation
|
|
* @see independentUnit
|
|
*/
|
|
virtual void extendUnit(std::set<size_t>& unit) const;
|
|
|
|
/**
|
|
* Computes independent subtrees starting with this element (this), that is, all elements (x) which are connected to either
|
|
* - one of the children of the element,
|
|
* - a propabilisistic dependency
|
|
* such that there exists a path from x to a child of this does not go through this.
|
|
*/
|
|
virtual std::vector<size_t> independentSubDft() const;
|
|
/**
|
|
* Helper to the independent subtree computation
|
|
* @see independentSubDft
|
|
*/
|
|
virtual void extendSubDft(std::set<size_t> elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot) const;
|
|
|
|
virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const {
|
|
return type() == other.type();
|
|
}
|
|
|
|
|
|
protected:
|
|
// virtual bool checkIsomorphicSubDftHelper(DFTElement const& otherElem, std::vector<std::pair<DFTElement const&, DFTElement const&>>& mapping, std::vector<DFTElement const&> const& order ) const = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTGate : public DFTElement<ValueType> {
|
|
|
|
using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>;
|
|
using DFTElementVector = std::vector<DFTElementPointer>;
|
|
|
|
protected:
|
|
DFTElementVector mChildren;
|
|
|
|
public:
|
|
DFTGate(size_t id, std::string const& name, DFTElementVector const& children) :
|
|
DFTElement<ValueType>(id, name), mChildren(children)
|
|
{}
|
|
|
|
virtual ~DFTGate() {}
|
|
|
|
void pushBackChild(DFTElementPointer elem) {
|
|
return mChildren.push_back(elem);
|
|
}
|
|
|
|
size_t nrChildren() const override {
|
|
return mChildren.size();
|
|
}
|
|
|
|
DFTElementVector const& children() const {
|
|
return mChildren;
|
|
}
|
|
|
|
virtual bool isGate() const override {
|
|
return true;
|
|
}
|
|
|
|
|
|
virtual std::string typestring() const = 0;
|
|
|
|
virtual void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const = 0;
|
|
|
|
virtual void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const = 0;
|
|
|
|
virtual void extendSpareModule(std::set<size_t>& elementsInSpareModule) const override {
|
|
DFTElement<ValueType>::extendSpareModule(elementsInSpareModule);
|
|
for(auto const& child : mChildren) {
|
|
if(elementsInSpareModule.count(child->id()) == 0) {
|
|
elementsInSpareModule.insert(child->id());
|
|
child->extendSpareModule(elementsInSpareModule);
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual std::vector<size_t> independentUnit() const override {
|
|
std::set<size_t> unit = {this->mId};
|
|
for(auto const& child : mChildren) {
|
|
child->extendUnit(unit);
|
|
}
|
|
return std::vector<size_t>(unit.begin(), unit.end());
|
|
}
|
|
|
|
virtual void extendUnit(std::set<size_t>& unit) const override {
|
|
DFTElement<ValueType>::extendUnit(unit);
|
|
for(auto const& child : mChildren) {
|
|
child->extendUnit(unit);
|
|
}
|
|
}
|
|
|
|
virtual std::vector<size_t> independentSubDft() const override {
|
|
auto prelRes = DFTElement<ValueType>::independentSubDft();
|
|
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<size_t> unit(prelRes.begin(), prelRes.end());
|
|
std::vector<size_t> pids = this->parentIds();
|
|
for(auto const& child : mChildren) {
|
|
child->extendSubDft(unit, pids);
|
|
if(unit.empty()) {
|
|
// Parent in the subdft, ie it is *not* a subdft
|
|
break;
|
|
}
|
|
}
|
|
return std::vector<size_t>(unit.begin(), unit.end());
|
|
}
|
|
|
|
virtual void extendSubDft(std::set<size_t> elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot) const override {
|
|
DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot);
|
|
if(!elemsInSubtree.empty()) {
|
|
// Parent in the subdft, ie it is *not* a subdft
|
|
return;
|
|
}
|
|
for(auto const& child : mChildren) {
|
|
child->extendSubDft(elemsInSubtree, parentsOfSubRoot);
|
|
if(elemsInSubtree.empty()) {
|
|
// Parent in the subdft, ie it is *not* a subdft
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
virtual std::string toString() const override {
|
|
std::stringstream stream;
|
|
stream << "{" << this->name() << "} " << typestring() << "( ";
|
|
typename DFTElementVector::const_iterator it = mChildren.begin();
|
|
stream << (*it)->name();
|
|
++it;
|
|
while(it != mChildren.end()) {
|
|
stream << ", " << (*it)->name();
|
|
++it;
|
|
}
|
|
stream << ")";
|
|
return stream.str();
|
|
}
|
|
|
|
virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
if(DFTElement<ValueType>::checkDontCareAnymore(state, queues)) {
|
|
childrenDontCare(state, queues);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
protected:
|
|
|
|
void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
|
|
for(std::shared_ptr<DFTGate> parent : this->mParents) {
|
|
if(state.isOperational(parent->id())) {
|
|
queues.propagateFailure(parent);
|
|
}
|
|
}
|
|
state.setFailed(this->mId);
|
|
}
|
|
|
|
void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
|
|
for(std::shared_ptr<DFTGate> parent : this->mParents) {
|
|
if(state.isOperational(parent->id())) {
|
|
queues.propagateFailsafe(parent);
|
|
}
|
|
}
|
|
state.setFailsafe(this->mId);
|
|
}
|
|
|
|
void childrenDontCare(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
|
|
queues.propagateDontCare(mChildren);
|
|
}
|
|
|
|
bool hasFailsafeChild(DFTState<ValueType>& state) const {
|
|
for(auto const& child : mChildren) {
|
|
if(state.isFailsafe(child->id()))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool hasFailedChild(DFTState<ValueType>& state) const {
|
|
for(auto const& child : mChildren) {
|
|
if(state.hasFailed(child->id())) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTBE : public DFTElement<ValueType> {
|
|
|
|
ValueType mActiveFailureRate;
|
|
ValueType mPassiveFailureRate;
|
|
|
|
public:
|
|
DFTBE(size_t id, std::string const& name, ValueType failureRate, ValueType dormancyFactor) :
|
|
DFTElement<ValueType>(id, name), mActiveFailureRate(failureRate), mPassiveFailureRate(dormancyFactor * failureRate)
|
|
{}
|
|
|
|
DFTElementType type() const override {
|
|
return DFTElementType::BE;
|
|
}
|
|
|
|
virtual size_t nrChildren() const override {
|
|
return 0;
|
|
}
|
|
|
|
ValueType const& activeFailureRate() const {
|
|
return mActiveFailureRate;
|
|
}
|
|
|
|
ValueType const& passiveFailureRate() const {
|
|
return mPassiveFailureRate;
|
|
}
|
|
|
|
std::string toString() const override {
|
|
std::stringstream stream;
|
|
stream << *this;
|
|
return stream.str();
|
|
}
|
|
|
|
bool isBasicElement() const override{
|
|
return true;
|
|
}
|
|
|
|
bool isColdBasicElement() const override{
|
|
return storm::utility::isZero(mPassiveFailureRate);
|
|
}
|
|
|
|
bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
|
|
if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
|
|
DFTBE<ValueType> const& otherBE = static_cast<DFTBE<ValueType> const&>(other);
|
|
return (mActiveFailureRate == otherBE.mActiveFailureRate) && (mPassiveFailureRate == otherBE.mPassiveFailureRate);
|
|
}
|
|
|
|
virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override;
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTBE<ValueType> const& be) {
|
|
return os << "{" << be.name() << "} BE(" << be.activeFailureRate() << ", " << be.passiveFailureRate() << ")";
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTConst : public DFTElement<ValueType> {
|
|
|
|
bool mFailed;
|
|
|
|
public:
|
|
DFTConst(size_t id, std::string const& name, bool failed) :
|
|
DFTElement<ValueType>(id, name), mFailed(failed)
|
|
{}
|
|
|
|
DFTElementType type() const override {
|
|
if(mFailed) {
|
|
return DFTElementType::CONSTF;
|
|
} else {
|
|
return DFTElementType::CONSTS;
|
|
}
|
|
}
|
|
|
|
|
|
bool failed() const {
|
|
return mFailed;
|
|
}
|
|
|
|
virtual bool isConstant() const {
|
|
return true;
|
|
}
|
|
|
|
virtual size_t nrChildren() const override {
|
|
return 0;
|
|
}
|
|
|
|
bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
|
|
if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
|
|
DFTConst<ValueType> const& otherCNST = static_cast<DFTConst<ValueType> const&>(other);
|
|
return (mFailed == otherCNST.mFailed);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTDependency : public DFTElement<ValueType> {
|
|
|
|
using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
|
|
using DFTBEPointer = std::shared_ptr<DFTBE<ValueType>>;
|
|
|
|
protected:
|
|
std::string mNameTrigger;
|
|
std::string mNameDependent;
|
|
ValueType mProbability;
|
|
DFTGatePointer mTriggerEvent;
|
|
DFTBEPointer mDependentEvent;
|
|
|
|
public:
|
|
DFTDependency(size_t id, std::string const& name, std::string const& trigger, std::string const& dependent, ValueType probability) :
|
|
DFTElement<ValueType>(id, name), mNameTrigger(trigger), mNameDependent(dependent), mProbability(probability)
|
|
{
|
|
}
|
|
|
|
virtual ~DFTDependency() {}
|
|
|
|
void initialize(DFTGatePointer triggerEvent, DFTBEPointer dependentEvent) {
|
|
assert(triggerEvent->name() == mNameTrigger);
|
|
assert(dependentEvent->name() == mNameDependent);
|
|
mTriggerEvent = triggerEvent;
|
|
mDependentEvent = dependentEvent;
|
|
}
|
|
|
|
std::string nameTrigger() const {
|
|
return mNameTrigger;
|
|
}
|
|
|
|
std::string nameDependent() const {
|
|
return mNameDependent;
|
|
}
|
|
|
|
ValueType const& probability() const {
|
|
return mProbability;
|
|
}
|
|
|
|
DFTGatePointer const& triggerEvent() const {
|
|
assert(mTriggerEvent);
|
|
return mTriggerEvent;
|
|
}
|
|
|
|
DFTBEPointer const& dependentEvent() const {
|
|
assert(mDependentEvent);
|
|
return mDependentEvent;
|
|
}
|
|
|
|
DFTElementType type() const override {
|
|
return DFTElementType::PDEP;
|
|
}
|
|
|
|
virtual size_t nrChildren() const override {
|
|
return 1;
|
|
}
|
|
|
|
virtual bool isDependency() const override {
|
|
return true;
|
|
}
|
|
|
|
virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
|
|
if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
|
|
DFTDependency<ValueType> const& otherDEP= static_cast<DFTDependency<ValueType> const&>(other);
|
|
return (mProbability == otherDEP.mProbability);
|
|
}
|
|
|
|
|
|
virtual std::vector<size_t> independentUnit() const override {
|
|
std::set<size_t> unit = {this->mId};
|
|
mDependentEvent->extendUnit(unit);
|
|
if(unit.count(mTriggerEvent->id()) != 0) {
|
|
return {};
|
|
}
|
|
return std::vector<size_t>(unit.begin(), unit.end());
|
|
}
|
|
|
|
virtual std::string toString() const override {
|
|
std::stringstream stream;
|
|
bool fdep = storm::utility::isOne(mProbability);
|
|
stream << "{" << this->name() << "} " << (fdep ? "FDEP" : "PDEP") << "(" << mTriggerEvent->name() << " => " << mDependentEvent->name() << ")";
|
|
if (!fdep) {
|
|
stream << " with probability " << mProbability;
|
|
}
|
|
return stream.str();
|
|
}
|
|
|
|
protected:
|
|
|
|
};
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTAnd : public DFTGate<ValueType> {
|
|
|
|
public:
|
|
DFTAnd(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(id, name, children)
|
|
{}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
if(state.isOperational(this->mId)) {
|
|
for(auto const& child : this->mChildren)
|
|
{
|
|
if(!state.hasFailed(child->id())) {
|
|
return;
|
|
}
|
|
}
|
|
this->fail(state, queues);
|
|
}
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
assert(this->hasFailsafeChild(state));
|
|
if(state.isOperational(this->mId)) {
|
|
this->failsafe(state, queues);
|
|
this->childrenDontCare(state, queues);
|
|
}
|
|
}
|
|
|
|
virtual DFTElementType type() const override {
|
|
return DFTElementType::AND;
|
|
}
|
|
|
|
std::string typestring() const override {
|
|
return "AND";
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTAnd<ValueType> const& gate) {
|
|
return os << gate.toString();
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTOr : public DFTGate<ValueType> {
|
|
|
|
public:
|
|
DFTOr(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(id, name, children)
|
|
{}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
assert(this->hasFailedChild(state));
|
|
if(state.isOperational(this->mId)) {
|
|
this->fail(state, queues);
|
|
}
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
for(auto const& child : this->mChildren) {
|
|
if(!state.isFailsafe(child->id())) {
|
|
return;
|
|
}
|
|
}
|
|
this->failsafe(state, queues);
|
|
}
|
|
|
|
virtual DFTElementType type() const override {
|
|
return DFTElementType::OR;
|
|
}
|
|
|
|
std::string typestring() const override {
|
|
return "OR";
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTOr<ValueType> const& gate) {
|
|
return os << gate.toString();
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTSeqAnd : public DFTGate<ValueType> {
|
|
|
|
public:
|
|
DFTSeqAnd(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(id, name, children)
|
|
{}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
|
|
if(!state.hasFailed(this->mId)) {
|
|
bool childOperationalBefore = false;
|
|
for(auto const& child : this->mChildren)
|
|
{
|
|
if(!state.hasFailed(child->id())) {
|
|
childOperationalBefore = true;
|
|
}
|
|
else {
|
|
if(childOperationalBefore) {
|
|
state.markAsInvalid();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if(!childOperationalBefore) {
|
|
fail(state, queues);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const{
|
|
assert(hasFailsafeChild(state));
|
|
if(state.isOperational(this->mId)) {
|
|
failsafe(state, queues);
|
|
//return true;
|
|
}
|
|
//return false;
|
|
}
|
|
|
|
virtual DFTElementType type() const override {
|
|
return DFTElementType::SEQAND;
|
|
}
|
|
|
|
std::string typestring() const override {
|
|
return "SEQAND";
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTSeqAnd<ValueType> const& gate) {
|
|
return os << gate.toString();
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTPand : public DFTGate<ValueType> {
|
|
|
|
public:
|
|
DFTPand(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(id, name, children)
|
|
{}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
if(state.isOperational(this->mId)) {
|
|
bool childOperationalBefore = false;
|
|
for(auto const& child : this->mChildren)
|
|
{
|
|
if(!state.hasFailed(child->id())) {
|
|
childOperationalBefore = true;
|
|
} else if(childOperationalBefore && state.hasFailed(child->id())){
|
|
this->failsafe(state, queues);
|
|
this->childrenDontCare(state, queues);
|
|
return;
|
|
}
|
|
}
|
|
if(!childOperationalBefore) {
|
|
this->fail(state, queues);
|
|
}
|
|
}
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
assert(this->hasFailsafeChild(state));
|
|
if(state.isOperational(this->mId)) {
|
|
this->failsafe(state, queues);
|
|
this->childrenDontCare(state, queues);
|
|
}
|
|
}
|
|
|
|
virtual DFTElementType type() const override {
|
|
return DFTElementType::PAND;
|
|
}
|
|
|
|
std::string typestring() const override {
|
|
return "PAND";
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTPand<ValueType> const& gate) {
|
|
return os << gate.toString();
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTPor : public DFTGate<ValueType> {
|
|
public:
|
|
DFTPor(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(id, name, children)
|
|
{}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
assert(false);
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
assert(false);
|
|
}
|
|
|
|
virtual DFTElementType type() const override {
|
|
return DFTElementType::POR;
|
|
}
|
|
|
|
std::string typestring() const override {
|
|
return "POR";
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTPor<ValueType> const& gate) {
|
|
return os << gate.toString();
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTVot : public DFTGate<ValueType> {
|
|
|
|
private:
|
|
unsigned mThreshold;
|
|
|
|
public:
|
|
DFTVot(size_t id, std::string const& name, unsigned threshold, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(id, name, children), mThreshold(threshold)
|
|
{}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
if(state.isOperational(this->mId)) {
|
|
unsigned nrFailedChildren = 0;
|
|
for(auto const& child : this->mChildren)
|
|
{
|
|
if(state.hasFailed(child->id())) {
|
|
++nrFailedChildren;
|
|
if(nrFailedChildren >= mThreshold)
|
|
{
|
|
this->fail(state, queues);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
assert(this->hasFailsafeChild(state));
|
|
if(state.isOperational(this->mId)) {
|
|
unsigned nrFailsafeChildren = 0;
|
|
for(auto const& child : this->mChildren)
|
|
{
|
|
if(state.isFailsafe(child->id())) {
|
|
++nrFailsafeChildren;
|
|
if(nrFailsafeChildren > this->nrChildren() - mThreshold)
|
|
{
|
|
this->failsafe(state, queues);
|
|
this->childrenDontCare(state, queues);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual DFTElementType type() const override {
|
|
return DFTElementType::VOT;
|
|
}
|
|
|
|
std::string typestring() const override{
|
|
return "VOT (" + std::to_string(mThreshold) + ")";
|
|
}
|
|
|
|
virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
|
|
if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
|
|
DFTVot<ValueType> const& otherVOT = static_cast<DFTVot<ValueType> const&>(other);
|
|
return (mThreshold == otherVOT.mThreshold);
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
inline std::ostream& operator<<(std::ostream& os, DFTVot<ValueType> const& gate) {
|
|
return os << gate.toString();
|
|
}
|
|
|
|
|
|
|
|
template<typename ValueType>
|
|
class DFTSpare : public DFTGate<ValueType> {
|
|
|
|
private:
|
|
size_t mUseIndex;
|
|
size_t mActiveIndex;
|
|
|
|
public:
|
|
DFTSpare(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
|
|
DFTGate<ValueType>(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 setUseIndex(size_t useIndex) {
|
|
mUseIndex = useIndex;
|
|
}
|
|
|
|
void setActiveIndex(size_t activeIndex) {
|
|
mActiveIndex = activeIndex;
|
|
}
|
|
|
|
void initializeUses(storm::storage::DFTState<ValueType>& state) {
|
|
assert(this->mChildren.size() > 0);
|
|
state.setUsesAtPosition(mUseIndex, this->mChildren[0]->id());
|
|
}
|
|
|
|
void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
if(state.isOperational(this->mId)) {
|
|
size_t uses = state.extractUses(mUseIndex);
|
|
if(!state.isOperational(uses)) {
|
|
bool claimingSuccessful = state.claimNew(this->mId, mUseIndex, uses, this->mChildren);
|
|
if(!claimingSuccessful) {
|
|
this->fail(state, queues);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
|
|
if(state.isOperational(this->mId)) {
|
|
if(state.isFailsafe(state.extractUses((mUseIndex)))) {
|
|
this->failsafe(state, queues);
|
|
this->childrenDontCare(state, queues);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename ValueType>
|
|
bool equalType(DFTElement<ValueType> const& e1, DFTElement<ValueType> const& e2) {
|
|
return e1.isTypeEqualTo(e2);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endif /* DFTELEMENTS_H */
|
|
|