#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: std::string operator()(ValueType result) const { std::stringstream stream; stream << result; return stream.str(); } std::string operator()(std::pair const& result) const { std::stringstream stream; stream << "(" << result.first << ", " << result.second << ")"; return stream.str(); } }; /*! * 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 approximationError Error allowed for approximation. Value 0 indicates no approximation. * @param approximationHeuristic Heuristic used for state space exploration. * @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 = {}, double approximationError = 0.0, storm::builder::ApproximationHeuristic approximationHeuristic = storm::builder::ApproximationHeuristic::DEPTH); /*! * 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 approximationError Error allowed for approximation. Value 0 indicates no approximation. * @param approximationHeuristic Heuristic used for approximation. * @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, double approximationError, storm::builder::ApproximationHeuristic approximationHeuristic = storm::builder::ApproximationHeuristic::DEPTH); /*! * 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. * @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); /*! * 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 approximationError Error allowed for approximation. Value 0 indicates no approximation. * @param approximationHeuristic Heuristic used for approximation. * * @return Model checking result */ dft_results checkDFT(storm::storage::DFT const& dft, property_vector const& properties, bool symred, std::set const& relevantEvents = {}, double approximationError = 0.0, storm::builder::ApproximationHeuristic approximationHeuristic = storm::builder::ApproximationHeuristic::DEPTH); /*! * 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); }; } }