#include "storm/utility/Engine.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/models/symbolic/StandardRewardModel.h" #include "storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" #include "storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h" #include "storm/modelchecker/csl/SparseCtmcCslModelChecker.h" #include "storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h" #include "storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h" #include "storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h" #include "storm/modelchecker/csl/HybridCtmcCslModelChecker.h" #include "storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.h" #include "storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h" #include "storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h" #include "storm/modelchecker/CheckTask.h" #include "storm/storage/SymbolicModelDescription.h" #include "storm/storage/jani/Property.h" #include "storm/utility/macros.h" #include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace utility { // Returns a list of all available engines (excluding Unknown) std::vector getEngines() { std::vector res; for (int i = 0; i != static_cast(Engine::Unknown); ++i) { res.push_back(static_cast(i)); } return res; } std::string toString(Engine const& engine) { switch (engine) { case Engine::Sparse: return "sparse"; case Engine::Hybrid: return "hybrid"; case Engine::Dd: return "dd"; case Engine::DdSparse: return "dd-to-sparse"; case Engine::Jit: return "jit"; case Engine::Exploration: return "expl"; case Engine::AbstractionRefinement: return "abs"; case Engine::Automatic: return "automatic"; case Engine::Unknown: return "UNKNOWN"; default: STORM_LOG_ASSERT(false, "The given engine has no name assigned to it."); return "UNKNOWN"; } } std::ostream& operator<<(std::ostream& os, Engine const& engine) { os << toString(engine); return os; } Engine engineFromString(std::string const& engineStr) { for (Engine const& e : getEngines()) { if (engineStr == toString(e)) { return e; } } if (engineStr == "portfolio") { STORM_LOG_WARN("The engine name \"portfolio\" is deprecated. The name of this engine has been changed to \"" << toString(Engine::Automatic) << "\"."); return Engine::Automatic; } STORM_LOG_ERROR("The engine '" << engineStr << "' was not found."); return Engine::Unknown; } storm::builder::BuilderType getBuilderType(Engine const& engine) { switch (engine) { case Engine::Sparse: return storm::builder::BuilderType::Explicit; case Engine::Hybrid: return storm::builder::BuilderType::Dd; case Engine::Dd: return storm::builder::BuilderType::Dd; case Engine::DdSparse: return storm::builder::BuilderType::Dd; case Engine::Jit: return storm::builder::BuilderType::Jit; case Engine::Exploration: return storm::builder::BuilderType::Explicit; case Engine::AbstractionRefinement: return storm::builder::BuilderType::Dd; default: STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given engine has no builder type to it."); return storm::builder::BuilderType::Explicit; } } template bool canHandle(storm::utility::Engine const& engine, storm::storage::SymbolicModelDescription::ModelType const& modelType, storm::modelchecker::CheckTask const& checkTask) { // Define types to improve readability typedef storm::storage::SymbolicModelDescription::ModelType ModelType; // The Dd library does not make much of a difference (in case of exact or parametric models we will switch to sylvan anyway). // Therefore, we always use sylvan here storm::dd::DdType const ddType = storm::dd::DdType::Sylvan; switch (engine) { case Engine::Sparse: case Engine::DdSparse: case Engine::Jit: switch (modelType) { case ModelType::DTMC: return storm::modelchecker::SparseDtmcPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::MDP: return storm::modelchecker::SparseMdpPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::CTMC: return storm::modelchecker::SparseCtmcCslModelChecker>::canHandleStatic(checkTask); case ModelType::MA: return storm::modelchecker::SparseMarkovAutomatonCslModelChecker>::canHandleStatic(checkTask); case ModelType::POMDP: return false; } break; case Engine::Hybrid: switch (modelType) { case ModelType::DTMC: return storm::modelchecker::HybridDtmcPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::MDP: return storm::modelchecker::HybridMdpPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::CTMC: return storm::modelchecker::HybridCtmcCslModelChecker>::canHandleStatic(checkTask); case ModelType::MA: return storm::modelchecker::HybridMarkovAutomatonCslModelChecker>::canHandleStatic(checkTask); case ModelType::POMDP: return false; } break; case Engine::Dd: switch (modelType) { case ModelType::DTMC: return storm::modelchecker::SymbolicDtmcPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::MDP: return storm::modelchecker::SymbolicMdpPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::CTMC: case ModelType::MA: case ModelType::POMDP: return false; } break; default: STORM_LOG_ERROR("The selected engine " << engine << " is not considered."); } STORM_LOG_ERROR("The selected combination of engine (" << engine << ") and model type (" << modelType << ") does not seem to be supported for this value type."); return false; } template <> bool canHandle(storm::utility::Engine const& engine, storm::storage::SymbolicModelDescription::ModelType const& modelType, storm::modelchecker::CheckTask const& checkTask) { // Define types to improve readability typedef storm::storage::SymbolicModelDescription::ModelType ModelType; // The Dd library does not make much of a difference (in case of exact or parametric models we will switch to sylvan anyway). // Therefore, we always use sylvan here storm::dd::DdType const ddType = storm::dd::DdType::Sylvan; switch (engine) { case Engine::Sparse: case Engine::DdSparse: switch (modelType) { case ModelType::DTMC: return storm::modelchecker::SparseDtmcPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::CTMC: return storm::modelchecker::SparseCtmcCslModelChecker>::canHandleStatic(checkTask); case ModelType::MDP: case ModelType::MA: case ModelType::POMDP: return false; } break; case Engine::Hybrid: switch (modelType) { case ModelType::DTMC: return storm::modelchecker::HybridDtmcPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::CTMC: return storm::modelchecker::HybridCtmcCslModelChecker>::canHandleStatic(checkTask); case ModelType::MDP: case ModelType::MA: case ModelType::POMDP: return false; } break; case Engine::Dd: switch (modelType) { case ModelType::DTMC: return storm::modelchecker::SymbolicDtmcPrctlModelChecker>::canHandleStatic(checkTask); case ModelType::MDP: case ModelType::CTMC: case ModelType::MA: case ModelType::POMDP: return false; } break; default: STORM_LOG_ERROR("The selected engine" << engine << " is not considered."); } STORM_LOG_ERROR("The selected combination of engine (" << engine << ") and model type (" << modelType << ") does not seem to be supported for this value type."); return false; } template bool canHandle(storm::utility::Engine const& engine, std::vector const& properties, storm::storage::SymbolicModelDescription const& modelDescription) { // Check handability of properties based on model type for (auto const& p : properties) { for (auto const& f : {p.getRawFormula(), p.getFilter().getStatesFormula()}) { auto task = storm::modelchecker::CheckTask(*f, true); if (!canHandle(engine, modelDescription.getModelType(), task)) { STORM_LOG_INFO("Engine " << engine << " can not handle formula '" << *f << "' on models of type " << modelDescription.getModelType() << "."); return false; } } } // Check whether the model builder can handle the model description return storm::builder::canHandle(getBuilderType(engine), modelDescription, properties); } // explicit template instantiations. template bool canHandle(storm::utility::Engine const&, std::vector const&, storm::storage::SymbolicModelDescription const&); template bool canHandle(storm::utility::Engine const&, std::vector const&, storm::storage::SymbolicModelDescription const&); template bool canHandle(storm::utility::Engine const&, std::vector const&, storm::storage::SymbolicModelDescription const&); } }