6 changed files with 123 additions and 4 deletions
			
			
		- 
					60src/core/pla.cpp
 - 
					8src/core/pla.h
 - 
					10src/core/result.cpp
 - 
					2src/mod_core.cpp
 - 
					2src/utility/shortestPaths.cpp
 - 
					43tests/core/test_pla.py
 
@ -0,0 +1,60 @@ | 
				
			|||
#include "pla.h"
 | 
				
			|||
#include "src/helpers.h"
 | 
				
			|||
 | 
				
			|||
typedef storm::modelchecker::parametric::SparseDtmcRegionChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, double, storm::RationalNumber> SparseDtmcRegionChecker; | 
				
			|||
typedef storm::storage::ParameterRegion<storm::RationalFunction> Region; | 
				
			|||
 | 
				
			|||
// Thin wrappers
 | 
				
			|||
void specifyFormula(std::shared_ptr<SparseDtmcRegionChecker>& checker, std::shared_ptr<const storm::logic::Formula> const& formula) { | 
				
			|||
    checker->specifyFormula(storm::modelchecker::CheckTask<storm::logic::Formula, storm::RationalFunction>(*formula, true)); | 
				
			|||
} | 
				
			|||
storm::modelchecker::parametric::RegionCheckResult checkRegion(std::shared_ptr<SparseDtmcRegionChecker>& checker, Region& region, storm::modelchecker::parametric::RegionCheckResult initialResult, bool sampleVertices) { | 
				
			|||
    return checker->analyzeRegion(region, initialResult, sampleVertices); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
std::set<storm::Polynomial> gatherDerivatives(storm::models::sparse::Dtmc<storm::RationalFunction> const& model, carl::Variable const& var) { | 
				
			|||
    std::set<storm::Polynomial> 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_<storm::modelchecker::parametric::RegionCheckResult>(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<storm::modelchecker::parametric::RegionCheckResult>) | 
				
			|||
    ; | 
				
			|||
 | 
				
			|||
    // Region
 | 
				
			|||
    py::class_<Region, std::shared_ptr<Region>>(m, "ParameterRegion", "Parameter region") | 
				
			|||
       .def("__init__", [](Region &instance, std::string const& regionString, std::set<Region::VariableType> const& variables) -> void { | 
				
			|||
                new (&instance) Region(Region::parseRegion(regionString, variables)); | 
				
			|||
            }) | 
				
			|||
        //.def(py::init<Region::VariableSubstitutionType &, Region::VariableSubstitutionType &>(), py::arg("lowerBounds"), py::arg("upperBounds"))
 | 
				
			|||
    ; | 
				
			|||
 | 
				
			|||
    // RegionChecker
 | 
				
			|||
    py::class_<SparseDtmcRegionChecker, std::shared_ptr<SparseDtmcRegionChecker>>(m, "SparseDtmcRegionChecker", "Region model checker for sparse DTMCs") | 
				
			|||
        .def("__init__", [](SparseDtmcRegionChecker& instance, std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> 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")); | 
				
			|||
} | 
				
			|||
@ -0,0 +1,8 @@ | 
				
			|||
#ifndef PYTHON_CORE_PLA_H_ | 
				
			|||
#define PYTHON_CORE_PLA_H_ | 
				
			|||
 | 
				
			|||
#include "common.h" | 
				
			|||
 | 
				
			|||
void define_pla(py::module& m); | 
				
			|||
 | 
				
			|||
#endif /* PYTHON_CORE_PLA_H_ */ | 
				
			|||
@ -0,0 +1,43 @@ | 
				
			|||
import stormpy | 
				
			|||
import stormpy.logic | 
				
			|||
from helpers.helper import get_example_path | 
				
			|||
 | 
				
			|||
class TestModelChecking: | 
				
			|||
    def test_pla(self): | 
				
			|||
        import pycarl | 
				
			|||
        program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) | 
				
			|||
        prop = "P<=0.84 [F s=5 ]" | 
				
			|||
        formulas = stormpy.parse_properties_for_prism_program(prop, program) | 
				
			|||
        model = stormpy.build_parametric_model(program, formulas) | 
				
			|||
        assert model.nr_states == 613 | 
				
			|||
        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) | 
				
			|||
        parameters = model.collect_probability_parameters() | 
				
			|||
        assert len(parameters) == 2 | 
				
			|||
        region = stormpy.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) | 
				
			|||
        result = checker.check_region(region) | 
				
			|||
        assert result == stormpy.RegionCheckResult.ALLVIOLATED | 
				
			|||
     | 
				
			|||
    def test_derivatives(self): | 
				
			|||
        import pycarl | 
				
			|||
        program = stormpy.parse_prism_program(get_example_path("pdtmc", "brp16_2.pm")) | 
				
			|||
        prop = "P<=0.84 [F s=5 ]" | 
				
			|||
        formulas = stormpy.parse_properties_for_prism_program(prop, program) | 
				
			|||
        model = stormpy.build_parametric_model(program, formulas) | 
				
			|||
        assert model.nr_states == 613 | 
				
			|||
        assert model.nr_transitions == 803 | 
				
			|||
        assert model.model_type == stormpy.ModelType.DTMC | 
				
			|||
        assert model.has_parameters | 
				
			|||
        parameters = model.collect_probability_parameters() | 
				
			|||
        assert len(parameters) == 2 | 
				
			|||
        derivatives = stormpy.gather_derivatives(model, list(parameters)[0]) | 
				
			|||
        assert len(derivatives) == 0 | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue