50 changed files with 2172 additions and 1773 deletions
-
3src/CMakeLists.txt
-
40src/storm-pars/CMakeLists.txt
-
45src/storm-pars/api/parametric.h
-
126src/storm-pars/api/region.h
-
4src/storm-pars/api/storm-pars.h
-
4src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp
-
6src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.h
-
4src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp
-
4src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.h
-
4src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp
-
6src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.h
-
25src/storm-pars/modelchecker/region/RegionCheckEngine.cpp
-
19src/storm-pars/modelchecker/region/RegionCheckEngine.h
-
237src/storm-pars/modelchecker/region/RegionModelChecker.cpp
-
79src/storm-pars/modelchecker/region/RegionModelChecker.h
-
24src/storm-pars/modelchecker/region/RegionResult.cpp
-
8src/storm-pars/modelchecker/region/RegionResult.h
-
22src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp
-
13src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.h
-
65src/storm-pars/modelchecker/region/SparseDtmcRegionChecker.cpp
-
27src/storm-pars/modelchecker/region/SparseDtmcRegionChecker.h
-
23src/storm-pars/modelchecker/region/SparseMdpParameterLiftingModelChecker.cpp
-
12src/storm-pars/modelchecker/region/SparseMdpParameterLiftingModelChecker.h
-
70src/storm-pars/modelchecker/region/SparseMdpRegionChecker.cpp
-
28src/storm-pars/modelchecker/region/SparseMdpRegionChecker.h
-
52src/storm-pars/modelchecker/region/SparseParameterLiftingModelChecker.cpp
-
30src/storm-pars/modelchecker/region/SparseParameterLiftingModelChecker.h
-
112src/storm-pars/modelchecker/results/RegionCheckResult.cpp
-
40src/storm-pars/modelchecker/results/RegionCheckResult.h
-
100src/storm-pars/modelchecker/results/RegionRefinementCheckResult.cpp
-
30src/storm-pars/modelchecker/results/RegionRefinementCheckResult.h
-
97src/storm-pars/parser/ParameterRegionParser.cpp
-
47src/storm-pars/parser/ParameterRegionParser.h
-
62src/storm-pars/settings/modules/ParametricSettings.cpp
-
28src/storm-pars/settings/modules/ParametricSettings.h
-
82src/storm-pars/settings/modules/RegionSettings.cpp
-
71src/storm-pars/settings/modules/RegionSettings.h
-
61src/storm-pars/storage/ParameterRegion.cpp
-
24src/storm-pars/storage/ParameterRegion.h
-
2src/storm-pars/transformer/ParameterLifter.cpp
-
4src/storm-pars/transformer/ParameterLifter.h
-
2src/storm-pars/transformer/SparseParametricDtmcSimplifier.cpp
-
2src/storm-pars/transformer/SparseParametricDtmcSimplifier.h
-
2src/storm-pars/transformer/SparseParametricMdpSimplifier.cpp
-
2src/storm-pars/transformer/SparseParametricMdpSimplifier.h
-
2src/storm-pars/transformer/SparseParametricModelSimplifier.cpp
-
2src/storm-pars/utility/ModelInstantiator.cpp
-
2src/storm-pars/utility/ModelInstantiator.h
-
35src/storm-pars/utility/parameterlifting.h
-
2src/storm-pars/utility/parametric.cpp
@ -0,0 +1,40 @@ |
|||
file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-pars/*.h ${PROJECT_SOURCE_DIR}/src/storm-pars/*.cpp) |
|||
|
|||
register_source_groups_from_filestructure("${ALL_FILES}" storm-pars) |
|||
|
|||
|
|||
|
|||
file(GLOB_RECURSE STORM_PARS_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-pars/*/*.cpp) |
|||
file(GLOB_RECURSE STORM_PARS_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-pars/*/*.h) |
|||
|
|||
|
|||
# Create storm-pars. |
|||
add_library(storm-pars SHARED ${STORM_PARS_SOURCES} ${STORM_PARS_HEADERS}) |
|||
|
|||
# Remove define symbol for shared libstorm. |
|||
set_target_properties(storm-pars PROPERTIES DEFINE_SYMBOL "") |
|||
#add_dependencies(storm resources) |
|||
list(APPEND STORM_TARGETS storm-pars) |
|||
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) |
|||
|
|||
target_link_libraries(storm-pars PUBLIC storm ${STORM_PARS_LINK_LIBRARIES}) |
|||
|
|||
# Install storm headers to include directory. |
|||
foreach(HEADER ${STORM_PARS_HEADERS}) |
|||
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/src/?" "" RELATIVE_HEADER_PATH ${HEADER}) |
|||
string(REGEX MATCH "(.*)[/\\]" RELATIVE_DIRECTORY ${RELATIVE_HEADER_PATH}) |
|||
string(REGEX REPLACE "${RELATIVE_DIRECTORY}/?" "" HEADER_FILENAME ${RELATIVE_HEADER_PATH}) |
|||
add_custom_command( |
|||
OUTPUT ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME} |
|||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY} |
|||
COMMAND ${CMAKE_COMMAND} -E copy ${HEADER} ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME} |
|||
DEPENDS ${HEADER} |
|||
) |
|||
list(APPEND STORM_PARS_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") |
|||
endforeach() |
|||
add_custom_target(copy_storm_pars_headers DEPENDS ${STORM_PARS_OUTPUT_HEADERS} ${STORM_PARS_HEADERS}) |
|||
add_dependencies(storm-pars copy_storm_pars_headers) |
|||
|
|||
# installation |
|||
install(TARGETS storm-pars RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) |
|||
|
|||
@ -0,0 +1,45 @@ |
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
|
|||
#include "storm-pars/transformer/SparseParametricDtmcSimplifier.h" |
|||
#include "storm-pars/transformer/SparseParametricMdpSimplifier.h" |
|||
|
|||
#include "storm/models/sparse/Model.h" |
|||
#include "storm/logic/Formula.h" |
|||
#include "storm/utility/macros.h" |
|||
|
|||
namespace storm { |
|||
namespace api { |
|||
|
|||
template <typename ValueType> |
|||
bool simplifyParametricModel(std::shared_ptr<storm::models::sparse::Model<ValueType> const& inputModel, std::shared_ptr<storm::logic::Formula const> const& inputFormula, std::shared_ptr<storm::models::sparse::Model<ValueType>& outputModel, std::shared_ptr<storm::logic::Formula const>& outputFormula) { |
|||
|
|||
if (inputModel->isOfType(storm::models::ModelType::Dtmc)) { |
|||
auto const& dtmc = *inputModel->template as<storm::models::sparse::Dtmc<ValueType>>(); |
|||
auto simplifier = storm::transformer::SparseParametricDtmcSimplifier<storm::models::sparse::Dtmc<ValueType>>(dtmc); |
|||
if (simplifier.simplify(*inputFormula)) { |
|||
outputModel = simplifier.getSimplifiedModel(); |
|||
outputFormula = simplifier.getSimplifiedFormula(); |
|||
return true; |
|||
} |
|||
} else if (inputModel->isOfType(storm::models::ModelType::Mdp)) { |
|||
auto const& mdp = *inputModel->template as<storm::models::sparse::Mdp<ValueType>>(); |
|||
auto simplifier = storm::transformer::SparseParametricMdpSimplifier<storm::models::sparse::Mdp<ValueType>>(mdp); |
|||
if (simplifier.simplify(*inputFormula)) { |
|||
outputModel = simplifier.getSimplifiedModel(); |
|||
outputFormula = simplifier.getSimplifiedFormula(); |
|||
return true; |
|||
} |
|||
} else { |
|||
STORM_LOG_ERROR("Unable to simplify model with the given type."); |
|||
} |
|||
|
|||
// Reaching this point means that simplification was not successful. |
|||
outputModel = nullptr; |
|||
outputFormula = nullptr; |
|||
return false; |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,126 @@ |
|||
#pragma once |
|||
|
|||
#include <string> |
|||
#include <set> |
|||
#include <vector> |
|||
#include <memory> |
|||
#include <boost/optional.hpp> |
|||
|
|||
#include "storm-pars/storage/ParameterRegion.h" |
|||
|
|||
#include "storm-pars/modelchecker/results/RegionCheckResult.h" |
|||
#include "storm-pars/modelchecker/results/RegionRefinementCheckResult.h" |
|||
#include "storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.h" |
|||
#include "storm-pars/modelchecker/region/SparseMdpParameterLiftingModelChecker.h" |
|||
#include "storm-pars/parser/ParameterRegionParser.h" |
|||
|
|||
#include "storm/api/transformation.h" |
|||
#include "storm/models/sparse/Model.h" |
|||
#include "storm/exceptions/UnexpectedException.h" |
|||
#include "storm/exceptions/InvalidOperationException.h" |
|||
|
|||
namespace storm { |
|||
|
|||
namespace api { |
|||
|
|||
|
|||
enum class RegionModelCheckerType { |
|||
ParameterLifting, |
|||
ExactParameterLifting, |
|||
ValidatingParameterLifting |
|||
}; |
|||
|
|||
template <typename ValueType> |
|||
std::vector<storm::storage::ParameterRegion<ValueType>> parseRegions(std::string const& inputString, std::set<typename storm::storage::ParameterRegion<ValueType>::VariableType> const& consideredVariables) { |
|||
// If the given input string looks like a file (containing a dot and there exists a file with that name), |
|||
// we try to parse it as a file, otherwise we assume it's a region string. |
|||
if (inputString.find(".") != std::string::npos && std::ifstream(inputString).good()) { |
|||
return storm::parser::ParameterRegionParser<ValueType>().parseMultipleRegionsFromFile(inputString, consideredVariables); |
|||
} else { |
|||
return storm::parser::ParameterRegionParser<ValueType>().parseMultipleRegions(inputString, consideredVariables); |
|||
} |
|||
} |
|||
|
|||
template <typename ValueType> |
|||
std::vector<storm::storage::ParameterRegion<ValueType>> parseRegions(std::string const& inputString, storm::models::sparse::Model<ValueType> const& model) { |
|||
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model); |
|||
auto rewParameters = storm::models::sparse::getRewardParameters(*model); |
|||
modelParameters.insert(rewParameters.begin(), rewParameters.end()); |
|||
return parseRegions(inputString, modelParameters); |
|||
} |
|||
|
|||
template <typename ParametricType, typename ConstantType> |
|||
std::unique_ptr<storm::modelchecker::RegionModelChecker<ParametricType>> initializeParameterLiftingRegionModelChecker(std::shared_ptr<storm::models::sparse::Model<ParametricType>> const& model, storm::modelchecker::CheckTask<storm::logic::Formula, ParametricType> const& task) { |
|||
// Treat continuous time models |
|||
if (model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::MarkovAutomaton)) { |
|||
STORM_LOG_WARN("Parameter lifting not supported for continuous time models. Transforming continuous model to discrete model..."); |
|||
std::vector<std::shared_ptr<storm::logic::Formula const>> taskFormulaAsVector { task.getFormula().asSharedPointer() }; |
|||
auto discreteTimeModel = storm::api::transformContinuousToDiscreteTimeSparseModel(model, taskFormulaAsVector); |
|||
STORM_LOG_THROW(discreteTimeModel->isOfType(storm::models::ModelType::Dtmc) || discreteTimeModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::UnexpectedException, "Transformation to discrete time model has failed."); |
|||
return initializeParameterLiftingRegionModelChecker(discreteTimeModel, task); |
|||
} |
|||
|
|||
// Obtain the region model checker |
|||
std::unique_ptr<storm::modelchecker::RegionModelChecker<ParametricType>> result; |
|||
if (model->isOfType(storm::models::ModelType::Dtmc)) { |
|||
auto const& dtmc = *model->template as<storm::models::sparse::Dtmc<ParametricType>>(); |
|||
result = std::make_unique<storm::modelchecker::SparseDtmcParameterLiftingModelChecker<storm::models::sparse::Dtmc<ValueType>, ConstantType>>(dtmc); |
|||
} else if (model->isOfType(storm::models::ModelType::Mdp)) { |
|||
auto const& mdp = *model->template as<storm::models::sparse::Mdp<ParametricType>>(); |
|||
result = std::make_unique<storm::modelchecker::SparseMdpParameterLiftingModelChecker<storm::models::sparse::Mdp<ValueType>, ConstantType>>(mdp); |
|||
} else { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Unable to perform parameterLifting on the provided model type."); |
|||
} |
|||
|
|||
result->specifyFormula(task); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
template <typename ParametricType, typename ImpreciseType, typename PreciseType> |
|||
std::unique_ptr<storm::modelchecker::RegionModelChecker<ValueType>> initializeValidatingRegionModelChecker(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, storm::modelchecker::CheckTask<storm::logic::Formula, ParametricType> const& task) { |
|||
// todo |
|||
return nullptr; |
|||
} |
|||
|
|||
template <typename ValueType> |
|||
std::unique_ptr<storm::modelchecker::RegionModelChecker<ValueType>> initializeRegionModelChecker(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, storm::modelchecker::CheckTask<storm::logic::Formula, ValueType> const& task, RegionModelCheckerType checkerType) { |
|||
switch (checkerType) { |
|||
case RegionModelCheckerType::ParameterLifting: |
|||
return initializeParameterLiftingRegionModelChecker<ValueType, double>(model, task); |
|||
case RegionModelCheckerType::ExactParameterLifting: |
|||
return initializeParameterLiftingRegionModelChecker<ValueType, storm::RationalNumber>(model, task); |
|||
case RegionModelCheckerType::ValidatingParameterLifting: |
|||
return initializeValidatingRegionModelChecker<ValueType, double, storm::RationalNumber>(model, task); |
|||
default: |
|||
STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected region model checker type."); |
|||
} |
|||
return nullptr; |
|||
} |
|||
|
|||
template <typename ValueType> |
|||
std::unique_ptr<storm::modelchecker::RegionCheckResult<ValueType>> checkRegionsWithSparseEngine(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, storm::modelchecker::CheckTask<storm::logic::Formula, ValueType> const& task, std::vector<storm::storage::ParameterRegion<ValueType>> const& regions, RegionModelCheckerType checkerType) { |
|||
auto regionChecker = initializeRegionModelChecker(model, task, checkerType); |
|||
return regionChecker->analyzeRegions(regions, true); |
|||
} |
|||
|
|||
|
|||
template <typename ValueType> |
|||
td::unique_ptr<storm::modelchecker::RegionRefinementCheckResult<ValueType>> checkAndRefineRegionWithSparseEngine(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, storm::modelchecker::CheckTask<storm::logic::Formula, ValueType> const& task, storm::storage::ParameterRegion<ValueType> const& region, ValueType const& refinementThreshold) { |
|||
auto regionChecker = initializeRegionModelChecker(model, task, checkerType); |
|||
return regionChecker->performRegionRefinement(region, refinementThreshold); |
|||
} |
|||
|
|||
|
|||
template <typename ValueType> |
|||
void exportRegionCheckResultToFile(std::unique_ptr<storm::modelchecker::RegionCheckResult<ValueType>> const& checkResult, std::string const& filename) { |
|||
|
|||
std::ofstream filestream; |
|||
storm::utility::openFile(path, filestream); |
|||
for (auto const& res : checkResult->getRegionResults()) { |
|||
filestream << res.second << ": " << res.first << std::endl; |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
#pragma once |
|||
|
|||
#include "storm-pars/api/region.h" |
|||
#include "storm-pars/api/parametric.h" |
|||
@ -0,0 +1,25 @@ |
|||
#include "storm-pars/modelchecker/region/RegionCheckEngine.h"
|
|||
|
|||
#include "storm/utility/macros.h"
|
|||
#include "storm/exceptions/NotImplementedException.h"
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
std::ostream& operator<<(std::ostream& os, RegionCheckEngine const& e) { |
|||
switch (e) { |
|||
case RegionCheckEngine::ParameterLifting: |
|||
os << "Parameter Lifting"; |
|||
break; |
|||
case RegionCheckEngine::ExactParameterLifting: |
|||
os << "Exact Parameter Lifting"; |
|||
break; |
|||
case RegionCheckEngine::ValidatingParameterLifting: |
|||
os << "Validating Parameter Lifting"; |
|||
break; |
|||
default: |
|||
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Could not get a string from the region check engine. The case has not been implemented"); |
|||
} |
|||
return os; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
#pragma once |
|||
|
|||
#include <ostream> |
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
/*! |
|||
* The considered engine for region checking |
|||
*/ |
|||
enum class RegionCheckEngine { |
|||
ParameterLifting, /*!< Parameter lifting approach */ |
|||
ExactParameterLifting, /*!< Parameter lifting approach with exact arithmethics*/ |
|||
ValidatingParameterLifting, /*!< Parameter lifting approach with a) inexact (and fast) computation first and b) exact validation of obtained results second */ |
|||
}; |
|||
|
|||
std::ostream& operator<<(std::ostream& os, RegionCheckEngine const& regionCheckResult); |
|||
} |
|||
} |
|||
|
|||
@ -1,65 +0,0 @@ |
|||
#include "storm/modelchecker/parametric/SparseDtmcRegionChecker.h"
|
|||
|
|||
#include "storm/adapters/RationalFunctionAdapter.h"
|
|||
|
|||
#include "storm/modelchecker/parametric/SparseDtmcParameterLiftingModelChecker.h"
|
|||
#include "storm/modelchecker/parametric/SparseDtmcInstantiationModelChecker.h"
|
|||
#include "storm/transformer/SparseParametricDtmcSimplifier.h"
|
|||
#include "storm/models/sparse/StandardRewardModel.h"
|
|||
#include "storm/models/sparse/Dtmc.h"
|
|||
#include "storm/utility/NumberTraits.h"
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace parametric { |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
SparseDtmcRegionChecker<SparseModelType, ConstantType, ExactConstantType>::SparseDtmcRegionChecker(SparseModelType const& parametricModel) : RegionChecker<SparseModelType, ConstantType, ExactConstantType>(parametricModel) { |
|||
// Intentionally left empty
|
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
void SparseDtmcRegionChecker<SparseModelType, ConstantType, ExactConstantType>::simplifyParametricModel(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask) { |
|||
storm::transformer::SparseParametricDtmcSimplifier<SparseModelType> simplifier(this->parametricModel); |
|||
if(simplifier.simplify(checkTask.getFormula())) { |
|||
this->simplifiedModel = simplifier.getSimplifiedModel(); |
|||
this->currentFormula = simplifier.getSimplifiedFormula(); |
|||
} else { |
|||
this->simplifiedModel = nullptr; |
|||
this->currentFormula = checkTask.getFormula().asSharedPointer(); |
|||
} |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
void SparseDtmcRegionChecker<SparseModelType, ConstantType, ExactConstantType>::initializeUnderlyingCheckers() { |
|||
if (this->settings.applyExactValidation) { |
|||
STORM_LOG_WARN_COND(!storm::NumberTraits<ConstantType>::IsExact, "Exact validation is not necessarry if the original computation is already exact"); |
|||
this->exactParameterLiftingChecker = std::make_unique<SparseDtmcParameterLiftingModelChecker<SparseModelType, ExactConstantType>>(this->getConsideredParametricModel()); |
|||
} |
|||
this->parameterLiftingChecker = std::make_unique<SparseDtmcParameterLiftingModelChecker<SparseModelType, ConstantType>>(this->getConsideredParametricModel()); |
|||
this->instantiationChecker = std::make_unique<SparseDtmcInstantiationModelChecker<SparseModelType, ConstantType>>(this->getConsideredParametricModel()); |
|||
this->instantiationChecker->setInstantiationsAreGraphPreserving(true); |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
void SparseDtmcRegionChecker<SparseModelType, ConstantType, ExactConstantType>::applyHintsToExactChecker() { |
|||
auto dtmcPLChecker = dynamic_cast<storm::modelchecker::parametric::SparseDtmcParameterLiftingModelChecker<SparseModelType, ConstantType>*>(this->parameterLiftingChecker.get()); |
|||
STORM_LOG_ASSERT(dtmcPLChecker, "Underlying Parameter lifting checker has unexpected type"); |
|||
auto exactDtmcPLChecker = dynamic_cast<storm::modelchecker::parametric::SparseDtmcParameterLiftingModelChecker<SparseModelType, ExactConstantType>*>(this->exactParameterLiftingChecker.get()); |
|||
STORM_LOG_ASSERT(exactDtmcPLChecker, "Underlying exact parameter lifting checker has unexpected type"); |
|||
if (dtmcPLChecker->getCurrentMaxScheduler()) { |
|||
exactDtmcPLChecker->getCurrentMaxScheduler() = dtmcPLChecker->getCurrentMaxScheduler()->template toValueType<ExactConstantType>(); |
|||
} |
|||
if (dtmcPLChecker->getCurrentMinScheduler()) { |
|||
exactDtmcPLChecker->getCurrentMinScheduler() = dtmcPLChecker->getCurrentMinScheduler()->template toValueType<ExactConstantType>(); |
|||
} |
|||
} |
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class SparseDtmcRegionChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, double, storm::RationalNumber>; |
|||
template class SparseDtmcRegionChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::RationalNumber>; |
|||
#endif
|
|||
} // namespace parametric
|
|||
} //namespace modelchecker
|
|||
} //namespace storm
|
|||
|
|||
@ -1,27 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
|
|||
#include "storm/modelchecker/parametric/RegionChecker.h" |
|||
|
|||
namespace storm { |
|||
namespace modelchecker{ |
|||
namespace parametric{ |
|||
|
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType = ConstantType> |
|||
class SparseDtmcRegionChecker : public RegionChecker<SparseModelType, ConstantType, ExactConstantType> { |
|||
|
|||
public: |
|||
SparseDtmcRegionChecker(SparseModelType const& parametricModel); |
|||
|
|||
protected: |
|||
virtual void simplifyParametricModel(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask) override; |
|||
virtual void initializeUnderlyingCheckers() override; |
|||
virtual void applyHintsToExactChecker() override; |
|||
|
|||
}; |
|||
|
|||
} //namespace parametric |
|||
} //namespace modelchecker |
|||
} //namespace storm |
|||
@ -1,70 +0,0 @@ |
|||
#include "storm/modelchecker/parametric/SparseMdpRegionChecker.h"
|
|||
|
|||
#include "storm/adapters/RationalFunctionAdapter.h"
|
|||
|
|||
#include "storm/modelchecker/parametric/SparseMdpParameterLiftingModelChecker.h"
|
|||
#include "storm/modelchecker/parametric/SparseMdpInstantiationModelChecker.h"
|
|||
#include "storm/transformer/SparseParametricMdpSimplifier.h"
|
|||
#include "storm/models/sparse/StandardRewardModel.h"
|
|||
#include "storm/models/sparse/Mdp.h"
|
|||
#include "storm/utility/NumberTraits.h"
|
|||
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
namespace parametric { |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
SparseMdpRegionChecker<SparseModelType, ConstantType, ExactConstantType>::SparseMdpRegionChecker(SparseModelType const& parametricModel) : RegionChecker<SparseModelType, ConstantType, ExactConstantType>(parametricModel) { |
|||
// Intentionally left empty
|
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
void SparseMdpRegionChecker<SparseModelType, ConstantType, ExactConstantType>::simplifyParametricModel(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask) { |
|||
storm::transformer::SparseParametricMdpSimplifier<SparseModelType> simplifier(this->parametricModel); |
|||
if(simplifier.simplify(checkTask.getFormula())) { |
|||
this->simplifiedModel = simplifier.getSimplifiedModel(); |
|||
this->currentFormula = simplifier.getSimplifiedFormula(); |
|||
} else { |
|||
this->simplifiedModel = nullptr; |
|||
this->currentFormula = checkTask.getFormula().asSharedPointer(); |
|||
} |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
void SparseMdpRegionChecker<SparseModelType, ConstantType, ExactConstantType>::initializeUnderlyingCheckers() { |
|||
if (this->settings.applyExactValidation) { |
|||
STORM_LOG_WARN_COND(!storm::NumberTraits<ConstantType>::IsExact, "Exact validation is not necessarry if the original computation is already exact"); |
|||
this->exactParameterLiftingChecker = std::make_unique<SparseMdpParameterLiftingModelChecker<SparseModelType, ExactConstantType>>(this->getConsideredParametricModel()); |
|||
} |
|||
this->parameterLiftingChecker = std::make_unique<SparseMdpParameterLiftingModelChecker<SparseModelType, ConstantType>>(this->getConsideredParametricModel()); |
|||
this->instantiationChecker = std::make_unique<SparseMdpInstantiationModelChecker<SparseModelType, ConstantType>>(this->getConsideredParametricModel()); |
|||
this->instantiationChecker->setInstantiationsAreGraphPreserving(true); |
|||
} |
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType> |
|||
void SparseMdpRegionChecker<SparseModelType, ConstantType, ExactConstantType>::applyHintsToExactChecker() { |
|||
auto MdpPLChecker = dynamic_cast<storm::modelchecker::parametric::SparseMdpParameterLiftingModelChecker<SparseModelType, ConstantType>*>(this->parameterLiftingChecker.get()); |
|||
STORM_LOG_ASSERT(MdpPLChecker, "Underlying Parameter lifting checker has unexpected type"); |
|||
auto exactMdpPLChecker = dynamic_cast<storm::modelchecker::parametric::SparseMdpParameterLiftingModelChecker<SparseModelType, ExactConstantType>*>(this->exactParameterLiftingChecker.get()); |
|||
STORM_LOG_ASSERT(exactMdpPLChecker, "Underlying exact parameter lifting checker has unexpected type"); |
|||
if (MdpPLChecker->getCurrentMaxScheduler()) { |
|||
exactMdpPLChecker->getCurrentMaxScheduler() = MdpPLChecker->getCurrentMaxScheduler()->template toValueType<ExactConstantType>(); |
|||
} |
|||
if (MdpPLChecker->getCurrentMinScheduler()) { |
|||
exactMdpPLChecker->getCurrentMinScheduler() = MdpPLChecker->getCurrentMinScheduler()->template toValueType<ExactConstantType>(); |
|||
} |
|||
if (MdpPLChecker->getCurrentPlayer1Scheduler()) { |
|||
exactMdpPLChecker->getCurrentPlayer1Scheduler() = MdpPLChecker->getCurrentPlayer1Scheduler()->template toValueType<ExactConstantType>(); |
|||
} |
|||
} |
|||
|
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class SparseMdpRegionChecker<storm::models::sparse::Mdp<storm::RationalFunction>, double, storm::RationalNumber>; |
|||
template class SparseMdpRegionChecker<storm::models::sparse::Mdp<storm::RationalFunction>, storm::RationalNumber>; |
|||
#endif
|
|||
} // namespace parametric
|
|||
} //namespace modelchecker
|
|||
} //namespace storm
|
|||
|
|||
@ -1,28 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
|
|||
#include "storm/modelchecker/parametric/RegionChecker.h" |
|||
|
|||
namespace storm { |
|||
namespace modelchecker{ |
|||
namespace parametric{ |
|||
|
|||
|
|||
template <typename SparseModelType, typename ConstantType, typename ExactConstantType = ConstantType> |
|||
class SparseMdpRegionChecker : public RegionChecker<SparseModelType, ConstantType, ExactConstantType> { |
|||
|
|||
public: |
|||
SparseMdpRegionChecker(SparseModelType const& parametricModel); |
|||
|
|||
protected: |
|||
|
|||
virtual void initializeUnderlyingCheckers() override; |
|||
virtual void simplifyParametricModel(CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask) override; |
|||
virtual void applyHintsToExactChecker() override; |
|||
|
|||
}; |
|||
|
|||
} //namespace parametric |
|||
} //namespace modelchecker |
|||
} //namespace storm |
|||
@ -0,0 +1,112 @@ |
|||
#include "storm-pars/modelchecker/results/RegionCheckResult.h"
|
|||
|
|||
#include <map>
|
|||
|
|||
#include "storm/adapters/RationalFunctionAdapter.h"
|
|||
#include "storm/utility/constants.h"
|
|||
#include "storm/utility/macros.h"
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
|
|||
template<typename ValueType> |
|||
RegionCheckResult<ValueType>::RegionCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> const& regionResults) : regionResults(regionResults) { |
|||
auto overallArea = storm::utility::zero<typename storm::storage::ParameterRegion<ValueType>::CoefficientType>(); |
|||
for (auto const& res : this->regionResults) { |
|||
overallArea += res.first.area(); |
|||
} |
|||
initFractions(overallArea); |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
RegionCheckResult<ValueType>::RegionCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>>&& regionResults) : regionResults(std::move(regionResults)) { |
|||
auto overallArea = storm::utility::zero<typename storm::storage::ParameterRegion<ValueType>::CoefficientType>(); |
|||
for (auto const& res : this->regionResults) { |
|||
overallArea += res.first.area(); |
|||
} |
|||
initFractions(overallArea); |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
bool RegionCheckResult<ValueType>::isRegionCheckResult() const { |
|||
return true; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
bool RegionCheckResult<ValueType>::isRegionRefinementCheckResult() const { |
|||
return false; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> const& RegionCheckResult<ValueType>::getRegionResults() const { |
|||
return regionResults; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
typename storm::storage::ParameterRegion<ValueType>::CoefficientType const& RegionCheckResult<ValueType>::getSatFraction() const { |
|||
return satFraction; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
typename storm::storage::ParameterRegion<ValueType>::CoefficientType const& RegionCheckResult<ValueType>::getUnsatFraction() const { |
|||
return unsatFraction; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
std::ostream& RegionCheckResult<ValueType>::writeToStream(std::ostream& out) const { |
|||
writeCondensedToStream(out); |
|||
out << std::endl << "Region results: " << std::endl; |
|||
for (auto const& res : this->regionResults) { |
|||
out << res.first.toString() << ": \t" << res.second << std::endl; |
|||
} |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
std::ostream& RegionCheckResult<ValueType>::writeCondensedToStream(std::ostream& out) const { |
|||
auto oneHundred = storm::utility::convertNumber<typename storm::storage::ParameterRegion<ValueType>::CoefficientType>(100.0); |
|||
auto one = storm::utility::convertNumber<typename storm::storage::ParameterRegion<ValueType>::CoefficientType>(1.0); |
|||
out << "Fraction of satisfied area: " << (satFraction * oneHundred) << std::endl; |
|||
out << "Fraction of unsatisfied area: " << (unsatFraction * oneHundred) << std::endl; |
|||
out << "Unknown fraction: " << ((one - satFraction - unsatFraction) * oneHundred) << std::endl; |
|||
out << "Total Number of regions: " << regionResults.size() << std::endl; |
|||
std::map<storm::modelchecker::RegionResult, uint_fast64_t> counters; |
|||
for (auto const& res : this->regionResults) { |
|||
++counters[res.second]; |
|||
} |
|||
for (auto const& counter : counters) { |
|||
out << std::setw(28) << counter.first << ": " << counter.second << std::endl; |
|||
} |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
std::ostream& RegionCheckResult<ValueType>::writeIllustrationToStream(std::ostream& out) const { |
|||
STORM_LOG_WARN("Writing illustration of region check result to a stream is not implemented."); |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
void RegionCheckResult<ValueType>::initFractions(typename storm::storage::ParameterRegion<ValueType>::CoefficientType const& overallArea) { |
|||
auto satArea = storm::utility::zero<typename storm::storage::ParameterRegion<ValueType>::CoefficientType>(); |
|||
auto unsatArea = storm::utility::zero<typename storm::storage::ParameterRegion<ValueType>::CoefficientType>(); |
|||
for (auto const& res : this->regionResults) { |
|||
if (res.second == storm::modelchecker::RegionResult::AllSat) { |
|||
satArea += res.first.area(); |
|||
} else if (res.second == storm::modelchecker::RegionResult::AllViolated) { |
|||
unsatArea += res.first.area(); |
|||
} |
|||
} |
|||
satFraction = satArea / overallArea; |
|||
unsatFraction = unsatArea / overallArea; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
void RegionCheckResult<ValueType>::filter(QualitativeCheckResult const& filter) { |
|||
// Filtering has no effect as we only store the result w.r.t. a single state anyway.
|
|||
// Hence, this is intentionally left empty.
|
|||
} |
|||
|
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class RegionCheckResult<storm::RationalFunction>; |
|||
#endif
|
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
#pragma once |
|||
|
|||
#include <vector> |
|||
|
|||
#include "storm/modelchecker/results/CheckResult.h" |
|||
#include "storm-pars/modelchecker/region/RegionResult.h" |
|||
#include "storm-pars/storage/ParameterRegion.h" |
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
template<typename ValueType> |
|||
class RegionCheckResult : public CheckResult { |
|||
public: |
|||
|
|||
RegionCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> const& regionResults); |
|||
RegionCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>>&& regionResults); |
|||
virtual ~RegionCheckResult() = default; |
|||
|
|||
virtual bool isRegionCheckResult() const; |
|||
virtual bool isRegionRefinementCheckResult() const; |
|||
|
|||
std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> const& getRegionResults() const; |
|||
typename storm::storage::ParameterRegion<ValueType>::CoefficientType const& getSatFraction() const; |
|||
typename storm::storage::ParameterRegion<ValueType>::CoefficientType const& getUnsatFraction() const; |
|||
|
|||
virtual std::ostream& writeToStream(std::ostream& out) const override; |
|||
virtual std::ostream& writeCondensedToStream(std::ostream& out) const; |
|||
virtual std::ostream& writeIllustrationToStream(std::ostream& out) const; |
|||
|
|||
virtual void filter(QualitativeCheckResult const& filter) override; |
|||
|
|||
protected: |
|||
virtual void initFractions(typename storm::storage::ParameterRegion<ValueType>::CoefficientType const& overallArea); |
|||
|
|||
std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> regionResults; |
|||
typename storm::storage::ParameterRegion<ValueType>::CoefficientType satFraction, unsatFraction; |
|||
|
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,100 @@ |
|||
#include "storm-pars/modelchecker/results/RegionRefinementCheckResult.h"
|
|||
|
|||
#include <map>
|
|||
|
|||
#include "storm/adapters/RationalFunctionAdapter.h"
|
|||
#include "storm/utility/constants.h"
|
|||
#include "storm/utility/macros.h"
|
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
|
|||
template<typename ValueType> |
|||
RegionRefinementCheckResult<ValueType>::RegionRefinementCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> const& regionResults, storm::storage::ParameterRegion<ValueType> const& parameterSpace) : RegionCheckResult<ValueType>(regionResults), parameterSpace(parameterSpace) { |
|||
this->initFractions(this->parameterSpace.area()); |
|||
} |
|||
|
|||
|
|||
template<typename ValueType> |
|||
RegionRefinementCheckResult<ValueType>::RegionRefinementCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>>&& regionResults, storm::storage::ParameterRegion<ValueType>&& parameterSpace) : RegionCheckResult<ValueType>(std::move(regionResults)), parameterSpace(std::move(parameterSpace)) { |
|||
this->initFractions(this->parameterSpace.area()); |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
bool RegionRefinementCheckResult<ValueType>::isRegionRefinementCheckResult() const { |
|||
return true; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
storm::storage::ParameterRegion<ValueType> const& RegionRefinementCheckResult<ValueType>::getParameterSpace() const { |
|||
return parameterSpace; |
|||
} |
|||
|
|||
template<typename ValueType> |
|||
std::ostream& RegionRefinementCheckResult<ValueType>::writeIllustrationToStream(std::ostream& out) const { |
|||
if (this->getParameterSpace().getVariables().size() == 2) { |
|||
|
|||
typedef typename storm::storage::ParameterRegion<ValueType>::CoefficientType CoefficientType; |
|||
auto x = *this->getParameterSpace().getVariables().begin(); |
|||
auto y = *(this->getParameterSpace().getVariables().rbegin()); |
|||
|
|||
uint_fast64_t const sizeX = 128; |
|||
uint_fast64_t const sizeY = 64; |
|||
|
|||
out << "Region refinement Check result (visualization):" << std::endl; |
|||
out << " \t x-axis: " << x << " \t y-axis: " << y << " \t S=safe, [ ]=unsafe, -=ambiguous " << std::endl; |
|||
for (uint_fast64_t i = 0; i < sizeX+2; ++i) out << "#"; out << std::endl; |
|||
|
|||
CoefficientType deltaX = (getParameterSpace().getUpperBoundary(x) - getParameterSpace().getLowerBoundary(x)) / storm::utility::convertNumber<CoefficientType>(sizeX); |
|||
CoefficientType deltaY = (getParameterSpace().getUpperBoundary(y) - getParameterSpace().getLowerBoundary(y)) / storm::utility::convertNumber<CoefficientType>(sizeY); |
|||
CoefficientType printedRegionArea = deltaX * deltaY; |
|||
for (CoefficientType yUpper = getParameterSpace().getUpperBoundary(y); yUpper != getParameterSpace().getLowerBoundary(y); yUpper -= deltaY) { |
|||
CoefficientType yLower = yUpper - deltaY; |
|||
out << "#"; |
|||
for (CoefficientType xLower = getParameterSpace().getLowerBoundary(x); xLower != getParameterSpace().getUpperBoundary(x); xLower += deltaX) { |
|||
CoefficientType xUpper = xLower + deltaX; |
|||
bool currRegionSafe = false; |
|||
bool currRegionUnSafe = false; |
|||
bool currRegionComplete = false; |
|||
CoefficientType coveredArea = storm::utility::zero<CoefficientType>(); |
|||
for (auto const& r : this->getRegionResults()) { |
|||
CoefficientType interesctionSizeY = std::min(yUpper, r.first.getUpperBoundary(y)) - std::max(yLower, r.first.getLowerBoundary(y)); |
|||
interesctionSizeY = std::max(interesctionSizeY, storm::utility::zero<CoefficientType>()); |
|||
CoefficientType interesctionSizeX = std::min(xUpper, r.first.getUpperBoundary(x)) - std::max(xLower, r.first.getLowerBoundary(x)); |
|||
interesctionSizeX = std::max(interesctionSizeX, storm::utility::zero<CoefficientType>()); |
|||
CoefficientType instersectionArea = interesctionSizeY * interesctionSizeX; |
|||
if(!storm::utility::isZero(instersectionArea)) { |
|||
currRegionSafe = currRegionSafe || r.second == storm::modelchecker::RegionResult::AllSat; |
|||
currRegionUnSafe = currRegionUnSafe || r.second == storm::modelchecker::RegionResult::AllViolated; |
|||
coveredArea += instersectionArea; |
|||
if(currRegionSafe && currRegionUnSafe) { |
|||
break; |
|||
} |
|||
if(coveredArea == printedRegionArea) { |
|||
currRegionComplete = true; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
if (currRegionComplete && currRegionSafe && !currRegionUnSafe) { |
|||
out << "S"; |
|||
} else if (currRegionComplete && currRegionUnSafe && !currRegionSafe) { |
|||
out << " "; |
|||
} else { |
|||
out << "-"; |
|||
} |
|||
} |
|||
out << "#" << std::endl; |
|||
} |
|||
for (uint_fast64_t i = 0; i < sizeX+2; ++i) out << "#"; out << std::endl; |
|||
} else { |
|||
STORM_LOG_WARN("Writing illustration of region check result to a stream is only implemented for two parameters."); |
|||
} |
|||
return out; |
|||
} |
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class RegionRefinementCheckResult<storm::RationalFunction>; |
|||
#endif
|
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
#pragma once |
|||
|
|||
#include <vector> |
|||
|
|||
#include "storm-pars/modelchecker/results/RegionCheckResult.h" |
|||
#include "storm-pars/modelchecker/region/RegionResult.h" |
|||
#include "storm-pars/storage/ParameterRegion.h" |
|||
|
|||
namespace storm { |
|||
namespace modelchecker { |
|||
template<typename ValueType> |
|||
class RegionRefinementCheckResult : public RegionCheckResult<ValueType> { |
|||
public: |
|||
|
|||
RegionRefinementCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>> const& regionResults, storm::storage::ParameterRegion<ValueType> const& parameterSpace); |
|||
RegionRefinementCheckResult(std::vector<std::pair<storm::storage::ParameterRegion<ValueType>, storm::modelchecker::RegionResult>>&& regionResults, storm::storage::ParameterRegion<ValueType>&& parameterSpace); |
|||
virtual ~RegionRefinementCheckResult() = default; |
|||
|
|||
virtual bool isRegionRefinementCheckResult() const override; |
|||
|
|||
storm::storage::ParameterRegion<ValueType> const& getParameterSpace() const; |
|||
|
|||
virtual std::ostream& writeIllustrationToStream(std::ostream& out) const override; |
|||
|
|||
|
|||
protected: |
|||
storm::storage::ParameterRegion<ValueType> parameterSpace; |
|||
}; |
|||
} |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
#include "storm-pars/parser/ParameterRegionParser.h"
|
|||
|
|||
#include "storm/utility/macros.h"
|
|||
#include "storm/exceptions/InvalidArgumentException.h"
|
|||
#include "storm/utility/constants.h"
|
|||
#include "storm/utility/file.h"
|
|||
|
|||
namespace storm { |
|||
namespace parser { |
|||
|
|||
template<typename ParametricType> |
|||
void ParameterRegionParser<ParametricType>::parseParameterBoundaries(Valuation& lowerBoundaries, Valuation& upperBoundaries, std::string const& parameterBoundariesString, std::set<VariableType> const& consideredVariables) { |
|||
|
|||
std::string::size_type positionOfFirstRelation = parameterBoundariesString.find("<="); |
|||
STORM_LOG_THROW(positionOfFirstRelation!=std::string::npos, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundariesString << " I could not find a '<=' after the first number"); |
|||
std::string::size_type positionOfSecondRelation = parameterBoundariesString.find("<=", positionOfFirstRelation+2); |
|||
STORM_LOG_THROW(positionOfSecondRelation!=std::string::npos, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundariesString << " I could not find a '<=' after the parameter"); |
|||
|
|||
std::string parameter = parameterBoundariesString.substr(positionOfFirstRelation+2,positionOfSecondRelation-(positionOfFirstRelation+2)); |
|||
//removes all whitespaces from the parameter string:
|
|||
parameter.erase(std::remove_if (parameter.begin(), parameter.end(), ::isspace), parameter.end()); |
|||
STORM_LOG_THROW(parameter.length()>0, storm::exceptions::InvalidArgumentException, "When parsing the region" << parameterBoundariesString << " I could not find a parameter"); |
|||
|
|||
std::unique_ptr<VariableType> var; |
|||
for (auto const& v : consideredVariables) { |
|||
std::stringstream stream; |
|||
stream << v; |
|||
std::string vAsString = stream.str(); |
|||
if (parameter == stream.str()) { |
|||
var = std::make_unique<VariableType>(v); |
|||
} |
|||
} |
|||
STORM_LOG_ASSERT(var, "Could not find parameter " << parameter << " in the set of considered variables"); |
|||
|
|||
CoefficientType lb = storm::utility::convertNumber<CoefficientType>(parameterBoundariesString.substr(0,positionOfFirstRelation)); |
|||
CoefficientType ub = storm::utility::convertNumber<CoefficientType>(parameterBoundariesString.substr(positionOfSecondRelation+2)); |
|||
lowerBoundaries.emplace(std::make_pair(*var, lb)); |
|||
upperBoundaries.emplace(std::make_pair(*var, ub)); |
|||
} |
|||
|
|||
template<typename ParametricType> |
|||
storm::storage::ParameterRegion<ParametricType> ParameterRegionParser<ParametricType>::parseRegion(std::string const& regionString, std::set<VariableType> const& consideredVariables) { |
|||
Valuation lowerBoundaries; |
|||
Valuation upperBoundaries; |
|||
std::vector<std::string> parameterBoundaries; |
|||
boost::split(parameterBoundaries, regionString, boost::is_any_of(",")); |
|||
for (auto const& parameterBoundary : parameterBoundaries){ |
|||
if (!std::all_of(parameterBoundary.begin(),parameterBoundary.end(), ::isspace)){ //skip this string if it only consists of space
|
|||
parseParameterBoundaries(lowerBoundaries, upperBoundaries, parameterBoundary, consideredVariables); |
|||
} |
|||
} |
|||
return storm::storage::ParameterRegion<ParametricType>(std::move(lowerBoundaries), std::move(upperBoundaries)); |
|||
} |
|||
|
|||
template<typename ParametricType> |
|||
std::vector<storm::storage::ParameterRegion<ParametricType>> ParameterRegionParser<ParametricType>::parseMultipleRegions(std::string const& regionsString, std::set<VariableType> const& consideredVariables) { |
|||
std::vector<storm::storage::ParameterRegion<ParametricType>> result; |
|||
std::vector<std::string> regionsStrVec; |
|||
boost::split(regionsStrVec, regionsString, boost::is_any_of(";")); |
|||
for (auto const& regionStr : regionsStrVec){ |
|||
if (!std::all_of(regionStr.begin(),regionStr.end(), ::isspace)){ //skip this string if it only consists of space
|
|||
result.emplace_back(parseRegion(regionStr, consideredVariables)); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
template<typename ParametricType> |
|||
std::vector<storm::storage::ParameterRegion<ParametricType>> ParameterRegionParser<ParametricType>::parseMultipleRegionsFromFile(std::string const& fileName, std::set<VariableType> const& consideredVariables) { |
|||
|
|||
// Open file and initialize result.
|
|||
std::ifstream inputFileStream; |
|||
storm::utility::openFile(fileName, inputFileStream); |
|||
|
|||
std::vector<storm::storage::ParameterRegion<ParametricType>> result; |
|||
|
|||
// Now try to parse the contents of the file.
|
|||
try { |
|||
std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>())); |
|||
result = parseMultipleRegions(fileContent, consideredVariables); |
|||
} catch(std::exception& e) { |
|||
// In case of an exception properly close the file before passing exception.
|
|||
storm::utility::closeFile(inputFileStream); |
|||
throw e; |
|||
} |
|||
|
|||
// Close the stream in case everything went smoothly and return result.
|
|||
storm::utility::closeFile(inputFileStream); |
|||
return result; |
|||
} |
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
template class ParameterRegionParser<storm::RationalFunction>; |
|||
#endif
|
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,47 @@ |
|||
#pragma once |
|||
|
|||
#include <map> |
|||
|
|||
#include "storm-pars/storage/ParameterRegion.h" |
|||
|
|||
namespace storm { |
|||
namespace parser { |
|||
template<typename ParametricType> |
|||
class ParameterRegionParser{ |
|||
public: |
|||
|
|||
typedef typename storm::storage::ParameterRegion<ParametricType>::VariableType VariableType; |
|||
typedef typename storm::storage::ParameterRegion<ParametricType>::CoefficientType CoefficientType; |
|||
typedef typename storm::storage::ParameterRegion<ParametricType>::Valuation Valuation; |
|||
|
|||
/* |
|||
* Parse a single parameter with its boundaries from a string of the form "0.3<=p<=0.5". |
|||
* The results will be inserted in the given maps |
|||
* |
|||
*/ |
|||
static void parseParameterBoundaries( Valuation& lowerBoundaries, Valuation& upperBoundaries, std::string const& parameterBoundariesString, std::set<VariableType> const& consideredVariables); |
|||
|
|||
/* |
|||
* Parse a single region from a string of the form "0.3<=p<=0.5,0.4<=q<=0.7". |
|||
* |
|||
*/ |
|||
static storm::storage::ParameterRegion<ParametricType> parseRegion(std::string const& regionString, std::set<VariableType> const& consideredVariables); |
|||
|
|||
/* |
|||
* Parse a vector of region from a string of the form "0.3<=p<=0.5,0.4<=q<=0.7;0.1<=p<=0.3,0.2<=q<=0.4". |
|||
* |
|||
*/ |
|||
static std::vector<storm::storage::ParameterRegion<ParametricType>> parseMultipleRegions(std::string const& regionsString, std::set<VariableType> const& consideredVariables); |
|||
|
|||
|
|||
/* |
|||
* Parse multiple regions from a file |
|||
* |
|||
*/ |
|||
static std::vector<storm::storage::ParameterRegion<ParametricType>> parseMultipleRegionsFromFile(std::string const& fileName, std::set<VariableType> const& consideredVariables); |
|||
|
|||
}; |
|||
} |
|||
} |
|||
|
|||
|
|||
@ -0,0 +1,82 @@ |
|||
#include "storm-pars/settings/modules/RegionSettings.h"
|
|||
|
|||
#include "storm/settings/Option.h"
|
|||
#include "storm/settings/OptionBuilder.h"
|
|||
#include "storm/settings/ArgumentBuilder.h"
|
|||
#include "storm/settings/Argument.h"
|
|||
|
|||
#include "storm/utility/macros.h"
|
|||
#include "storm/exceptions/IllegalArgumentValueException.h"
|
|||
|
|||
namespace storm { |
|||
namespace settings { |
|||
namespace modules { |
|||
|
|||
const std::string RegionSettings::moduleName = "region"; |
|||
const std::string RegionSettings::regionOptionName = "region"; |
|||
const std::string RegionSettings::refineOptionName = "refine"; |
|||
const std::string RegionSettings::checkEngineOptionName = "engine"; |
|||
const std::string RegionSettings::printNoIllustrationOptionName = "noillustration"; |
|||
const std::string RegionSettings::printFullResultOptionName = "printfullresult"; |
|||
|
|||
RegionSettings::RegionSettings() : ModuleSettings(moduleName) { |
|||
this->addOption(storm::settings::OptionBuilder(moduleName, regionOptionName, true, "Sets the region(s) considered for analysis.") |
|||
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("regioninput", "The region(s) given in format a<=x<=b,c<=y<=d seperated by ';'. Can also be point to a file.").build()).build()); |
|||
|
|||
this->addOption(storm::settings::OptionBuilder(moduleName, refineOptionName, true, "Enables region refinement.") |
|||
.addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("threshold", "Refinement converges if the fraction of unknown area falls below this threshold.").setDefaultValueDouble(0.05).addValidatorDouble(storm::settings::ArgumentValidatorFactory::createDoubleRangeValidatorExcluding(0.0,1.0)).build()).build()); |
|||
|
|||
std::vector<std::string> engines = {"pl", "exactpl", "validatingpl"}; |
|||
this->addOption(storm::settings::OptionBuilder(moduleName, checkEngineOptionName, false, "Sets which engine is used for analyzing regions.") |
|||
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the engine to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(engines)).setDefaultValueString("pl").build()).build()); |
|||
|
|||
this->addOption(storm::settings::OptionBuilder(moduleName, printNoIllustrationOptionName, true, "If set, no illustration of the result is printed.").build()); |
|||
|
|||
this->addOption(storm::settings::OptionBuilder(moduleName, printFullResultOptionName, true, "If set, the full result for every region is printed.").build()); |
|||
} |
|||
|
|||
bool RegionSettings::isRegionSet() const { |
|||
return this->getOption(regionOptionName).getHasOptionBeenSet(); |
|||
} |
|||
|
|||
std::string RegionSettings::getRegionString() const { |
|||
return this->getOption(regionOptionName).getArgumentByName("regioninput").getValueAsString(); |
|||
} |
|||
|
|||
bool RegionSettings::isRefineSet() const { |
|||
return this->getOption(refineOptionName).getHasOptionBeenSet(); |
|||
} |
|||
|
|||
double RegionSettings::getRefinementThreshold() const { |
|||
return this->getOption(refineOptionName).getArgumentByName("threshold").getValueAsDouble(); |
|||
} |
|||
|
|||
storm::modelchecker::RegionCheckEngine RegionSettings::getRegionCheckEngine() const { |
|||
std::string engineString = this->getOption(regionOptionName).getArgumentByName("regioninput").getValueAsString(); |
|||
|
|||
storm::modelchecker::RegionCheckEngine result; |
|||
if (engineString == "pl") { |
|||
result = storm::modelchecker::RegionCheckEngine::ParameterLifting; |
|||
} else if (engineString == "exactpl") { |
|||
result = storm::modelchecker::RegionCheckEngine::ExactParameterLifting; |
|||
} else if (engineString == "validatingpl") { |
|||
result = storm::modelchecker::RegionCheckEngine::ValidatingParameterLifting; |
|||
} else { |
|||
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown region check engine '" << engineString << "'."); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
bool RegionSettings::isPrintNoIllustrationSet() const { |
|||
return this->getOption(printNoIllustrationOptionName).getHasOptionBeenSet(); |
|||
} |
|||
|
|||
bool RegionSettings::isPrintFullResultSet() const { |
|||
return this->getOption(printFullResultOptionName).getHasOptionBeenSet(); |
|||
} |
|||
|
|||
|
|||
} // namespace modules
|
|||
} // namespace settings
|
|||
} // namespace storm
|
|||
@ -0,0 +1,71 @@ |
|||
#pragma once |
|||
|
|||
#include "storm-pars/modelchecker/region/RegionCheckEngine.h" |
|||
|
|||
#include "storm/settings/modules/ModuleSettings.h" |
|||
|
|||
namespace storm { |
|||
namespace settings { |
|||
namespace modules { |
|||
|
|||
/*! |
|||
* This class represents the settings for parametric model checking. |
|||
*/ |
|||
class RegionSettings : public ModuleSettings { |
|||
public: |
|||
|
|||
/*! |
|||
* Creates a new set of parametric model checking settings. |
|||
*/ |
|||
RegionSettings(); |
|||
|
|||
/*! |
|||
* Retrieves whether region(s) were declared |
|||
*/ |
|||
bool isRegionSet() const; |
|||
|
|||
/*! |
|||
* Retrieves the region definition string |
|||
*/ |
|||
std::string getRegionString() const; |
|||
|
|||
/*! |
|||
* Retrieves whether region refinement is enabled |
|||
*/ |
|||
bool isRefineSet() const; |
|||
|
|||
/*! |
|||
* Retrieves the threshold considered for iterative region refinement. |
|||
* The refinement converges as soon as the fraction of unknown area falls below this threshold |
|||
*/ |
|||
double getRefinementThreshold() const; |
|||
|
|||
/*! |
|||
* Retrieves which type of region check should be performed |
|||
*/ |
|||
storm::modelchecker::RegionCheckEngine getRegionCheckEngine() const; |
|||
|
|||
/*! |
|||
* Retrieves whether no illustration of the result should be printed. |
|||
*/ |
|||
bool isPrintNoIllustrationSet() const; |
|||
|
|||
/*! |
|||
* Retrieves whether the full result should be printed |
|||
*/ |
|||
bool isPrintFullResultSet() const; |
|||
|
|||
const static std::string moduleName; |
|||
|
|||
private: |
|||
const static std::string regionOptionName; |
|||
const static std::string refineOptionName; |
|||
const static std::string checkEngineOptionName; |
|||
const static std::string printNoIllustrationOptionName; |
|||
const static std::string printFullResultOptionName; |
|||
}; |
|||
|
|||
} // namespace modules |
|||
} // namespace settings |
|||
} // namespace storm |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue