Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bindings for computing steady-state distributions #133

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/stormpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,21 @@ def compute_expected_number_of_visits(environment, model):
return core._compute_expected_number_of_visits_double(environment, model)


def compute_steady_state_distribution(environment, model):
"""
Compute the steady-state (aka stationary) distribution. Model must be deterministic.

:param environment: A model checking environment
:param model: A DTMC or CTMC
:return: A vector with the steady-state distribution
"""
if model.supports_parameters:
raise NotImplementedError("Steady-state distribution is not implemented for parametric models")
if model.is_exact:
return core._compute_steady_state_distribution_exact(environment, model)
return core._compute_steady_state_distribution_double(environment, model)


def construct_submodel(model, states, actions, keep_unreachable_states=True, options=SubsystemBuilderOptions()):
"""

Expand Down
7 changes: 7 additions & 0 deletions src/core/modelchecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ template<typename ValueType>
std::shared_ptr<storm::modelchecker::CheckResult> getExpectedNumberOfVisits(storm::Environment const& env, std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model) {
return storm::api::computeExpectedVisitingTimesWithSparseEngine(env, model);
}
template<typename ValueType>
std::shared_ptr<storm::modelchecker::CheckResult> getSteadyStateDistribution(storm::Environment const& env, std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model) {
return storm::api::computeSteadyStateDistributionWithSparseEngine(env, model);
}

template<typename ValueType>
storm::storage::BitVector getReachableStates(storm::models::sparse::Model<ValueType> const& model, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, boost::optional<uint64_t> maximalStep, boost::optional<storm::storage::BitVector> const& choiceFilter) {
Expand Down Expand Up @@ -123,6 +127,9 @@ void define_modelchecking(py::module& m) {
m.def("_compute_expected_number_of_visits_double", &getExpectedNumberOfVisits<double>, py::arg("env"), py::arg("model"));
m.def("_compute_expected_number_of_visits_exact", &getExpectedNumberOfVisits<storm::RationalNumber>, py::arg("env"), py::arg("model"));

m.def("_compute_steady_state_distribution_double", &getSteadyStateDistribution<double>, py::arg("env"), py::arg("model"));
m.def("_compute_steady_state_distribution_exact", &getSteadyStateDistribution<storm::RationalNumber>, py::arg("env"), py::arg("model"));

// Model checking
m.def("_model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine<double>, py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
m.def("_exact_model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine<storm::RationalNumber>, py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
Expand Down
13 changes: 13 additions & 0 deletions tests/core/test_modelchecking.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,16 @@ def test_compute_expected_number_of_visits(self):
result = stormpy.compute_expected_number_of_visits(environment, model)
assert result.at(0) == 1
assert math.isclose(result.at(1),2.0/3)

def test_compute_steady_state_distribution(self):
program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm"))
model = stormpy.build_model(program)
environment = stormpy.Environment()
result = stormpy.compute_steady_state_distribution(environment, model)
values = result.get_values()
assert len(values) == 13
sorted(values)
for i in range(7):
assert values[i] == 0
for i in range(7,13):
assert math.isclose(values[i], 1.0/6)
Loading