100 for (; iterFailable != this->state->getFailableElements().end(!exploreDependencies); ++iterFailable) {
101 DFTStatePointer newState;
102 if (iterFailable.isFailureDueToDependency()) {
104 STORM_LOG_ASSERT(exploreDependencies,
"Failure should be due to dependency.");
105 std::shared_ptr<storm::dft::storage::elements::DFTDependency<ValueType>
const> dependency = iterFailable.asDependency(mDft);
107 newState = createSuccessorState(this->state, dependency,
true);
109 auto [newStateId, shouldStop] = getNewStateId(newState, stateToIdCallback);
114 "Self loop was added for " << newStateId <<
" and successful trigger of " << dependency->name());
117 ValueType probability = dependency->probability();
118 choice.addProbability(newStateId, probability);
119 STORM_LOG_TRACE(
"Added transition to " << newStateId <<
" with probability " << probability);
123 DFTStatePointer unsuccessfulState = createSuccessorState(this->state, dependency,
false);
125 StateType unsuccessfulStateId = stateToIdCallback(unsuccessfulState);
126 ValueType remainingProbability = storm::utility::one<ValueType>() - probability;
127 choice.addProbability(unsuccessfulStateId, remainingProbability);
128 STORM_LOG_TRACE(
"Added transition to " << unsuccessfulStateId <<
" with remaining probability " << remainingProbability);
130 "Self loop was added for " << unsuccessfulStateId <<
" and unsuccessful trigger of " << dependency->name());
135 if (!iterFailable.isConflictingDependency()) {
139 if (takeFirstDependency) {
144 STORM_LOG_ASSERT(!exploreDependencies,
"Failure due to dependency should not be possible.");
147 std::shared_ptr<storm::dft::storage::elements::DFTBE<ValueType>
const> nextBE = iterFailable.asBE(mDft);
149 newState = createSuccessorState(this->state, nextBE);
151 auto [newStateId, shouldStop] = getNewStateId(newState, stateToIdCallback);
155 STORM_LOG_ASSERT(newStateId != this->state->getId(),
"Self loop was added for " << newStateId <<
" and failure of " << nextBE->name());
158 ValueType rate = this->state->getBERate(nextBE->id());
160 choice.addProbability(newStateId, rate);
161 STORM_LOG_TRACE(
"Added transition to " << newStateId <<
" with failure rate " << rate);
166 if (exploreDependencies) {
167 if (result.
empty()) {
169 return exploreState(stateToIdCallback,
false, takeFirstDependency);
172 if (choice.size() == 0) {
176 choice.addProbability(this->state->getId(), storm::utility::one<ValueType>());
179 STORM_LOG_ASSERT(choice.size() > 0,
"At least one choice should have been generated.");
184 STORM_LOG_TRACE(
"Finished exploring state: " << mDft.getStateString(state));
189template<
typename ValueType,
typename StateType>
190std::pair<StateType, bool> DftNextStateGenerator<ValueType, StateType>::getNewStateId(DFTStatePointer newState,
191 StateToIdCallback
const& stateToIdCallback)
const {
192 if (newState->isInvalid() || newState->isTransient()) {
193 STORM_LOG_TRACE(
"State is ignored because " << (newState->isInvalid() ?
"it is invalid" :
"the transient fault is ignored"));
194 return std::make_pair(0,
true);
197 if (newState->hasFailed(mDft.getTopLevelIndex()) && uniqueFailedState) {
199 return std::make_pair(0,
false);
202 return std::make_pair(stateToIdCallback(newState),
false);
206template<
typename ValueType,
typename StateType>
209 bool dependencySuccessful)
const {
211 DFTStatePointer newState = origState->copy();
213 if (dependencySuccessful) {
215 STORM_LOG_TRACE(
"With the successful triggering of PDEP " << dependency->name() <<
" [" << dependency->id() <<
"]" <<
" in "
216 << mDft.getStateString(origState));
217 newState->letDependencyTrigger(dependency,
true);
218 STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1,
"Dependency " << dependency->name() <<
" does not have unique dependent event.");
220 "Trigger event " << dependency->dependentEvents().front()->name() <<
" is not a BE.");
221 auto trigger = std::static_pointer_cast<storm::dft::storage::elements::DFTBE<ValueType>
const>(dependency->dependentEvents().front());
222 return createSuccessorState(newState, trigger);
225 STORM_LOG_TRACE(
"With the unsuccessful triggering of PDEP " << dependency->name() <<
" [" << dependency->id() <<
"]" <<
" in "
226 << mDft.getStateString(origState));
227 newState->letDependencyTrigger(dependency,
false);
232template<
typename ValueType,
typename StateType>
236 DFTStatePointer newState = origState->copy();
238 STORM_LOG_TRACE(
"With the failure of " << be->name() <<
" [" << be->id() <<
"]" <<
" in " << mDft.getStateString(origState));
239 newState->letBEFail(be);
243 propagateFailure(newState, be, queues);
248 auto beExp = std::static_pointer_cast<storm::dft::storage::elements::BEExponential<ValueType>
const>(be);
249 if (beExp->isTransient() && !newState->hasFailed(mDft.getTopLevelIndex())) {
250 newState->markAsTransient();
255 bool discardFailSafe =
false;
256 discardFailSafe |= newState->isInvalid();
257 discardFailSafe |= newState->isTransient();
258 discardFailSafe |= (newState->hasFailed(mDft.getTopLevelIndex()) && uniqueFailedState);
261 if (!discardFailSafe) {
262 propagateFailsafe(newState, be, queues);
265 newState->updateFailableDependencies(be->id());
266 newState->updateDontCareDependencies(be->id());
267 newState->updateFailableInRestrictions(be->id());
272template<
typename ValueType,
typename StateType>
277 for (DFTGatePointer parent : nextBE->parents()) {
278 if (newState->isOperational(parent->id())) {
285 next->checkFails(*newState, queues);
286 newState->updateFailableDependencies(next->id());
287 newState->updateFailableInRestrictions(next->id());
291 for (DFTRestrictionPointer restr : nextBE->restrictions()) {
297 next->checkFails(*newState, queues);
298 newState->updateFailableDependencies(next->id());
299 newState->updateFailableInRestrictions(next->id());
303template<
typename ValueType,
typename StateType>
310 next->checkFailsafe(*newState, queues);
317 next->checkDontCareAnymore(*newState, queues);