11template<
typename ValueType>
13 : mStatus(dft.stateBitVectorSize()),
15 failableElements(dft.nrElements()),
19 mStateGenerationInfo(stateGenerationInfo) {
23 for (
size_t spareId : mDft.getSpareIndices()) {
24 std::shared_ptr<storm::dft::storage::elements::DFTGate<ValueType>
const> elem = mDft.getGate(spareId);
27 this->
setUses(spareId, elem->children()[0]->id());
31 propagateActivation(mDft.getTopLevelIndex());
34 for (
size_t id : mDft.nonColdBEs()) {
37 failableElements.
addBE(
id);
44template<
typename ValueType>
46 : mStatus(status), mId(id), failableElements(dft.nrElements()), indexRelevant(0), mPseudoState(true), mDft(dft), mStateGenerationInfo(stateGenerationInfo) {
50template<
typename ValueType>
52 STORM_LOG_TRACE(
"Construct concrete state from pseudo state " << mDft.getStateString(mStatus, mStateGenerationInfo, mId));
54 failableElements.clear();
55 mUsedRepresentants.clear();
57 for (
size_t index = 0; index < mDft.nrElements(); ++index) {
59 if (mDft.isBasicElement(index) && isOperational(index) && !isEventDisabledViaRestriction(index)) {
60 std::shared_ptr<const storm::dft::storage::elements::DFTBE<ValueType>> be = mDft.getBasicElement(index);
63 switch (be->beType()) {
65 failableElements.addBE(index);
69 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>
const>(be);
70 if (!beExp->isColdBasicElement() || !mDft.hasRepresentant(index) || isActive(mDft.getRepresentant(index))) {
71 failableElements.addBE(index);
77 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"BE type '" << be->beType() <<
"' is not supported.");
81 }
else if (mDft.getElement(index)->isSpareGate()) {
83 uint_fast64_t useId = uses(index);
84 mUsedRepresentants.push_back(useId);
90 for (
size_t dependencyId : mDft.getDependencies()) {
92 std::shared_ptr<storm::dft::storage::elements::DFTDependency<ValueType>
const> dependency = mDft.getDependency(dependencyId);
94 STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1,
"Only one dependent event is allowed.");
95 if (hasFailed(dependency->triggerEvent()->id()) && getElementState(dependency->dependentEvents()[0]->id()) ==
DFTElementState::Operational) {
96 failableElements.addDependency(dependencyId, mDft.isDependencyInConflict(dependencyId));
102 mPseudoState =
false;
105template<
typename ValueType>
107 return std::make_shared<storm::dft::storage::DFTState<ValueType>>(*this);
110template<
typename ValueType>
115template<
typename ValueType>
120template<
typename ValueType>
125template<
typename ValueType>
131template<
typename ValueType>
133 return mStatus.getAsInt(mStateGenerationInfo.getStateIndex(
id), 2);
136template<
typename ValueType>
137int DFTState<ValueType>::getElementStateInt(
storm::storage::BitVector const& state, DFTStateGenerationInfo
const& stateGenerationInfo,
size_t id) {
138 return state.
getAsInt(stateGenerationInfo.getStateIndex(
id), 2);
141template<
typename ValueType>
146template<
typename ValueType>
151template<
typename ValueType>
156template<
typename ValueType>
158 return mStatus[mStateGenerationInfo.getStateIndex(
id)];
161template<
typename ValueType>
163 return state[indexId];
166template<
typename ValueType>
168 return mStatus[mStateGenerationInfo.getStateIndex(
id) + 1];
171template<
typename ValueType>
173 return state[indexId + 1];
176template<
typename ValueType>
181template<
typename ValueType>
183 return getElementStateInt(
id) > 0;
186template<
typename ValueType>
188 return mStatus[mStateGenerationInfo.getStateIndex(
id)];
190template<
typename ValueType>
192 return mStatus[mStateGenerationInfo.getStateIndex(
id) + 1];
195template<
typename ValueType>
197 mStatus.
set(mStateGenerationInfo.getStateIndex(
id));
200template<
typename ValueType>
202 mStatus.set(mStateGenerationInfo.getStateIndex(
id) + 1);
205template<
typename ValueType>
207 if (mDft.isRepresentative(
id)) {
214template<
typename ValueType>
218 setDependencyDontCare(
id);
221template<
typename ValueType>
225 setDependencyDontCare(
id);
228template<
typename ValueType>
233template<
typename ValueType>
235 failableElements.removeBE(
id);
236 updateDontCareDependencies(
id);
239template<
typename ValueType>
241 if (!hasFailed(
id)) {
245 bool addedFailableDependency =
false;
246 for (
auto dependency : mDft.getElement(
id)->outgoingDependencies()) {
247 STORM_LOG_ASSERT(dependency->triggerEvent()->id() ==
id,
"Ids do not match.");
249 STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1,
"Only one dependent event is allowed.");
251 STORM_LOG_ASSERT(!isFailsafe(dependency->dependentEvents()[0]->id()),
"Dependent event is failsafe.");
254 if (!isEventDisabledViaRestriction(dependency->dependentEvents()[0]->id())) {
256 failableElements.addDependency(dependency->id(), mDft.isDependencyInConflict(dependency->id()));
258 addedFailableDependency =
true;
263 return addedFailableDependency;
266template<
typename ValueType>
268 if (!hasFailed(
id)) {
273 bool addedFailableEvent =
false;
274 for (
auto restriction : mDft.getElement(
id)->restrictions()) {
276 if (restriction->isSeqEnforcer()) {
277 for (
auto it = restriction->children().cbegin(); it != restriction->children().cend(); ++it) {
278 if ((*it)->id() != id) {
279 if (!hasFailed((*it)->id())) {
286 STORM_LOG_ASSERT(hasFailed((*it)->id()),
"Child " << (*it)->name() <<
" should have failed.");
288 while (it != restriction->children().cend() && !isOperational((*it)->id())) {
291 if (it != restriction->children().cend() && (*it)->isBasicElement() && isOperational((*it)->id())) {
292 auto be = std::static_pointer_cast<storm::dft::storage::elements::DFTBE<ValueType>
const>(*it);
296 failableElements.addBE((*it)->id());
298 addedFailableEvent =
true;
303 for (
auto dependency : be->ingoingDependencies()) {
304 change |= updateFailableDependencies(dependency->triggerEvent()->id());
307 addedFailableEvent =
true;
313 }
else if (restriction->isMutex()) {
315 for (
auto const& child : restriction->children()) {
318 failableElements.removeBE(child->id());
320 addedFailableEvent =
true;
324 STORM_LOG_THROW(
false, storm::exceptions::InvalidArgumentException,
"Restriction must be SEQ or MUTEX");
327 return addedFailableEvent;
330template<
typename ValueType>
335 for (
auto dependency : mDft.getBasicElement(
id)->ingoingDependencies()) {
336 assert(dependency->dependentEvents().size() == 1);
337 STORM_LOG_ASSERT(dependency->dependentEvents()[0]->id() ==
id,
"Ids do not match.");
338 setDependencyDontCare(dependency->id());
339 failableElements.removeDependency(dependency->id());
343template<
typename ValueType>
347 "BE of type '" << mDft.getBasicElement(
id)->beType() <<
"' is not supported.");
348 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>
const>(mDft.getBasicElement(
id));
349 if (mDft.hasRepresentant(
id) && !isActive(mDft.getRepresentant(
id))) {
351 return beExp->passiveFailureRate();
354 return beExp->activeFailureRate();
358template<
typename ValueType>
360 STORM_LOG_ASSERT(!hasFailed(be->id()),
"Element " << *be <<
" has already failed.");
362 STORM_LOG_ASSERT(be->canFail() || std::any_of(be->ingoingDependencies().begin(), be->ingoingDependencies().end(),
364 return this->dependencySuccessful(dep->id());
366 "Element " << *be <<
" cannot fail.");
369 failableElements.removeBE(be->id());
372template<
typename ValueType>
375 failableElements.removeDependency(dependency->id());
377 setDependencySuccessful(dependency->id());
380 setDependencyUnsuccessful(dependency->id());
384template<
typename ValueType>
386 size_t activationIndex = mStateGenerationInfo.getSpareActivationIndex(repr);
387 mStatus.set(activationIndex);
390template<
typename ValueType>
392 STORM_LOG_ASSERT(mDft.isRepresentative(
id),
"Element " << *(mDft.getElement(
id)) <<
" is no representative.");
393 return mStatus[mStateGenerationInfo.getSpareActivationIndex(
id)];
396template<
typename ValueType>
398 if (representativeId != mDft.getTopLevelIndex()) {
399 activate(representativeId);
401 for (
size_t elem : mDft.module(representativeId).getElements()) {
402 if (mDft.isBasicElement(elem) && isOperational(elem) && !isEventDisabledViaRestriction(elem)) {
403 std::shared_ptr<const storm::dft::storage::elements::DFTBE<ValueType>> be = mDft.getBasicElement(elem);
405 switch (be->beType()) {
410 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>
const>(be);
411 if (beExp->isColdBasicElement()) {
413 failableElements.addBE(elem);
418 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"BE type '" << be->beType() <<
"' is not supported.");
421 }
else if (mDft.getElement(elem)->isSpareGate()) {
422 if (isOperational(elem)) {
424 if (!isActive(uses(elem))) {
425 propagateActivation(uses(elem));
432template<
typename ValueType>
434 size_t nrUsedChild = extractUses(mStateGenerationInfo.getSpareUsageIndex(
id));
435 if (nrUsedChild == mDft.getMaxSpareChildCount()) {
438 return mDft.getChild(
id, nrUsedChild);
442template<
typename ValueType>
447template<
typename ValueType>
449 STORM_LOG_ASSERT(mStateGenerationInfo.usageInfoBits() < 64,
"UsageInfoBit size too large.");
450 return mStatus.getAsInt(from, mStateGenerationInfo.usageInfoBits());
453template<
typename ValueType>
455 return (std::find(mUsedRepresentants.begin(), mUsedRepresentants.end(), child) != mUsedRepresentants.end());
458template<
typename ValueType>
460 mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getNrChild(spareId, child));
461 mUsedRepresentants.push_back(child);
464template<
typename ValueType>
467 mStatus.setFromInt(mStateGenerationInfo.getSpareUsageIndex(spareId), mStateGenerationInfo.usageInfoBits(), mDft.getMaxSpareChildCount());
470template<
typename ValueType>
472 STORM_LOG_ASSERT(!mDft.isDependency(
id),
"Event " <<
id <<
" is dependency.");
473 STORM_LOG_ASSERT(!mDft.isRestriction(
id),
"Event " <<
id <<
" is restriction.");
475 auto const& preIds = mStateGenerationInfo.seqRestrictionPreElements(
id);
476 for (
size_t id : preIds) {
477 if (isOperational(
id)) {
483 auto const& mutexIds = mStateGenerationInfo.mutexRestrictionElements(
id);
484 for (
size_t id : mutexIds) {
485 if (!isOperational(
id)) {
492template<
typename ValueType>
498 auto const& postIds = mStateGenerationInfo.seqRestrictionPostElements(
id);
499 for (
size_t id : postIds) {
500 if (isOperational(
id)) {
506 auto const& mutexIds = mStateGenerationInfo.mutexRestrictionElements(
id);
507 for (
size_t id : mutexIds) {
508 if (isOperational(
id)) {
515template<
typename ValueType>
519 while (indexRelevant < mDft.getRelevantEvents().size()) {
520 if (isOperational(mDft.getRelevantEvents()[indexRelevant])) {
531template<
typename ValueType>
534 auto it = children.begin();
535 while ((*it)->id() != currentlyUses) {
536 STORM_LOG_ASSERT(it != children.end(),
"Currently used element not found.");
540 while (it != children.end()) {
541 size_t childId = (*it)->id();
542 if (!hasFailed(childId) && !isUsed(childId)) {
543 setUses(spareId, childId);
544 if (isActive(currentlyUses)) {
545 propagateActivation(childId);
554template<
typename ValueType>
556 bool changed =
false;
557 for (
size_t pos = 0; pos < mStateGenerationInfo.getSymmetrySize(); ++pos) {
559 size_t length = mStateGenerationInfo.getSymmetryLength(pos);
560 std::vector<size_t> symmetryIndices = mStateGenerationInfo.getSymmetryIndices(pos);
564 size_t n = symmetryIndices.size();
567 for (
size_t i = 1; i < n; ++i) {
569 "Symmetry index " << symmetryIndices[i - 1] <<
" + length " << length <<
" is larger than status vector " << mStatus.size());
571 "Symmetry index " << symmetryIndices[i] <<
" + length " << length <<
" is larger than status vector " << mStatus.size());
572 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)