diff --git a/CMakeLists.txt b/CMakeLists.txt index a01dcea..1eab77a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ option(STORMPY_DISABLE_SIGNATURE_DOC "disables the signature in the documentatio find_package(storm REQUIRED) add_subdirectory(resources/pybind11) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/generated/config.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/generated/config.h) message(STATUS "STORM-DIR: ${storm_DIR}") set(STORMPY_LIB_DIR "${CMAKE_SOURCE_DIR}/lib/stormpy" CACHE STRING "Sets the storm library dir") @@ -49,8 +49,10 @@ stormpy_module(logic) stormpy_module(storage) stormpy_module(utility) +if(HAVE_STORM_PARS) + stormpy_module(pars "${STORMPY_LIB_DIR}/pars" storm-pars "${storm-pars_INCLUDE_DIR}") +endif() + if(HAVE_STORM_DFT) stormpy_module(dft "${STORMPY_LIB_DIR}/dft" storm-dft "${storm-dft_INCLUDE_DIR}") endif() - - diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 309669e..ef03051 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -2,6 +2,15 @@ cmake_minimum_required(VERSION 3.0.0) project(storm-version) find_package(storm REQUIRED) +# Check for storm-pars +if(EXISTS "${storm_DIR}/lib/libstorm-pars.dylib") + set(HAVE_STORM_PARS TRUE) +elseif(EXISTS "${storm_DIR}/lib/libstorm-pars.so") + set(HAVE_STORM_PARS TRUE) +else() + set(HAVE_STORM_PARS FALSE) +endif() + # Check for storm-dft if(EXISTS "${storm_DIR}/lib/libstorm-dft.dylib") set(HAVE_STORM_DFT TRUE) @@ -15,6 +24,12 @@ endif() set(STORM_DIR ${storm_DIR}) set(STORM_VERSION ${storm_VERSION}) +if(HAVE_STORM_PARS) + set(HAVE_STORM_PARS_BOOL "True") +else() + set(HAVE_STORM_PARS_BOOL "False") +endif() + if(HAVE_STORM_DFT) set(HAVE_STORM_DFT_BOOL "True") else() diff --git a/cmake/config.py.in b/cmake/config.py.in index 122d464..16e5ee7 100644 --- a/cmake/config.py.in +++ b/cmake/config.py.in @@ -1,7 +1,8 @@ -# Auto-generated by Cmake. +# Auto-generated by CMake. STORM_DIR = "@STORM_DIR@" STORM_VERSION = "@STORM_VERSION@" STORM_CLN_EA = @STORM_CLN_EA_BOOL@ STORM_CLN_RF = @STORM_CLN_RF_BOOL@ +HAVE_STORM_PARS = @HAVE_STORM_PARS_BOOL@ HAVE_STORM_DFT = @HAVE_STORM_DFT_BOOL@ diff --git a/lib/.gitignore b/lib/.gitignore index f40fdce..bc81f1a 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -1,4 +1,6 @@ *.so __pycache__/ stormpy.egg-info/ +stormpy/_config.py stormpy/dft/_config.py +stormpy/pars/_config.py diff --git a/lib/stormpy/pars/__init__.py b/lib/stormpy/pars/__init__.py new file mode 100644 index 0000000..f178522 --- /dev/null +++ b/lib/stormpy/pars/__init__.py @@ -0,0 +1,9 @@ +from . import _config + +if not _config.has_storm_pars: + raise ImportError("No support for parametric analysis was built in Storm.") + +from . import pars +from .pars import * + +pars._set_up() diff --git a/setup.py b/setup.py index 229dc50..fe28eea 100755 --- a/setup.py +++ b/setup.py @@ -106,6 +106,13 @@ class CMakeBuild(build_ext): f.write("storm_version = {}\n".format(self.conf.STORM_VERSION)) f.write("storm_cln_ea = {}\n".format(self.conf.STORM_CLN_EA)) f.write("storm_cln_rf = {}".format(self.conf.STORM_CLN_RF)) + elif ext.name == "pars": + with open(os.path.join(self.extdir(ext.name), ext.subdir, "_config.py"), "w") as f: + f.write("# Generated from setup.py at {}\n".format(datetime.datetime.now())) + f.write("has_storm_pars = {}".format(self.conf.HAVE_STORM_PARS)) + if not self.conf.HAVE_STORM_PARS: + print("WARNING: storm-pars not found. No support for parametric analysis will be built.") + continue elif ext.name == "dft": with open(os.path.join(self.extdir(ext.name), ext.subdir, "_config.py"), "w") as f: f.write("# Generated from setup.py at {}\n".format(datetime.datetime.now())) @@ -141,6 +148,8 @@ class CMakeBuild(build_ext): cmake_args += ['-DCMAKE_BUILD_TYPE=' + build_type] if self.conf.STORM_DIR is not None: cmake_args += ['-Dstorm_DIR=' + self.conf.STORM_DIR] + if self.conf.HAVE_STORM_PARS: + cmake_args += ['-DHAVE_STORM_PARS=ON'] if self.conf.HAVE_STORM_DFT: cmake_args += ['-DHAVE_STORM_DFT=ON'] @@ -172,7 +181,8 @@ setup( maintainer_email="sebastian.junges@cs.rwth-aachen.de", url="http://moves.rwth-aachen.de", description="stormpy - Python Bindings for Storm", - packages=['stormpy', 'stormpy.info', 'stormpy.expressions', 'stormpy.logic', 'stormpy.storage', 'stormpy.utility', 'stormpy.dft'], + packages=['stormpy', 'stormpy.info', 'stormpy.expressions', 'stormpy.logic', 'stormpy.storage', 'stormpy.utility', + 'stormpy.pars', 'stormpy.dft'], package_dir={'': 'lib'}, ext_package='stormpy', ext_modules=[CMakeExtension('core', subdir=''), @@ -181,7 +191,8 @@ setup( CMakeExtension('logic', subdir='logic'), CMakeExtension('storage', subdir='storage'), CMakeExtension('utility', subdir='utility'), - CMakeExtension('dft', subdir='dft') + CMakeExtension('pars', subdir='pars'), + CMakeExtension('dft', subdir='dft'), ], cmdclass={'build_ext': CMakeBuild, 'test': PyTest}, zip_safe=False, diff --git a/src/core/pla.cpp b/src/core/pla.cpp deleted file mode 100644 index 1f34f12..0000000 --- a/src/core/pla.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "pla.h" -#include "src/helpers.h" -#include "storm/modelchecker/parametric/SparseDtmcRegionChecker.h" - -typedef storm::modelchecker::parametric::SparseDtmcRegionChecker, double, storm::RationalNumber> SparseDtmcRegionChecker; -typedef storm::storage::ParameterRegion Region; - -// Thin wrappers -void specifyFormula(std::shared_ptr& checker, std::shared_ptr const& formula) { - checker->specifyFormula(storm::modelchecker::CheckTask(*formula, true)); -} -storm::modelchecker::parametric::RegionCheckResult checkRegion(std::shared_ptr& checker, Region& region, storm::modelchecker::parametric::RegionCheckResult initialResult, bool sampleVertices) { - return checker->analyzeRegion(region, initialResult, sampleVertices); -} - -std::set gatherDerivatives(storm::models::sparse::Dtmc const& model, carl::Variable const& var) { - std::set derivatives; - for (auto it : model.getTransitionMatrix()) { - storm::Polynomial pol = it.getValue().derivative(var, 1).nominator(); - if (!pol.isConstant()) { - derivatives.insert(pol); - } - } - return derivatives; -} - -// Define python bindings -void define_pla(py::module& m) { - - // RegionCheckResult - py::enum_(m, "RegionCheckResult", "Types of region check results") - .value("EXISTSSAT", storm::modelchecker::parametric::RegionCheckResult::ExistsSat) - .value("EXISTSVIOLATED", storm::modelchecker::parametric::RegionCheckResult::ExistsViolated) - .value("EXISTSBOTH", storm::modelchecker::parametric::RegionCheckResult::ExistsBoth) - .value("CENTERSAT", storm::modelchecker::parametric::RegionCheckResult::CenterSat) - .value("CENTERVIOLATED", storm::modelchecker::parametric::RegionCheckResult::CenterViolated) - .value("ALLSAT", storm::modelchecker::parametric::RegionCheckResult::AllSat) - .value("ALLVIOLATED", storm::modelchecker::parametric::RegionCheckResult::AllViolated) - .value("UNKNOWN", storm::modelchecker::parametric::RegionCheckResult::Unknown) - .def("__str__", &streamToString) - ; - - // Region - py::class_>(m, "ParameterRegion", "Parameter region") - .def("__init__", [](Region &instance, std::string const& regionString, std::set const& variables) -> void { - new (&instance) Region(Region::parseRegion(regionString, variables)); - }) - //.def(py::init(), py::arg("lowerBounds"), py::arg("upperBounds")) - ; - - // RegionChecker - py::class_>(m, "SparseDtmcRegionChecker", "Region model checker for sparse DTMCs") - .def("__init__", [](SparseDtmcRegionChecker& instance, std::shared_ptr> model) -> void { - new (&instance) SparseDtmcRegionChecker(*model); - }) - .def("specify_formula", &specifyFormula, "Specify formula", py::arg("formula")) - .def("check_region", &checkRegion, "Check region", py::arg("region"), py::arg("initialResult") = storm::modelchecker::parametric::RegionCheckResult::Unknown, py::arg("sampleVertices") = false) - ; - - m.def("gather_derivatives", &gatherDerivatives, "Gather all derivatives of transition probabilities", py::arg("model"), py::arg("var")); -} diff --git a/src/core/pla.h b/src/core/pla.h deleted file mode 100644 index 7ca587a..0000000 --- a/src/core/pla.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PYTHON_CORE_PLA_H_ -#define PYTHON_CORE_PLA_H_ - -#include "common.h" - -void define_pla(py::module& m); - -#endif /* PYTHON_CORE_PLA_H_ */ diff --git a/src/mod_core.cpp b/src/mod_core.cpp index 10cbe19..1c2485a 100644 --- a/src/mod_core.cpp +++ b/src/mod_core.cpp @@ -5,16 +5,15 @@ #include "core/modelchecking.h" #include "core/bisimulation.h" #include "core/input.h" -#include "core/pla.h" PYBIND11_PLUGIN(core) { py::module m("core"); - + #ifdef STORMPY_DISABLE_SIGNATURE_DOC py::options options; // options.disable_function_signatures(); #endif - + define_core(m); define_property(m); define_parse(m); @@ -25,6 +24,5 @@ PYBIND11_PLUGIN(core) { define_modelchecking(m); define_bisimulation(m); define_input(m); - define_pla(m); return m.ptr(); } diff --git a/src/mod_pars.cpp b/src/mod_pars.cpp new file mode 100644 index 0000000..b65de7b --- /dev/null +++ b/src/mod_pars.cpp @@ -0,0 +1,19 @@ +#include "common.h" + +#include "pars/pars.h" +#include "pars/pla.h" +#include "pars/model_instantiator.h" + +PYBIND11_PLUGIN(pars) { + py::module m("pars", "Functionality for parametric analysis"); + +#ifdef STORMPY_DISABLE_SIGNATURE_DOC + py::options options; + options.disable_function_signatures(); +#endif + + define_pars(m); + define_pla(m); + define_model_instantiator(m); + return m.ptr(); +} diff --git a/src/mod_storage.cpp b/src/mod_storage.cpp index 2755911..ef8903f 100644 --- a/src/mod_storage.cpp +++ b/src/mod_storage.cpp @@ -18,7 +18,6 @@ PYBIND11_PLUGIN(storage) { define_model(m); define_sparse_matrix(m); define_state(m); - define_model_instantiator(m); define_labeling(m); return m.ptr(); } diff --git a/src/pars/common.h b/src/pars/common.h new file mode 100644 index 0000000..79a9840 --- /dev/null +++ b/src/pars/common.h @@ -0,0 +1,3 @@ +#include "src/common.h" + +#include "storm-pars/api/storm-pars.h" diff --git a/src/pars/model_instantiator.cpp b/src/pars/model_instantiator.cpp new file mode 100644 index 0000000..78b0376 --- /dev/null +++ b/src/pars/model_instantiator.cpp @@ -0,0 +1,29 @@ +#include "model_instantiator.h" +#include "storm/models/sparse/Model.h" + +template using Model = storm::models::sparse::Model; +template using Dtmc = storm::models::sparse::Dtmc; +template using Mdp = storm::models::sparse::Mdp; +template using Ctmc = storm::models::sparse::Ctmc; +template using MarkovAutomaton = storm::models::sparse::MarkovAutomaton; + +// Model instantiator +void define_model_instantiator(py::module& m) { + py::class_, Dtmc>>(m, "PDtmcInstantiator", "Instantiate PDTMCs to DTMCs") + .def(py::init>(), "parametric model"_a) + .def("instantiate", &storm::utility::ModelInstantiator, Dtmc>::instantiate, "Instantiate model with given parameter values") + ; + + py::class_,Mdp>>(m, "PMdpInstantiator", "Instantiate PMDPs to MDPs") + .def(py::init>(), "parametric model"_a) + .def("instantiate", &storm::utility::ModelInstantiator, Mdp>::instantiate, "Instantiate model with given parameter values") + ; + + py::class_,Ctmc>>(m, "PCtmcInstantiator", "Instantiate PCTMCs to CTMCs") + .def(py::init>(), "parametric model"_a) + .def("instantiate", &storm::utility::ModelInstantiator, Ctmc>::instantiate, "Instantiate model with given parameter values"); + + py::class_,MarkovAutomaton>>(m, "PMaInstantiator", "Instantiate PMAs to MAs") + .def(py::init>(), "parametric model"_a) + .def("instantiate", &storm::utility::ModelInstantiator, MarkovAutomaton>::instantiate, "Instantiate model with given parameter values"); +} diff --git a/src/pars/model_instantiator.h b/src/pars/model_instantiator.h new file mode 100644 index 0000000..d841821 --- /dev/null +++ b/src/pars/model_instantiator.h @@ -0,0 +1,8 @@ +#ifndef PYTHON_PARS_MODEL_INSTANTIATOR_H_ +#define PYTHON_PARS_MODEL_INSTANTIATOR_H_ + +#include "common.h" + +void define_model_instantiator(py::module& m); + +#endif /* PYTHON_PARS_MODEL_INSTANTIATOR_H_ */ diff --git a/src/pars/pars.cpp b/src/pars/pars.cpp new file mode 100644 index 0000000..662735c --- /dev/null +++ b/src/pars/pars.cpp @@ -0,0 +1,11 @@ +#include "pars.h" +#include "storm/settings/SettingsManager.h" +#include "storm-pars/settings/modules/ParametricSettings.h" +#include "storm-pars/settings/modules/RegionSettings.h" + +void define_pars(py::module& m) { + m.def("_set_up", []() { + storm::settings::addModule(); + storm::settings::addModule(); + }, "Initialize Storm-pars"); +} diff --git a/src/pars/pars.h b/src/pars/pars.h new file mode 100644 index 0000000..2f1cf7d --- /dev/null +++ b/src/pars/pars.h @@ -0,0 +1,8 @@ +#ifndef PYTHON_PARS_PARS_H_ +#define PYTHON_PARS_PARS_H_ + +#include "common.h" + +void define_pars(py::module& m); + +#endif /* PYTHON_PARS_PARS_H_ */ diff --git a/src/pars/pla.cpp b/src/pars/pla.cpp new file mode 100644 index 0000000..1e786db --- /dev/null +++ b/src/pars/pla.cpp @@ -0,0 +1,70 @@ +#include "pla.h" +#include "src/helpers.h" +#include "storm/api/storm.h" + +typedef storm::modelchecker::SparseDtmcParameterLiftingModelChecker, double> SparseDtmcRegionChecker; +typedef storm::modelchecker::RegionModelChecker RegionModelChecker; +typedef storm::storage::ParameterRegion Region; + +// Thin wrappers +std::shared_ptr createRegionChecker(std::shared_ptr> const& model, std::shared_ptr const& formula) { + return storm::api::initializeParameterLiftingRegionModelChecker(model, storm::api::createTask(formula, true)); +} + +storm::modelchecker::RegionResult checkRegion(std::shared_ptr& checker, Region& region, storm::modelchecker::RegionResult initialResult, bool sampleVertices) { + return checker->analyzeRegion(region, initialResult, sampleVertices); +} + +std::set gatherDerivatives(storm::models::sparse::Dtmc const& model, carl::Variable const& var) { + std::set derivatives; + for (auto it : model.getTransitionMatrix()) { + storm::Polynomial pol = it.getValue().derivative(var, 1).nominator(); + if (!pol.isConstant()) { + derivatives.insert(pol); + } + } + return derivatives; +} + + + +// Define python bindings +void define_pla(py::module& m) { + + // RegionResult + py::enum_(m, "RegionResult", "Types of region check results") + .value("EXISTSSAT", storm::modelchecker::RegionResult::ExistsSat) + .value("EXISTSVIOLATED", storm::modelchecker::RegionResult::ExistsViolated) + .value("EXISTSBOTH", storm::modelchecker::RegionResult::ExistsBoth) + .value("CENTERSAT", storm::modelchecker::RegionResult::CenterSat) + .value("CENTERVIOLATED", storm::modelchecker::RegionResult::CenterViolated) + .value("ALLSAT", storm::modelchecker::RegionResult::AllSat) + .value("ALLVIOLATED", storm::modelchecker::RegionResult::AllViolated) + .value("UNKNOWN", storm::modelchecker::RegionResult::Unknown) + .def("__str__", &streamToString) + ; + + // Region + py::class_>(m, "ParameterRegion", "Parameter region") + .def("__init__", [](Region &instance, std::string const& regionString, std::set const& variables) -> void { + new (&instance) Region(storm::api::parseRegion(regionString, variables)); + }) + ; + + // RegionModelChecker + //py::class_>(m, "SparseDtmcRegionChecker", "Region model checker for sparse DTMCs") + py::class_>(m, "RegionModelChecker", "Region model checker via paramater lifting") +/* .def("__init__", [](std::unique_ptr& instance, std::shared_ptr> model, storm::modelchecker::CheckTask const& task) -> void { + // Better use storm::api::initializeParameterLiftingRegionModelChecker(model, task); + //SparseDtmcRegionChecker tmp; + //tmp.specify(model, task); + auto tmp = storm::api::initializeParameterLiftingRegionModelChecker(model, task); + new (&instance) std::unique_ptr(tmp); + }, py::arg("model"), py::arg("task")*/ + .def("check_region", &checkRegion, "Check region", py::arg("region"), py::arg("initialResult") = storm::modelchecker::RegionResult::Unknown, py::arg("sampleVertices") = false) + ; + + m.def("create_region_checker", &createRegionChecker, "Create region checker", py::arg("model"), py::arg("formula")); + //m.def("is_parameter_lifting_sound", &storm::utility::parameterlifting::validateParameterLiftingSound, "Check if parameter lifting is sound", py::arg("model"), py::arg("formula")); + m.def("gather_derivatives", &gatherDerivatives, "Gather all derivatives of transition probabilities", py::arg("model"), py::arg("var")); +} diff --git a/src/pars/pla.h b/src/pars/pla.h new file mode 100644 index 0000000..327e627 --- /dev/null +++ b/src/pars/pla.h @@ -0,0 +1,8 @@ +#ifndef PYTHON_PARS_PLA_H_ +#define PYTHON_PARS_PLA_H_ + +#include "common.h" + +void define_pla(py::module& m); + +#endif /* PYTHON_PARS_PLA_H_ */ diff --git a/src/storage/model.cpp b/src/storage/model.cpp index e37c38e..cb05b12 100644 --- a/src/storage/model.cpp +++ b/src/storage/model.cpp @@ -5,8 +5,9 @@ #include "storm/models/sparse/Model.h" #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/Mdp.h" +#include "storm/models/sparse/Ctmc.h" +#include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/utility/ModelInstantiator.h" #include #include @@ -159,23 +160,3 @@ void define_model(py::module& m) { } -// Model instantiator -void define_model_instantiator(py::module& m) { - py::class_, Dtmc>>(m, "PdtmcInstantiator", "Instantiate PDTMCs to DTMCs") - .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, Dtmc>::instantiate, "Instantiate model with given parameter values") - ; - - py::class_,Mdp>>(m, "PmdpInstantiator", "Instantiate PMDPs to MDPs") - .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, Mdp>::instantiate, "Instantiate model with given parameter values") - ; - - py::class_,Ctmc>>(m, "PctmcInstantiator", "Instantiate PCTMCs to CTMCs") - .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, Ctmc>::instantiate, "Instantiate model with given parameter values"); - - py::class_,MarkovAutomaton>>(m, "PmaInstantiator", "Instantiate PMAs to MAs") - .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, MarkovAutomaton>::instantiate, "Instantiate model with given parameter values"); -} diff --git a/src/storage/model.h b/src/storage/model.h index 69e4359..c779f26 100644 --- a/src/storage/model.h +++ b/src/storage/model.h @@ -4,6 +4,5 @@ #include "common.h" void define_model(py::module& m); -void define_model_instantiator(py::module& m); #endif /* PYTHON_STORAGE_MODEL_H_ */ diff --git a/tests/storage/test_model_instantiator.py b/tests/pars/test_model_instantiator.py similarity index 92% rename from tests/storage/test_model_instantiator.py rename to tests/pars/test_model_instantiator.py index f34b5f9..046dbbb 100644 --- a/tests/storage/test_model_instantiator.py +++ b/tests/pars/test_model_instantiator.py @@ -1,6 +1,7 @@ import pycarl import stormpy import stormpy.logic +import stormpy.pars from helpers.helper import get_example_path @@ -10,7 +11,7 @@ class TestModel: formulas = stormpy.parse_properties_for_prism_program("P=? [ F s=5 ]", program) model = stormpy.build_parametric_model(program, formulas) parameters = model.collect_probability_parameters() - instantiator = stormpy.ModelInstantiator(model) + instantiator = stormpy.pars.PDtmcInstantiator(model) point = {p: stormpy.RationalRF("0.4") for p in parameters} instantiated_model = instantiator.instantiate(point) diff --git a/tests/core/test_parametric.py b/tests/pars/test_parametric.py similarity index 100% rename from tests/core/test_parametric.py rename to tests/pars/test_parametric.py diff --git a/tests/core/test_pla.py b/tests/pars/test_pla.py similarity index 66% rename from tests/core/test_pla.py rename to tests/pars/test_pla.py index 0301692..62b8030 100644 --- a/tests/core/test_pla.py +++ b/tests/pars/test_pla.py @@ -1,5 +1,6 @@ import stormpy import stormpy.logic +import stormpy.pars from helpers.helper import get_example_path class TestModelChecking: @@ -13,19 +14,18 @@ class TestModelChecking: assert model.nr_transitions == 803 assert model.model_type == stormpy.ModelType.DTMC assert model.has_parameters - checker = stormpy.SparseDtmcRegionChecker(model) - checker.specify_formula(formulas[0].raw_formula) + checker = stormpy.pars.create_region_checker(model, formulas[0].raw_formula) parameters = model.collect_probability_parameters() assert len(parameters) == 2 - region = stormpy.ParameterRegion("0.7<=pL<=0.9,0.75<=pK<=0.95", parameters) + region = stormpy.pars.ParameterRegion("0.7<=pL<=0.9,0.75<=pK<=0.95", parameters) result = checker.check_region(region) - assert result == stormpy.RegionCheckResult.ALLSAT - region = stormpy.ParameterRegion("0.4<=pL<=0.65,0.75<=pK<=0.95", parameters) - result = checker.check_region(region, stormpy.RegionCheckResult.UNKNOWN, True) - assert result == stormpy.RegionCheckResult.EXISTSBOTH - region = stormpy.ParameterRegion("0.1<=pL<=0.73,0.2<=pK<=0.715", parameters) + assert result == stormpy.pars.RegionResult.ALLSAT + region = stormpy.pars.ParameterRegion("0.4<=pL<=0.65,0.75<=pK<=0.95", parameters) + result = checker.check_region(region, stormpy.pars.RegionResult.UNKNOWN, True) + assert result == stormpy.pars.RegionResult.EXISTSBOTH + region = stormpy.pars.ParameterRegion("0.1<=pL<=0.73,0.2<=pK<=0.715", parameters) result = checker.check_region(region) - assert result == stormpy.RegionCheckResult.ALLVIOLATED + assert result == stormpy.pars.RegionResult.ALLVIOLATED def test_derivatives(self): import pycarl @@ -39,5 +39,5 @@ class TestModelChecking: assert model.has_parameters parameters = model.collect_probability_parameters() assert len(parameters) == 2 - derivatives = stormpy.gather_derivatives(model, list(parameters)[0]) + derivatives = stormpy.pars.gather_derivatives(model, list(parameters)[0]) assert len(derivatives) == 0