101 for (; iterFailable != this->state->getFailableElements().end(!exploreDependencies); ++iterFailable) {
102 DFTStatePointer newState;
103 if (iterFailable.isFailureDueToDependency()) {
105 STORM_LOG_ASSERT(exploreDependencies,
"Failure should be due to dependency.");
106 std::shared_ptr<storm::dft::storage::elements::DFTDependency<ValueType>
const> dependency = iterFailable.asDependency(mDft);
108 newState = createSuccessorState(this->state, dependency,
true);
110 auto [newStateId, shouldStop] = getNewStateId(newState, stateToIdCallback);
115 "Self loop was added for " << newStateId <<
" and successful trigger of " << dependency->name());
118 ValueType probability = dependency->probability();
119 choice.addProbability(newStateId, probability);
120 STORM_LOG_TRACE(
"Added transition to " << newStateId <<
" with probability " << probability);
124 DFTStatePointer unsuccessfulState = createSuccessorState(this->state, dependency,
false);
126 StateType unsuccessfulStateId = stateToIdCallback(unsuccessfulState);
127 ValueType remainingProbability = storm::utility::one<ValueType>() - probability;
128 choice.addProbability(unsuccessfulStateId, remainingProbability);
129 STORM_LOG_TRACE(
"Added transition to " << unsuccessfulStateId <<
" with remaining probability " << remainingProbability);
131 "Self loop was added for " << unsuccessfulStateId <<
" and unsuccessful trigger of " << dependency->name());
136 if (!iterFailable.isConflictingDependency()) {
140 if (takeFirstDependency) {
145 STORM_LOG_ASSERT(!exploreDependencies,
"Failure due to dependency should not be possible.");
148 std::shared_ptr<storm::dft::storage::elements::DFTBE<ValueType>
const> nextBE = iterFailable.asBE(mDft);
150 newState = createSuccessorState(this->state, nextBE);
152 auto [newStateId, shouldStop] = getNewStateId(newState, stateToIdCallback);
156 STORM_LOG_ASSERT(newStateId != this->state->getId(),
"Self loop was added for " << newStateId <<
" and failure of " << nextBE->name());
159 ValueType rate = this->state->getBERate(nextBE->id());
161 choice.addProbability(newStateId, rate);
162 STORM_LOG_TRACE(
"Added transition to " << newStateId <<
" with failure rate " << rate);
167 if (exploreDependencies) {
168 if (result.
empty()) {
170 return exploreState(stateToIdCallback,
false, takeFirstDependency);
173 if (choice.size() == 0) {
177 choice.addProbability(this->state->getId(), storm::utility::one<ValueType>());
180 STORM_LOG_ASSERT(choice.size() > 0,
"At least one choice should have been generated.");
185 STORM_LOG_TRACE(
"Finished exploring state: " << mDft.getStateString(state));
190template<
typename ValueType,
typename StateType>
191std::pair<StateType, bool> DftNextStateGenerator<ValueType, StateType>::getNewStateId(DFTStatePointer newState,
192 StateToIdCallback
const& stateToIdCallback)
const {
193 if (newState->isInvalid() || newState->isTransient()) {
194 STORM_LOG_TRACE(
"State is ignored because " << (newState->isInvalid() ?
"it is invalid" :
"the transient fault is ignored"));
195 return std::make_pair(0,
true);
198 if (newState->hasFailed(mDft.getTopLevelIndex()) && uniqueFailedState) {
200 return std::make_pair(0,
false);
203 return std::make_pair(stateToIdCallback(newState),
false);
207template<
typename ValueType,
typename StateType>
210 bool dependencySuccessful)
const {
212 DFTStatePointer newState = origState->copy();
214 if (dependencySuccessful) {
216 STORM_LOG_TRACE(
"With the successful triggering of PDEP " << dependency->name() <<
" [" << dependency->id() <<
"]" <<
" in "
217 << mDft.getStateString(origState));
218 newState->letDependencyTrigger(dependency,
true);
219 STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1,
"Dependency " << dependency->name() <<
" does not have unique dependent event.");
221 "Trigger event " << dependency->dependentEvents().front()->name() <<
" is not a BE.");
222 auto trigger = std::static_pointer_cast<storm::dft::storage::elements::DFTBE<ValueType>
const>(dependency->dependentEvents().front());
223 return createSuccessorState(newState, trigger);
226 STORM_LOG_TRACE(
"With the unsuccessful triggering of PDEP " << dependency->name() <<
" [" << dependency->id() <<
"]" <<
" in "
227 << mDft.getStateString(origState));
228 newState->letDependencyTrigger(dependency,
false);
233template<
typename ValueType,
typename StateType>
237 DFTStatePointer newState = origState->copy();
239 STORM_LOG_TRACE(
"With the failure of " << be->name() <<
" [" << be->id() <<
"]" <<
" in " << mDft.getStateString(origState));
240 newState->letBEFail(be);
244 propagateFailure(newState, be, queues);
249 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>
const>(be);
250 if (beExp->isTransient() && !newState->hasFailed(mDft.getTopLevelIndex())) {
251 newState->markAsTransient();
256 bool discardFailSafe =
false;
257 discardFailSafe |= newState->isInvalid();
258 discardFailSafe |= newState->isTransient();
259 discardFailSafe |= (newState->hasFailed(mDft.getTopLevelIndex()) && uniqueFailedState);
262 if (!discardFailSafe) {
263 propagateFailsafe(newState, be, queues);
266 newState->updateFailableDependencies(be->id());
267 newState->updateDontCareDependencies(be->id());
268 newState->updateFailableInRestrictions(be->id());
273template<
typename ValueType,
typename StateType>
278 for (DFTGatePointer parent : nextBE->parents()) {
279 if (newState->isOperational(parent->id())) {
286 next->checkFails(*newState, queues);
287 newState->updateFailableDependencies(next->id());
288 newState->updateFailableInRestrictions(next->id());
292 for (DFTRestrictionPointer restr : nextBE->restrictions()) {
298 next->checkFails(*newState, queues);
299 newState->updateFailableDependencies(next->id());
300 newState->updateFailableInRestrictions(next->id());
304template<
typename ValueType,
typename StateType>
311 next->checkFailsafe(*newState, queues);
318 next->checkDontCareAnymore(*newState, queues);