No known key found for this signature in database
				  
				  	
						GPG Key ID: 83A57678F739FCD3
				  	
				  
				
			
		
		
		
	
				 2 changed files with 221 additions and 0 deletions
			
			
		@ -0,0 +1,124 @@ | 
				
			|||
#include "DFTTraceSimulator.h"
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace dft { | 
				
			|||
        namespace simulator { | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            DFTTraceSimulator<ValueType>::DFTTraceSimulator(storm::storage::DFT<ValueType> const& dft, storm::storage::DFTStateGenerationInfo const& stateGenerationInfo, boost::mt19937& randomGenerator) : dft(dft), stateGenerationInfo(stateGenerationInfo), generator(dft, stateGenerationInfo), randomGenerator(randomGenerator) { | 
				
			|||
                // Set initial state
 | 
				
			|||
                state = generator.createInitialState(); | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            void DFTTraceSimulator<ValueType>::setRandomNumberGenerator(boost::mt19937& randomNumberGenerator) { | 
				
			|||
                this->randomGenerator = randomNumberGenerator; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            void DFTTraceSimulator<ValueType>::resetToInitial() { | 
				
			|||
                state = generator.createInitialState();; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            typename DFTTraceSimulator<ValueType>::DFTStatePointer DFTTraceSimulator<ValueType>::getCurrentState() const { | 
				
			|||
                return state; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            double DFTTraceSimulator<ValueType>::randomStep() { | 
				
			|||
                auto iterFailable = state->getFailableElements().begin(); | 
				
			|||
 | 
				
			|||
                // Check for absorbing state:
 | 
				
			|||
                // - either no relevant event remains (i.e., all relevant events have failed already), or
 | 
				
			|||
                // - no BE can fail
 | 
				
			|||
                if (!state->hasOperationalRelevantEvent() || iterFailable == state->getFailableElements().end()) { | 
				
			|||
                    STORM_LOG_TRACE("No sucessor states available for " << state->getId()); | 
				
			|||
                    return -1; | 
				
			|||
                } | 
				
			|||
 | 
				
			|||
                // Get all failable elements
 | 
				
			|||
                if (iterFailable.isFailureDueToDependency()) { | 
				
			|||
                    if (iterFailable.isConflictingDependency()) { | 
				
			|||
                        // We take the first dependeny to resolve the non-determinism
 | 
				
			|||
                        STORM_LOG_WARN("Non-determinism present! We take the dependency with the lowest id"); | 
				
			|||
                    } | 
				
			|||
                    STORM_LOG_TRACE("Let dependency " << *iterFailable.getFailBE(dft).second << " fail"); | 
				
			|||
                    bool res = step(iterFailable); | 
				
			|||
                    return res ? 0 : -1; | 
				
			|||
                } else { | 
				
			|||
                    // Consider all "normal" BE failures
 | 
				
			|||
                    // Initialize with first BE
 | 
				
			|||
                    storm::dft::storage::FailableElements::const_iterator nextFail = iterFailable; | 
				
			|||
                    double rate = state->getBERate(iterFailable.getFailBE(dft).first->id()); | 
				
			|||
                    storm::utility::ExponentialDistributionGenerator rateGenerator(rate); | 
				
			|||
                    double smallestTimebound = rateGenerator.random(randomGenerator); | 
				
			|||
                    ++iterFailable; | 
				
			|||
 | 
				
			|||
                    // Consider all other BEs and find the one which fails first
 | 
				
			|||
                    for (; iterFailable != state->getFailableElements().end(); ++iterFailable) { | 
				
			|||
                        auto nextBE = iterFailable.getFailBE(dft).first; | 
				
			|||
                        rate = state->getBERate(nextBE->id()); | 
				
			|||
                        rateGenerator = storm::utility::ExponentialDistributionGenerator(rate); | 
				
			|||
                        double timebound = rateGenerator.random(randomGenerator); | 
				
			|||
                        if (timebound < smallestTimebound) { | 
				
			|||
                            // BE fails earlier -> use as nextFail
 | 
				
			|||
                            nextFail = iterFailable; | 
				
			|||
                            smallestTimebound = timebound; | 
				
			|||
                        } | 
				
			|||
                    } | 
				
			|||
                    STORM_LOG_TRACE("Let BE " << *nextFail.getFailBE(dft).first << "fail after time " << smallestTimebound); | 
				
			|||
                    bool res = step(nextFail); | 
				
			|||
                    return res ? smallestTimebound : -1; | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            bool DFTTraceSimulator<ValueType>::step(storm::dft::storage::FailableElements::const_iterator nextFailElement) { | 
				
			|||
                if (nextFailElement == state->getFailableElements().end()) { | 
				
			|||
                    return false; | 
				
			|||
                } | 
				
			|||
 | 
				
			|||
                auto nextBEPair = nextFailElement.getFailBE(dft); | 
				
			|||
                auto newState = generator.createSuccessorState(state, nextBEPair.first, nextBEPair.second); | 
				
			|||
 | 
				
			|||
                // TODO handle PDEP
 | 
				
			|||
                 | 
				
			|||
                if(newState->isInvalid() || newState->isTransient()) { | 
				
			|||
                    STORM_LOG_TRACE("Step is invalid because new state " << (newState->isInvalid() ? "it is invalid" : "the transient fault is ignored")); | 
				
			|||
                    return false; | 
				
			|||
                } | 
				
			|||
 | 
				
			|||
                state = newState; | 
				
			|||
                return true; | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            template<typename ValueType> | 
				
			|||
            bool DFTTraceSimulator<ValueType>::simulateCompleteTrace(double timebound) { | 
				
			|||
                resetToInitial(); | 
				
			|||
                double time = 0; | 
				
			|||
                while (time <= timebound) { | 
				
			|||
                    // Check whether DFT failed within timebound
 | 
				
			|||
                    if (state->hasFailed(dft.getTopLevelIndex())) { | 
				
			|||
                        STORM_LOG_TRACE("DFT has failed after " << time); | 
				
			|||
                        return true; | 
				
			|||
                    } | 
				
			|||
 | 
				
			|||
                    // Generate next state
 | 
				
			|||
                    double res = randomStep(); | 
				
			|||
                    STORM_LOG_TRACE("Current state: " << dft.getStateString(state)); | 
				
			|||
                    if (res < 0) { | 
				
			|||
                        // No next state can be reached
 | 
				
			|||
                        STORM_LOG_TRACE("No next state possible in state " << dft.getStateString(state)); | 
				
			|||
                        return false; | 
				
			|||
                    } | 
				
			|||
                    time += res; | 
				
			|||
                } | 
				
			|||
                // Time is up
 | 
				
			|||
                return false; | 
				
			|||
            }  | 
				
			|||
 | 
				
			|||
            template class DFTTraceSimulator<double>; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -0,0 +1,97 @@ | 
				
			|||
#include "storm-dft/generator/DftNextStateGenerator.h" | 
				
			|||
#include "storm-dft/storage/dft/DFT.h" | 
				
			|||
#include "storm-dft/storage/dft/DFTState.h" | 
				
			|||
#include "storm-dft/storage/dft/FailableElements.h" | 
				
			|||
 | 
				
			|||
#include "storm/utility/random.h" | 
				
			|||
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace dft { | 
				
			|||
        namespace simulator { | 
				
			|||
 | 
				
			|||
            /*! | 
				
			|||
             * Simulator for DFTs. | 
				
			|||
             * A step in the simulation corresponds to the failure of one BE (either on its own or triggered by a dependency) | 
				
			|||
             * and the failure propagation through the DFT. | 
				
			|||
             * The simulator also allows to randomly generate a next failure according to the failure rates. | 
				
			|||
             */ | 
				
			|||
            template<typename ValueType> | 
				
			|||
            class DFTTraceSimulator { | 
				
			|||
                using DFTStatePointer = std::shared_ptr<storm::storage::DFTState<ValueType>>; | 
				
			|||
            public: | 
				
			|||
                /*! | 
				
			|||
                 * Constructor. | 
				
			|||
                 *  | 
				
			|||
                 * @param dft DFT. | 
				
			|||
                 * @param stateGenerationInfo Info for state generation. | 
				
			|||
                 * @param randomGenerator Random number generator. | 
				
			|||
                 */ | 
				
			|||
                DFTTraceSimulator(storm::storage::DFT<ValueType> const& dft, storm::storage::DFTStateGenerationInfo const& stateGenerationInfo, boost::mt19937& randomGenerator); | 
				
			|||
 | 
				
			|||
                /*! | 
				
			|||
                 * Set the random number generator. | 
				
			|||
                 *  | 
				
			|||
                 * @param randomNumberGenerator Random number generator. | 
				
			|||
                 */ | 
				
			|||
                void setRandomNumberGenerator(boost::mt19937& randomNumberGenerator); | 
				
			|||
 | 
				
			|||
                /*! | 
				
			|||
                 * Set the current state back to the intial state in order to start a new simulation. | 
				
			|||
                 */ | 
				
			|||
                void resetToInitial(); | 
				
			|||
 | 
				
			|||
                /*! | 
				
			|||
                 * Get the current DFT state. | 
				
			|||
                 *  | 
				
			|||
                 * @return DFTStatePointer DFT state. | 
				
			|||
                 */ | 
				
			|||
                DFTStatePointer getCurrentState() const; | 
				
			|||
 | 
				
			|||
                /*! | 
				
			|||
                 * Perform one simulation step by letting the next element fail. | 
				
			|||
                 *  | 
				
			|||
                 * @param nextFailElement Iterator giving the next element which should fail. | 
				
			|||
                 * @return True iff step could be performed successfully. | 
				
			|||
                 */ | 
				
			|||
                bool step(storm::dft::storage::FailableElements::const_iterator nextFailElement); | 
				
			|||
 | 
				
			|||
                /*! | 
				
			|||
                 * Perform a random step by using the random number generator. | 
				
			|||
                 *  | 
				
			|||
                 * @return double The time which progessed between the last step and this step. | 
				
			|||
                 *      Returns -1 if no next step could be created. | 
				
			|||
                 */ | 
				
			|||
                double randomStep(); | 
				
			|||
 | 
				
			|||
                /*! | 
				
			|||
                 * Perform a complete simulation of a failure trace by using the random number generator. | 
				
			|||
                 * The simulation starts in the initial state and tries to reach a state where the top-level event of the DFT has failed. | 
				
			|||
                 * If this target state can be reached within the given timebound, the simulation was successful. | 
				
			|||
                 *  | 
				
			|||
                 * @param timebound Time bound in which the system failure should occur. | 
				
			|||
                 * @return True iff a system failure occurred for the generated trace within the time bound. | 
				
			|||
                 */ | 
				
			|||
                bool simulateCompleteTrace(double timebound); | 
				
			|||
 | 
				
			|||
            protected: | 
				
			|||
 | 
				
			|||
                // The DFT used for the generation of next states. | 
				
			|||
                storm::storage::DFT<ValueType> const& dft; | 
				
			|||
 | 
				
			|||
                // General information for the state generation. | 
				
			|||
                storm::storage::DFTStateGenerationInfo const& stateGenerationInfo; | 
				
			|||
 | 
				
			|||
                // Generator for creating next state in DFT | 
				
			|||
                storm::generator::DftNextStateGenerator<double> generator; | 
				
			|||
 | 
				
			|||
                // Current state | 
				
			|||
                DFTStatePointer state; | 
				
			|||
 | 
				
			|||
                // Random number generator | 
				
			|||
                boost::mt19937& randomGenerator; | 
				
			|||
            }; | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue