6template<
typename ValueType>
9 : dft(dft), stateGenerationInfo(stateGenerationInfo), generator(dft, stateGenerationInfo), randomGenerator(randomGenerator) {
14template<
typename ValueType>
16 this->randomGenerator = randomNumberGenerator;
19template<
typename ValueType>
21 resetToState(generator.createInitialState());
25template<
typename ValueType>
30template<
typename ValueType>
35template<
typename ValueType>
40template<
typename ValueType>
45template<
typename ValueType>
47 auto iterFailable = state->getFailableElements().begin();
52 if (!state->hasOperationalRelevantEvent() || iterFailable == state->getFailableElements().end()) {
53 STORM_LOG_TRACE(
"No successor states available for " << state->getId());
54 return std::make_tuple(iterFailable, -1,
true);
58 if (iterFailable.isFailureDueToDependency()) {
59 if (iterFailable.isConflictingDependency()) {
61 STORM_LOG_WARN(
"Non-determinism present! We take the dependency with the lowest id");
64 auto dependency = iterFailable.asDependency(dft);
65 bool successful =
true;
66 if (!dependency->isFDEP()) {
69 successful = probGenerator.
random(randomGenerator);
71 STORM_LOG_TRACE(
"Let dependency " << *dependency <<
" " << (successful ?
"successfully" :
"unsuccessfully") <<
" fail");
72 return std::make_tuple(iterFailable, 0, successful);
77 double rate = state->getBERate(nextFail.
asBE(dft)->id());
79 double smallestTimebound = rateGenerator.
random(randomGenerator);
83 for (; iterFailable != state->getFailableElements().end(); ++iterFailable) {
84 rate = state->getBERate(iterFailable.asBE(dft)->id());
86 double timebound = rateGenerator.
random(randomGenerator);
87 if (timebound < smallestTimebound) {
89 nextFail = iterFailable;
90 smallestTimebound = timebound;
93 STORM_LOG_TRACE(
"Let BE " << *nextFail.
asBE(dft) <<
" fail after time " << smallestTimebound);
94 return std::make_tuple(nextFail, smallestTimebound,
true);
100 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Simulation not support for parametric DFTs.");
103template<
typename ValueType>
106 auto [nextFailable, addTime, successfulDependency] = this->randomNextFailure();
109 STORM_LOG_TRACE(
"No next state possible in state " << dft.getStateString(state) <<
" because no element can fail anymore");
114 auto stepResult = step(nextFailable, successfulDependency);
118 this->time += addTime;
122template<
typename ValueType>
124 if (nextFailElement == state->getFailableElements().end()) {
129 DFTStatePointer newState;
131 newState = generator.createSuccessorState(state, nextFailElement.
asDependency(dft), dependencySuccessful);
133 newState = generator.createSuccessorState(state, nextFailElement.
asBE(dft));
136 if (newState->isInvalid() || newState->isTransient()) {
137 STORM_LOG_TRACE(
"Step is invalid because new state " << (newState->isInvalid() ?
"is invalid." :
"has transient fault."));
145template<
typename ValueType>
153 STORM_LOG_TRACE(
"Invalid state " << dft.getStateString(state) <<
" was reached.");
154 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Handling of invalid states is not supported for simulation");
157 STORM_LOG_TRACE(
"No next state possible in state " << dft.getStateString(state) <<
" because no further failures are possible.");
162 if (getCurrentTime() > timebound) {
165 }
else if (state->hasFailed(dft.getTopLevelIndex())) {
175template<
typename ValueType>
180 if (state->hasFailed(dft.getTopLevelIndex())) {
187 result = simulateNextStep(timebound);
194 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Simulation not support for parametric DFTs.");
SimulationStepResult step(storm::dft::storage::FailableElements::const_iterator nextFailElement, bool dependencySuccessful=true)
Perform one simulation step by letting the next element fail.
void resetToState(DFTStatePointer state)
Set the current state back to the given state.
std::tuple< storm::dft::storage::FailableElements::const_iterator, double, bool > randomNextFailure()
Randomly pick an element which fails next (either a BE or a dependency which triggers a BE) and the t...
SimulationTraceResult simulateNextStep(double timebound)
Simulate the (randomly chosen) next step and return the outcome of the current (partial) trace.
void setTime(double time)
Set the elapsed time so far.
double getCurrentTime() const
Get the total elapsed time so far.
SimulationStepResult randomStep()
Perform a random step by using the random number generator.
SimulationTraceResult simulateCompleteTrace(double timebound)
Perform a complete simulation of a failure trace by using the random number generator.
DFTTraceSimulator(storm::dft::storage::DFT< ValueType > const &dft, storm::dft::storage::DFTStateGenerationInfo const &stateGenerationInfo, boost::mt19937 &randomGenerator)
Constructor.
void resetToInitial()
Set the current state back to the initial state in order to start a new simulation.
void setRandomNumberGenerator(boost::mt19937 &randomNumberGenerator)
Set the random number generator.
DFTStatePointer getCurrentState() const
Get the current DFT state.
Represents a Dynamic Fault Tree.
Iterator for failable elements.
std::shared_ptr< storm::dft::storage::elements::DFTBE< ValueType > const > asBE(storm::dft::storage::DFT< ValueType > const &dft) const
Return the current iterator as a BE which fails next.
bool isFailureDueToDependency() const
Return whether the current failure is due to a dependency (or the BE itself).
std::shared_ptr< storm::dft::storage::elements::DFTDependency< ValueType > const > asDependency(storm::dft::storage::DFT< ValueType > const &dft) const
Return the current iterator as a dependency which triggers next.
bool random(boost::mt19937 &engine)
double random(boost::mt19937 &engine)
#define STORM_LOG_WARN(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
SimulationStepResult
Result of a single simulation step.
SimulationTraceResult
Result of a simulation trace.