9template<
typename ValueType>
 
   11    : mStatus(dft.stateBitVectorSize()),
 
   13      failableElements(dft.nrElements()),
 
   17      mStateGenerationInfo(stateGenerationInfo) {
 
   21    for (
size_t spareId : mDft.getSpareIndices()) {
 
   22        std::shared_ptr<storm::dft::storage::elements::DFTGate<ValueType> 
const> elem = mDft.getGate(spareId);
 
   25        this->
setUses(spareId, elem->children()[0]->id());
 
   29    propagateActivation(mDft.getTopLevelIndex());
 
   32    for (
size_t id : mDft.nonColdBEs()) {
 
   35            failableElements.
addBE(
id);
 
 
   42template<
typename ValueType>
 
   44    : mStatus(status), mId(id), failableElements(dft.nrElements()), indexRelevant(0), mPseudoState(true), mDft(dft), mStateGenerationInfo(stateGenerationInfo) {
 
 
   48template<
typename ValueType>
 
   50    STORM_LOG_TRACE(
"Construct concrete state from pseudo state " << mDft.getStateString(mStatus, mStateGenerationInfo, mId));
 
   52    failableElements.clear();
 
   53    mUsedRepresentants.clear();
 
   55    for (
size_t index = 0; index < mDft.nrElements(); ++index) {
 
   57        if (mDft.isBasicElement(index) && isOperational(index) && !isEventDisabledViaRestriction(index)) {
 
   58            std::shared_ptr<const storm::dft::storage::elements::DFTBE<ValueType>> be = mDft.getBasicElement(index);
 
   61                switch (be->beType()) {
 
   63                        failableElements.addBE(index);
 
   67                        auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType> 
const>(be);
 
   68                        if (!beExp->isColdBasicElement() || !mDft.hasRepresentant(index) || isActive(mDft.getRepresentant(index))) {
 
   69                            failableElements.addBE(index);
 
   75                        STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException, 
"BE type '" << be->beType() << 
"' is not supported.");
 
   79        } 
else if (mDft.getElement(index)->isSpareGate()) {
 
   81            uint_fast64_t useId = uses(index);
 
   82            mUsedRepresentants.push_back(useId);
 
   88    for (
size_t dependencyId : mDft.getDependencies()) {
 
   90            std::shared_ptr<storm::dft::storage::elements::DFTDependency<ValueType> 
const> dependency = mDft.getDependency(dependencyId);
 
   92            STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1, 
"Only one dependent event is allowed.");
 
   93            if (hasFailed(dependency->triggerEvent()->id()) && getElementState(dependency->dependentEvents()[0]->id()) == 
DFTElementState::Operational) {
 
   94                failableElements.addDependency(dependencyId, mDft.isDependencyInConflict(dependencyId));
 
  100    mPseudoState = 
false;
 
 
  103template<
typename ValueType>
 
  105    return std::make_shared<storm::dft::storage::DFTState<ValueType>>(*this);
 
 
  108template<
typename ValueType>
 
  113template<
typename ValueType>
 
  118template<
typename ValueType>
 
  123template<
typename ValueType>
 
  129template<
typename ValueType>
 
  131    return mStatus.getAsInt(mStateGenerationInfo.getStateIndex(
id), 2);
 
  134template<
typename ValueType>
 
  135int DFTState<ValueType>::getElementStateInt(
storm::storage::BitVector const& state, DFTStateGenerationInfo 
const& stateGenerationInfo, 
size_t id) {
 
  136    return state.
getAsInt(stateGenerationInfo.getStateIndex(
id), 2);
 
  139template<
typename ValueType>
 
  144template<
typename ValueType>
 
  149template<
typename ValueType>
 
  154template<
typename ValueType>
 
  156    return mStatus[mStateGenerationInfo.getStateIndex(
id)];
 
 
  159template<
typename ValueType>
 
  161    return state[indexId];
 
 
  164template<
typename ValueType>
 
  166    return mStatus[mStateGenerationInfo.getStateIndex(
id) + 1];
 
 
  169template<
typename ValueType>
 
  171    return state[indexId + 1];
 
 
  174template<
typename ValueType>
 
  179template<
typename ValueType>
 
  181    return getElementStateInt(
id) > 0;
 
 
  184template<
typename ValueType>
 
  186    return mStatus[mStateGenerationInfo.getStateIndex(
id)];
 
 
  188template<
typename ValueType>
 
  190    return mStatus[mStateGenerationInfo.getStateIndex(
id) + 1];
 
 
  193template<
typename ValueType>
 
  195    mStatus.
set(mStateGenerationInfo.getStateIndex(
id));
 
 
  198template<
typename ValueType>
 
  200    mStatus.set(mStateGenerationInfo.getStateIndex(
id) + 1);
 
 
  203template<
typename ValueType>
 
  205    if (mDft.isRepresentative(
id)) {
 
 
  212template<
typename ValueType>
 
  216    setDependencyDontCare(
id);
 
 
  219template<
typename ValueType>
 
  223    setDependencyDontCare(
id);
 
 
  226template<
typename ValueType>
 
  231template<
typename ValueType>
 
  233    failableElements.removeBE(
id);
 
  234    updateDontCareDependencies(
id);
 
 
  237template<
typename ValueType>
 
  239    if (!hasFailed(
id)) {
 
  243    bool addedFailableDependency = 
false;
 
  244    for (
auto dependency : mDft.getElement(
id)->outgoingDependencies()) {
 
  245        STORM_LOG_ASSERT(dependency->triggerEvent()->id() == 
id, 
"Ids do not match.");
 
  247            STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1, 
"Only one dependent event is allowed.");
 
  249                STORM_LOG_ASSERT(!isFailsafe(dependency->dependentEvents()[0]->id()), 
"Dependent event is failsafe.");
 
  252                if (!isEventDisabledViaRestriction(dependency->dependentEvents()[0]->id())) {
 
  254                    failableElements.addDependency(dependency->id(), mDft.isDependencyInConflict(dependency->id()));
 
  256                    addedFailableDependency = 
true;
 
  261    return addedFailableDependency;
 
 
  264template<
typename ValueType>
 
  266    if (!hasFailed(
id)) {
 
  271    bool addedFailableEvent = 
false;
 
  272    for (
auto restriction : mDft.getElement(
id)->restrictions()) {
 
  274        if (restriction->isSeqEnforcer()) {
 
  275            for (
auto it = restriction->children().cbegin(); it != restriction->children().cend(); ++it) {
 
  276                if ((*it)->id() != id) {
 
  277                    if (!hasFailed((*it)->id())) {
 
  284                    STORM_LOG_ASSERT(hasFailed((*it)->id()), 
"Child " << (*it)->name() << 
" should have failed.");
 
  286                    while (it != restriction->children().cend() && !isOperational((*it)->id())) {
 
  289                    if (it != restriction->children().cend() && (*it)->isBasicElement() && isOperational((*it)->id())) {
 
  290                        auto be = std::static_pointer_cast<storm::dft::storage::elements::DFTBE<ValueType> 
const>(*it);
 
  294                            failableElements.addBE((*it)->id());
 
  296                            addedFailableEvent = 
true;
 
  301                        for (
auto dependency : be->ingoingDependencies()) {
 
  302                            change |= updateFailableDependencies(dependency->triggerEvent()->id());
 
  305                            addedFailableEvent = 
true;
 
  311        } 
else if (restriction->isMutex()) {
 
  313            for (
auto const& child : restriction->children()) {
 
  316                    failableElements.removeBE(child->id());
 
  318                    addedFailableEvent = 
true;
 
  322            STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException, 
"Restriction must be SEQ or MUTEX");
 
  325    return addedFailableEvent;
 
 
  328template<
typename ValueType>
 
  333    for (
auto dependency : mDft.getBasicElement(
id)->ingoingDependencies()) {
 
  334        assert(dependency->dependentEvents().size() == 1);
 
  335        STORM_LOG_ASSERT(dependency->dependentEvents()[0]->id() == 
id, 
"Ids do not match.");
 
  336        setDependencyDontCare(dependency->id());
 
  337        failableElements.removeDependency(dependency->id());
 
 
  341template<
typename ValueType>
 
  345                    "BE of type '" << mDft.getBasicElement(
id)->beType() << 
"' is not supported.");
 
  346    auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType> 
const>(mDft.getBasicElement(
id));
 
  347    if (mDft.hasRepresentant(
id) && !isActive(mDft.getRepresentant(
id))) {
 
  349        return beExp->passiveFailureRate();
 
  352        return beExp->activeFailureRate();
 
 
  356template<
typename ValueType>
 
  358    STORM_LOG_ASSERT(!hasFailed(be->id()), 
"Element " << *be << 
" has already failed.");
 
  360    STORM_LOG_ASSERT(be->canFail() || std::any_of(be->ingoingDependencies().begin(), be->ingoingDependencies().end(),
 
  362                                                      return this->dependencySuccessful(dep->id());
 
  364                     "Element " << *be << 
" cannot fail.");
 
  367    failableElements.removeBE(be->id());
 
 
  370template<
typename ValueType>
 
  373    failableElements.removeDependency(dependency->id());
 
  375        setDependencySuccessful(dependency->id());
 
  378        setDependencyUnsuccessful(dependency->id());
 
 
  382template<
typename ValueType>
 
  384    size_t activationIndex = mStateGenerationInfo.getSpareActivationIndex(repr);
 
  385    mStatus.set(activationIndex);
 
 
  388template<
typename ValueType>
 
  390    STORM_LOG_ASSERT(mDft.isRepresentative(
id), 
"Element " << *(mDft.getElement(
id)) << 
" is no representative.");
 
  391    return mStatus[mStateGenerationInfo.getSpareActivationIndex(
id)];
 
 
  394template<
typename ValueType>
 
  396    if (representativeId != mDft.getTopLevelIndex()) {
 
  397        activate(representativeId);
 
  399    for (
size_t elem : mDft.module(representativeId).getElements()) {
 
  400        if (mDft.isBasicElement(elem) && isOperational(elem) && !isEventDisabledViaRestriction(elem)) {
 
  401            std::shared_ptr<const storm::dft::storage::elements::DFTBE<ValueType>> be = mDft.getBasicElement(elem);
 
  403                switch (be->beType()) {
 
  408                        auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType> 
const>(be);
 
  409                        if (beExp->isColdBasicElement()) {
 
  411                            failableElements.addBE(elem);
 
  416                        STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException, 
"BE type '" << be->beType() << 
"' is not supported.");
 
  419        } 
else if (mDft.getElement(elem)->isSpareGate()) {
 
  420            if (isOperational(elem)) {
 
  422                if (!isActive(uses(elem))) {
 
  423                    propagateActivation(uses(elem));
 
  430template<
typename ValueType>
 
  432    size_t nrUsedChild = extractUses(mStateGenerationInfo.getSpareUsageIndex(
id));
 
  433    if (nrUsedChild == mDft.getMaxSpareChildCount()) {
 
  436        return mDft.getChild(
id, nrUsedChild);
 
 
  440template<
typename ValueType>
 
  445template<
typename ValueType>
 
  447    STORM_LOG_ASSERT(mStateGenerationInfo.usageInfoBits() < 64, 
"UsageInfoBit size too large.");
 
  448    return mStatus.getAsInt(from, mStateGenerationInfo.usageInfoBits());
 
 
  451template<
typename ValueType>
 
  453    return (std::find(mUsedRepresentants.begin(), mUsedRepresentants.end(), child) != mUsedRepresentants.end());
 
 
  456template<
typename ValueType>
 
  458    mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getNrChild(spareId, child));
 
  459    mUsedRepresentants.push_back(child);
 
 
  462template<
typename ValueType>
 
  465    mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getMaxSpareChildCount());
 
 
  468template<
typename ValueType>
 
  470    STORM_LOG_ASSERT(!mDft.isDependency(
id), 
"Event " << 
id << 
" is dependency.");
 
  471    STORM_LOG_ASSERT(!mDft.isRestriction(
id), 
"Event " << 
id << 
" is restriction.");
 
  473    auto const& preIds = mStateGenerationInfo.seqRestrictionPreElements(
id);
 
  474    for (
size_t id : preIds) {
 
  475        if (isOperational(
id)) {
 
  481    auto const& mutexIds = mStateGenerationInfo.mutexRestrictionElements(
id);
 
  482    for (
size_t id : mutexIds) {
 
  483        if (!isOperational(
id)) {
 
 
  490template<
typename ValueType>
 
  496    auto const& postIds = mStateGenerationInfo.seqRestrictionPostElements(
id);
 
  497    for (
size_t id : postIds) {
 
  498        if (isOperational(
id)) {
 
  504    auto const& mutexIds = mStateGenerationInfo.mutexRestrictionElements(
id);
 
  505    for (
size_t id : mutexIds) {
 
  506        if (isOperational(
id)) {
 
 
  513template<
typename ValueType>
 
  517    while (indexRelevant < mDft.getRelevantEvents().size()) {
 
  518        if (isOperational(mDft.getRelevantEvents()[indexRelevant])) {
 
 
  529template<
typename ValueType>
 
  532    auto it = children.begin();
 
  533    while ((*it)->id() != currentlyUses) {
 
  534        STORM_LOG_ASSERT(it != children.end(), 
"Currently used element not found.");
 
  538    while (it != children.end()) {
 
  539        size_t childId = (*it)->id();
 
  540        if (!hasFailed(childId) && !isUsed(childId)) {
 
  541            setUses(spareId, childId);
 
  542            if (isActive(currentlyUses)) {
 
  543                propagateActivation(childId);
 
 
  552template<
typename ValueType>
 
  554    bool changed = 
false;
 
  555    for (
size_t pos = 0; pos < mStateGenerationInfo.getSymmetrySize(); ++pos) {
 
  557        size_t length = mStateGenerationInfo.getSymmetryLength(pos);
 
  558        std::vector<size_t> symmetryIndices = mStateGenerationInfo.getSymmetryIndices(pos);
 
  562        size_t n = symmetryIndices.size();
 
  565            for (
size_t i = 1; i < n; ++i) {
 
  567                                 "Symmetry index " << symmetryIndices[i - 1] << 
" + length " << length << 
" is larger than status vector " << mStatus.size());
 
  569                                 "Symmetry index " << symmetryIndices[i] << 
" + length " << length << 
" is larger than status vector " << mStatus.size());
 
  570                if (mStatus.compareAndSwap(symmetryIndices[i - 1], symmetryIndices[i], length)) {
 
 
Represents a Dynamic Fault Tree.
 
size_t getSpareUsageIndex(size_t id) const
 
size_t usageInfoBits() const
 
void letBEFail(std::shared_ptr< storm::dft::storage::elements::DFTBE< ValueType > const > be)
Sets the next BE as failed.
 
void setFailed(size_t id)
 
void setDependencyDontCare(size_t id)
 
bool dependencyUnsuccessful(size_t id) const
 
std::shared_ptr< DFTState< ValueType > > copy() const
 
ValueType getBERate(size_t id) const
Get the current failure rate of the given BE.
 
void setFailsafe(size_t id)
 
DFTState(DFT< ValueType > const &dft, DFTStateGenerationInfo const &stateGenerationInfo, size_t id)
Construct the initial state.
 
bool claimNew(size_t spareId, size_t currentlyUses, std::vector< std::shared_ptr< storm::dft::storage::elements::DFTElement< ValueType > > > const &children)
Claim a new spare child for the given spare gate.
 
void beNoLongerFailable(size_t id)
 
void activate(size_t repr)
 
DFTDependencyState getDependencyState(size_t id) const
 
void letDependencyTrigger(std::shared_ptr< storm::dft::storage::elements::DFTDependency< ValueType > const > dependency, bool successful=true)
Trigger the dependency and set it as successful/unsuccessful.
 
void setDontCare(size_t id)
 
bool hasFailed(size_t id) const
 
uint_fast64_t uses(size_t id) const
This method returns the id of the used child for a spare.
 
bool isUsed(size_t child) const
Checks whether an element is currently used.
 
bool isActive(size_t id) const
 
bool hasOperationalRelevantEvent()
Check whether at least one relevant event is still operational.
 
bool updateFailableDependencies(size_t id)
Sets all failable BEs due to dependencies from newly failed element.
 
bool dependencySuccessful(size_t id) const
 
bool isEventRelevantInRestriction(size_t id) const
Check whether the event is still relevant for any restriction.
 
void finalizeUses(size_t spareId)
Sets the use for the spare to a default value to gain consistent states after failures.
 
bool orderBySymmetry()
Order the state in decreasing order using the symmetries.
 
uint_fast64_t extractUses(size_t from) const
This method is commonly used to get the usage information for spares.
 
bool dontCare(size_t id) const
 
bool isOperational(size_t id) const
 
bool updateFailableInRestrictions(size_t id)
Sets all failable BEs due to restrictions from newly failed element.
 
bool isEventDisabledViaRestriction(size_t id) const
Check whether the event cannot fail at the moment due to a restriction.
 
void setDependencyUnsuccessful(size_t id)
 
DFTElementState getElementState(size_t id) const
 
void updateDontCareDependencies(size_t id)
Sets all dependencies dont care whose dependent event is the newly failed BE.
 
void setUses(size_t spareId, size_t child)
Sets for the spare which child is now used.
 
bool isFailsafe(size_t id) const
 
bool dependencyTriggered(size_t id) const
 
void construct()
Construct concrete state from pseudo state by using the underlying bitvector.
 
void setDependencySuccessful(size_t id)
 
static uint_fast64_t usesIndex(storm::storage::BitVector const &state, DFTStateGenerationInfo const &stateGenerationInfo, size_t id)
Returns the index of the used child for a spare gate.
 
void addBE(size_t id)
Add failable BE.
 
Abstract base class for basic events (BEs) in DFTs.
 
Dependency gate with probability p.
 
Abstract base class for DFT elements.
 
A bit vector that is internally represented as a vector of 64-bit values.
 
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
 
uint64_t getAsInt(uint64_t bitIndex, uint64_t numberOfBits) const
Retrieves the content of the current bit vector at the given index for the given number of bits as an...
 
#define STORM_LOG_TRACE(message)
 
#define STORM_LOG_ASSERT(cond, message)
 
#define STORM_LOG_THROW(cond, exception, message)