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(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
uint_fast64_t getAsInt(uint_fast64_t bitIndex, uint_fast64_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)