You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

235 lines
13 KiB

#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<Engine> getEngines() {
std::vector<Engine> res;
for (int i = 0; i != static_cast<int>(Engine::Unknown); ++i) {
res.push_back(static_cast<Engine>(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 <typename ValueType>
bool canHandle(storm::utility::Engine const& engine, storm::storage::SymbolicModelDescription::ModelType const& modelType, storm::modelchecker::CheckTask<storm::logic::Formula, ValueType> 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<storm::models::sparse::Dtmc<ValueType>>::canHandleStatic(checkTask);
case ModelType::MDP:
return storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ValueType>>::canHandleStatic(checkTask);
case ModelType::CTMC:
return storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<ValueType>>::canHandleStatic(checkTask);
case ModelType::MA:
return storm::modelchecker::SparseMarkovAutomatonCslModelChecker<storm::models::sparse::MarkovAutomaton<ValueType>>::canHandleStatic(checkTask);
case ModelType::POMDP:
return false;
}
break;
case Engine::Hybrid:
switch (modelType) {
case ModelType::DTMC:
return storm::modelchecker::HybridDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<ddType, ValueType>>::canHandleStatic(checkTask);
case ModelType::MDP:
return storm::modelchecker::HybridMdpPrctlModelChecker<storm::models::symbolic::Mdp<ddType, ValueType>>::canHandleStatic(checkTask);
case ModelType::CTMC:
return storm::modelchecker::HybridCtmcCslModelChecker<storm::models::symbolic::Ctmc<ddType, ValueType>>::canHandleStatic(checkTask);
case ModelType::MA:
return storm::modelchecker::HybridMarkovAutomatonCslModelChecker<storm::models::symbolic::MarkovAutomaton<ddType, ValueType>>::canHandleStatic(checkTask);
case ModelType::POMDP:
return false;
}
break;
case Engine::Dd:
switch (modelType) {
case ModelType::DTMC:
return storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<ddType, ValueType>>::canHandleStatic(checkTask);
case ModelType::MDP:
return storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<ddType, ValueType>>::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::RationalFunction>(storm::utility::Engine const& engine, storm::storage::SymbolicModelDescription::ModelType const& modelType, storm::modelchecker::CheckTask<storm::logic::Formula, storm::RationalFunction> 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<storm::models::sparse::Dtmc<storm::RationalFunction>>::canHandleStatic(checkTask);
case ModelType::CTMC:
return storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<storm::RationalFunction>>::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<storm::models::symbolic::Dtmc<ddType, storm::RationalFunction>>::canHandleStatic(checkTask);
case ModelType::CTMC:
return storm::modelchecker::HybridCtmcCslModelChecker<storm::models::symbolic::Ctmc<ddType, storm::RationalFunction>>::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<storm::models::symbolic::Dtmc<ddType, storm::RationalFunction>>::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 <typename ValueType>
bool canHandle(storm::utility::Engine const& engine, std::vector<storm::jani::Property> 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<storm::logic::Formula, ValueType>(*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<ValueType>(getBuilderType(engine), modelDescription, properties);
}
// explicit template instantiations.
template bool canHandle<double>(storm::utility::Engine const&, std::vector<storm::jani::Property> const&, storm::storage::SymbolicModelDescription const&);
template bool canHandle<storm::RationalNumber>(storm::utility::Engine const&, std::vector<storm::jani::Property> const&, storm::storage::SymbolicModelDescription const&);
template bool canHandle<storm::RationalFunction>(storm::utility::Engine const&, std::vector<storm::jani::Property> const&, storm::storage::SymbolicModelDescription const&);
}
}