#pragma once #include "storm/logic/Formula.h" #include "storm/modelchecker/results/CheckResult.h" #include "storm/api/storm.h" #include "storm/utility/Stopwatch.h" #include "storm-dft/storage/dft/DFT.h" namespace storm { namespace modelchecker { /*! * Analyser for DFTs. */ template class DFTModelChecker { public: typedef std::pair approximation_result; typedef std::vector> dft_results; typedef std::vector> property_vector; class ResultOutputVisitor : public boost::static_visitor<> { public: void operator()(ValueType result, std::ostream& os) const { os << result; } void operator()(std::pair const& result, std::ostream& os) const { os << "(" << result.first << ", " << result.second << ")"; } }; /*! * Constructor. */ DFTModelChecker(bool printOutput) : printInfo(printOutput) { } /*! * Main method for checking DFTs. * * @param origDft Original DFT. * @param properties Properties to check for. * @param symred Flag whether symmetry reduction should be used. * @param allowModularisation Flag indicating if modularisation is allowed. * @param relevantEvents List with ids of relevant events which should be observed. * @param allowDCForRelevantEvents If true, Don't Care propagation is allowed even for relevant events. * @param approximationError Error allowed for approximation. Value 0 indicates no approximation. * @param approximationHeuristic Heuristic used for state space exploration. * @param eliminateChains If true, chains of non-Markovian states are elimianted from the resulting MA * @param labelBehavior Behavior of labels of eliminated states * @return Model checking results for the given properties.. */ dft_results check(storm::storage::DFT const& origDft, property_vector const& properties, bool symred = true, bool allowModularisation = true, std::set const& relevantEvents = {}, bool allowDCForRelevantEvents = true, double approximationError = 0.0, storm::builder::ApproximationHeuristic approximationHeuristic = storm::builder::ApproximationHeuristic::DEPTH, bool eliminateChains = false, storm::transformer::EliminationLabelBehavior labelBehavior = storm::transformer::EliminationLabelBehavior::KeepLabels); /*! * Print timings of all operations to stream. * * @param os Output stream to write to. */ void printTimings(std::ostream& os = std::cout); /*! * Print result to stream. * * @param results List of results. * @param os Output stream to write to. */ void printResults(dft_results const& results, std::ostream& os = std::cout); private: bool printInfo; // Timing values storm::utility::Stopwatch buildingTimer; storm::utility::Stopwatch explorationTimer; storm::utility::Stopwatch bisimulationTimer; storm::utility::Stopwatch modelCheckingTimer; storm::utility::Stopwatch totalTimer; /*! * Internal helper for model checking a DFT. * * @param dft DFT. * @param properties Properties to check for. * @param symred Flag indicating if symmetry reduction should be used. * @param allowModularisation Flag indicating if modularisation is allowed. * @param relevantEvents List with ids of relevant events which should be observed. * @param allowDCForRelevantEvents If true, Don't Care propagation is allowed even for relevant events. * @param approximationError Error allowed for approximation. Value 0 indicates no approximation. * @param approximationHeuristic Heuristic used for approximation. * @param eliminateChains If true, chains of non-Markovian states are elimianted from the resulting MA * @param labelBehavior Behavior of labels of eliminated states * @return Model checking results (or in case of approximation two results for lower and upper bound) */ dft_results checkHelper(storm::storage::DFT const& dft, property_vector const& properties, bool symred, bool allowModularisation, std::set const& relevantEvents, bool allowDCForRelevantEvents = true, double approximationError = 0.0, storm::builder::ApproximationHeuristic approximationHeuristic = storm::builder::ApproximationHeuristic::DEPTH, bool eliminateChains = false, storm::transformer::EliminationLabelBehavior labelBehavior = storm::transformer::EliminationLabelBehavior::KeepLabels); /*! * Internal helper for building a CTMC from a DFT via parallel composition. * * @param dft DFT. * @param properties Properties to check for. * @param symred Flag indicating if symmetry reduction should be used. * @param allowModularisation Flag indicating if modularisation is allowed. * @param relevantEvents List with ids of relevant events which should be observed. * @param allowDCForRelevantEvents If true, Don't Care propagation is allowed even for relevant events. * @return CTMC representing the DFT */ std::shared_ptr> buildModelViaComposition(storm::storage::DFT const& dft, property_vector const& properties, bool symred, bool allowModularisation, std::set const& relevantEvents, bool allowDCForRelevantEvents = true); /*! * Check model generated from DFT. * * @param dft The DFT. * @param properties Properties to check for. * @param symred Flag indicating if symmetry reduction should be used. * @param relevantEvents List with ids of relevant events which should be observed. * @param allowDCForRelevantEvents If true, Don't Care propagation is allowed even for relevant events. * @param approximationError Error allowed for approximation. Value 0 indicates no approximation. * @param approximationHeuristic Heuristic used for approximation. * @param eliminateChains If true, chains of non-Markovian states are elimianted from the resulting MA * @param labelBehavior Behavior of labels of eliminated states * * @return Model checking result */ dft_results checkDFT(storm::storage::DFT const& dft, property_vector const& properties, bool symred, std::set const& relevantEvents = {}, bool allowDCForRelevantEvents = true, double approximationError = 0.0, storm::builder::ApproximationHeuristic approximationHeuristic = storm::builder::ApproximationHeuristic::DEPTH, bool eliminateChains = false, storm::transformer::EliminationLabelBehavior labelBehavior = storm::transformer::EliminationLabelBehavior::KeepLabels); /*! * Check the given markov model for the given properties. * * @param model Model to check * @param properties Properties to check for * * @return Model checking result */ std::vector checkModel(std::shared_ptr>& model, property_vector const& properties); /*! * Checks if the computed approximation is sufficient, i.e. * upperBound - lowerBound <= approximationError * mean(lowerBound, upperBound). * * @param lowerBound The lower bound on the result. * @param upperBound The upper bound on the result. * @param approximationError The allowed error for approximating. * @param relative Flag indicating if the error should be relative to 1 or to the mean of lower and upper bound. * * @return True, if the approximation is sufficient. */ bool isApproximationSufficient(ValueType lowerBound, ValueType upperBound, double approximationError, bool relative); }; } }