Browse Source

support for exact arithmetic

refactoring
Sebastian Junges 4 years ago
parent
commit
58da4df1c3
  1. 4
      CHANGELOG.md
  2. 12
      lib/stormpy/__init__.py
  3. 5
      lib/stormpy/simulator.py
  4. 10
      src/core/core.cpp
  5. 10
      src/core/modelchecking.cpp
  6. 23
      src/core/simulator.cpp
  7. 3
      src/core/simulator.h
  8. 4
      src/mod_core.cpp
  9. 5
      src/mod_pomdp.cpp
  10. 18
      src/mod_storage.cpp
  11. 59
      src/pomdp/tracker.cpp
  12. 3
      src/pomdp/tracker.h
  13. 14
      src/pomdp/transformations.cpp
  14. 4
      src/storage/distribution.cpp
  15. 1
      src/storage/jani.cpp
  16. 187
      src/storage/matrix.cpp
  17. 5
      src/storage/matrix.h
  18. 140
      src/storage/model.cpp
  19. 4
      src/storage/model.h
  20. 39
      src/storage/model_components.cpp
  21. 3
      src/storage/model_components.h
  22. 3
      src/storage/scheduler.cpp
  23. 64
      src/storage/state.cpp
  24. 3
      src/storage/state.h

4
CHANGELOG.md

@ -4,6 +4,10 @@ Changelog
Version 1.6.x
-------------
### Version 1.6.3 (to be released)
- Support for exact arithmetic in models
### Version 1.6.2 (2020/09)
Requires storm version >= 1.6.2 and pycarl version >= 2.0.4

12
lib/stormpy/__init__.py

@ -297,9 +297,15 @@ def check_model_sparse(model, property, only_initial_states=False, extract_sched
task.set_produce_schedulers(extract_scheduler)
return core._parametric_model_checking_sparse_engine(model, task, environment=environment)
else:
task = core.CheckTask(formula, only_initial_states)
task.set_produce_schedulers(extract_scheduler)
return core._model_checking_sparse_engine(model, task, environment=environment)
if model.is_exact:
task = core.ExactCheckTask(formula, only_initial_states)
task.set_produce_schedulers(extract_scheduler)
return core._exact_model_checking_sparse_engine(model, task, environment=environment)
else:
task = core.CheckTask(formula, only_initial_states)
task.set_produce_schedulers(extract_scheduler)
return core._model_checking_sparse_engine(model, task, environment=environment)
def check_model_dd(model, property, only_initial_states=False, environment=Environment()):

5
lib/stormpy/simulator.py

@ -93,7 +93,10 @@ class SparseSimulator(Simulator):
def __init__(self, model, seed=None):
super().__init__(seed)
self._model = model
self._engine = stormpy.core._DiscreteTimeSparseModelSimulatorDouble(model)
if self._model.is_exact:
self._engine = stormpy.core._DiscreteTimeSparseModelSimulatorExact(model)
else:
self._engine = stormpy.core._DiscreteTimeSparseModelSimulatorDouble(model)
if seed is not None:
self._engine.set_seed(seed)
self._state_valuations = None

10
src/core/core.cpp

@ -101,24 +101,28 @@ void define_build(py::module& m) {
// Build model
m.def("_build_sparse_model_from_symbolic_description", &buildSparseModel<double>, "Build the model in sparse representation", py::arg("model_description"), py::arg("formulas") = std::vector<std::shared_ptr<storm::logic::Formula const>>(), py::arg("use_jit") = false, py::arg("doctor") = false);
m.def("_build_sparse_exact_model_from_symbolic_description", &buildSparseModel<storm::RationalNumber>, "Build the model in sparse representation with exact number representation", py::arg("model_description"), py::arg("formulas") = std::vector<std::shared_ptr<storm::logic::Formula const>>(), py::arg("use_jit") = false, py::arg("doctor") = false);
m.def("_build_sparse_parametric_model_from_symbolic_description", &buildSparseModel<storm::RationalFunction>, "Build the parametric model in sparse representation", py::arg("model_description"), py::arg("formulas") = std::vector<std::shared_ptr<storm::logic::Formula const>>(), py::arg("use_jit") = false, py::arg("doctor") = false);
m.def("build_sparse_model_with_options", &buildSparseModelWithOptions<double>, "Build the model in sparse representation", py::arg("model_description"), py::arg("options"), py::arg("use_jit") = false, py::arg("doctor") = false);
m.def("build_sparse_exact_model_with_options", &buildSparseModelWithOptions<storm::RationalNumber>, "Build the model in sparse representation with exact number representation", py::arg("model_description"), py::arg("options"), py::arg("use_jit") = false, py::arg("doctor") = false);
m.def("build_sparse_parametric_model_with_options", &buildSparseModelWithOptions<storm::RationalFunction>, "Build the model in sparse representation", py::arg("model_description"), py::arg("options"), py::arg("use_jit") = false, py::arg("doctor") = false);
m.def("_build_symbolic_model_from_symbolic_description", &buildSymbolicModel<storm::dd::DdType::Sylvan, double>, "Build the model in symbolic representation", py::arg("model_description"), py::arg("formulas") = std::vector<std::shared_ptr<storm::logic::Formula const>>());
m.def("_build_symbolic_parametric_model_from_symbolic_description", &buildSymbolicModel<storm::dd::DdType::Sylvan, storm::RationalFunction>, "Build the parametric model in symbolic representation", py::arg("model_description"), py::arg("formulas") = std::vector<std::shared_ptr<storm::logic::Formula const>>());
m.def("_build_sparse_model_from_drn", &storm::api::buildExplicitDRNModel<double>, "Build the model from DRN", py::arg("file"), py::arg("options") = storm::parser::DirectEncodingParserOptions());
m.def("_build_sparse_exact_model_from_drn", &storm::api::buildExplicitDRNModel<storm::RationalNumber>, "Build the model from DRN", py::arg("file"), py::arg("options") = storm::parser::DirectEncodingParserOptions());
m.def("_build_sparse_parametric_model_from_drn", &storm::api::buildExplicitDRNModel<storm::RationalFunction>, "Build the parametric model from DRN", py::arg("file"), py::arg("options") = storm::parser::DirectEncodingParserOptions());
m.def("build_sparse_model_from_explicit", &storm::api::buildExplicitModel<double>, "Build the model model from explicit input", py::arg("transition_file"), py::arg("labeling_file"), py::arg("state_reward_file") = "", py::arg("transition_reward_file") = "", py::arg("choice_labeling_file") = "");
m.def("make_sparse_model_builder", &storm::api::makeExplicitModelBuilder<double>, "Construct a builder instance", py::arg("model_description"), py::arg("options"));
m.def("make_sparse_model_builder_exact", &storm::api::makeExplicitModelBuilder<storm::RationalNumber>, "Construct a builder instance", py::arg("model_description"), py::arg("options"));
m.def("make_sparse_model_builder_parametric", &storm::api::makeExplicitModelBuilder<double>, "Construct a builder instance", py::arg("model_description"), py::arg("options"));
py::class_<storm::builder::ExplicitModelBuilder<double>>(m, "ExplicitModelBuilder_Double", "Model builder for sparse models")
py::class_<storm::builder::ExplicitModelBuilder<double>>(m, "ExplicitModelBuilder", "Model builder for sparse models")
.def("build", &storm::builder::ExplicitModelBuilder<double>::build, "Build the model")
.def("export_lookup", &storm::builder::ExplicitModelBuilder<double>::exportExplicitStateLookup, "Export a lookup model")
;
py::class_<storm::builder::ExplicitModelBuilder<storm::RationalFunction>>(m, "ExplicitModelBuilder_RF", "Model builder for sparse models")
py::class_<storm::builder::ExplicitModelBuilder<storm::RationalFunction>>(m, "ExplicitParametricModelBuilder", "Model builder for sparse models")
.def("build", &storm::builder::ExplicitModelBuilder<storm::RationalFunction>::build, "Build the model")
.def("export_lookup", &storm::builder::ExplicitModelBuilder<storm::RationalFunction>::exportExplicitStateLookup, "Export a lookup model")
;
@ -164,6 +168,8 @@ void define_export(py::module& m) {
opts.def(py::init<>());
opts.def_readwrite("allow_placeholders", &storm::exporter::DirectEncodingOptions::allowPlaceholders);
// Export
// TODO make one export_to_drn that infers which of the folliwng to use.
m.def("export_to_drn", &exportDRN<double>, "Export model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::exporter::DirectEncodingOptions());
m.def("export_exact_to_drn", &exportDRN<double>, "Export model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::exporter::DirectEncodingOptions());
m.def("export_parametric_to_drn", &exportDRN<storm::RationalFunction>, "Export parametric model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::exporter::DirectEncodingOptions());
}

10
src/core/modelchecking.cpp

@ -66,6 +66,12 @@ void define_modelchecking(py::module& m) {
.def(py::init<storm::logic::Formula const&, bool>(), py::arg("formula"), py::arg("only_initial_states") = false)
.def("set_produce_schedulers", &CheckTask<double>::setProduceSchedulers, "Set whether schedulers should be produced (if possible)", py::arg("produce_schedulers") = true)
;
// CheckTask
py::class_<CheckTask<storm::RationalNumber>, std::shared_ptr<CheckTask<storm::RationalNumber>>>(m, "ExactCheckTask", "Task for model checking with exact numbers")
//m.def("create_check_task", &storm::api::createTask, "Create task for verification", py::arg("formula"), py::arg("only_initial_states") = false);
.def(py::init<storm::logic::Formula const&, bool>(), py::arg("formula"), py::arg("only_initial_states") = false)
.def("set_produce_schedulers", &CheckTask<storm::RationalNumber>::setProduceSchedulers, "Set whether schedulers should be produced (if possible)", py::arg("produce_schedulers") = true)
;
py::class_<CheckTask<storm::RationalFunction>, std::shared_ptr<CheckTask<storm::RationalFunction>>>(m, "ParametricCheckTask", "Task for parametric model checking")
//m.def("create_check_task", &storm::api::createTask, "Create task for verification", py::arg("formula"), py::arg("only_initial_states") = false);
.def(py::init<storm::logic::Formula const&, bool>(), py::arg("formula"), py::arg("only_initial_states") = false)
@ -73,8 +79,10 @@ void define_modelchecking(py::module& m) {
;
// Model checking
m.def("model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine<double>, py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
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());
m.def("_model_checking_sparse_engine", &modelCheckingSparseEngine<double>, "Perform model checking using the sparse engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
m.def("_exact_model_checking_sparse_engine", &modelCheckingSparseEngine<storm::RationalNumber>, "Perform model checking using the sparse engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
m.def("_parametric_model_checking_sparse_engine", &modelCheckingSparseEngine<storm::RationalFunction>, "Perform parametric model checking using the sparse engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
m.def("_model_checking_dd_engine", &modelCheckingDdEngine<storm::dd::DdType::Sylvan, double>, "Perform model checking using the dd engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());
m.def("_parametric_model_checking_dd_engine", &modelCheckingDdEngine<storm::dd::DdType::Sylvan, storm::RationalFunction>, "Perform parametric model checking using the dd engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment());

23
src/core/simulator.cpp

@ -1,14 +1,17 @@
#include "simulator.h"
#include <storm/simulator/DiscreteTimeSparseModelSimulator.h>
void define_sparse_model_simulator(py::module& m) {
py::class_<storm::simulator::DiscreteTimeSparseModelSimulator<double>> dtsmsd(m, "_DiscreteTimeSparseModelSimulatorDouble", "Simulator for sparse discrete-time models in memory (ValueType = double)");
dtsmsd.def(py::init<storm::models::sparse::Model<double> const&>());
dtsmsd.def("set_seed", &storm::simulator::DiscreteTimeSparseModelSimulator<double>::setSeed, py::arg("seed"));
dtsmsd.def("step", &storm::simulator::DiscreteTimeSparseModelSimulator<double>::step, py::arg("action"));
dtsmsd.def("random_step", &storm::simulator::DiscreteTimeSparseModelSimulator<double>::randomStep);
dtsmsd.def("get_last_reward", &storm::simulator::DiscreteTimeSparseModelSimulator<double>::getLastRewards);
dtsmsd.def("get_current_state", &storm::simulator::DiscreteTimeSparseModelSimulator<double>::getCurrentState);
dtsmsd.def("reset_to_initial_state", &storm::simulator::DiscreteTimeSparseModelSimulator<double>::resetToInitial);
template<typename ValueType>
void define_sparse_model_simulator(py::module& m, std::string const& vtSuffix) {
py::class_<storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>> dtsmsd(m, ("_DiscreteTimeSparseModelSimulator" + vtSuffix).c_str(), "Simulator for sparse discrete-time models in memory (ValueType = double)");
dtsmsd.def(py::init<storm::models::sparse::Model<ValueType> const&>());
dtsmsd.def("set_seed", &storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>::setSeed, py::arg("seed"));
dtsmsd.def("step", &storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>::step, py::arg("action"));
dtsmsd.def("random_step", &storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>::randomStep);
dtsmsd.def("get_last_reward", &storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>::getLastRewards);
dtsmsd.def("get_current_state", &storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>::getCurrentState);
dtsmsd.def("reset_to_initial_state", &storm::simulator::DiscreteTimeSparseModelSimulator<ValueType>::resetToInitial);
}
}
template void define_sparse_model_simulator<double>(py::module& m, std::string const& vtSuffix);
template void define_sparse_model_simulator<storm::RationalNumber>(py::module& m, std::string const& vtSuffix);

3
src/core/simulator.h

@ -2,4 +2,5 @@
#include "common.h"
void define_sparse_model_simulator(py::module& m);
template<typename ValueType>
void define_sparse_model_simulator(py::module& m, std::string const& vtSuffix);

4
src/mod_core.cpp

@ -34,5 +34,7 @@ PYBIND11_MODULE(core, m) {
define_input(m);
define_graph_constraints(m);
define_transformation(m);
define_sparse_model_simulator(m);
define_sparse_model_simulator<double>(m, "Double");
define_sparse_model_simulator<storm::RationalNumber>(m, "Exact");
}

5
src/mod_pomdp.cpp

@ -14,11 +14,14 @@ PYBIND11_MODULE(pomdp, m) {
py::options options;
options.disable_function_signatures();
#endif
define_tracker(m);
define_tracker<double>(m, "Double");
define_tracker<storm::RationalNumber>(m, "Exact");
define_qualitative_policy_search<double>(m, "Double");
define_qualitative_policy_search_nt(m);
define_memory(m);
define_transformations_nt(m);
define_transformations<double>(m, "Double");
define_transformations<storm::RationalNumber>(m, "Exact");
define_transformations<storm::RationalFunction>(m, "Rf");
}

18
src/mod_storage.cpp

@ -28,12 +28,19 @@ PYBIND11_MODULE(storage, m) {
define_bitvector(m);
define_dd<storm::dd::DdType::Sylvan>(m, "Sylvan");
define_dd_nt(m);
define_model(m);
define_sparse_model<double>(m, "");
define_sparse_model<storm::RationalNumber>(m, "Exact");
define_sparse_parametric_model(m);
define_statevaluation(m);
define_sparse_model(m);
define_sparse_matrix(m);
define_sparse_matrix<double>(m, "");
define_sparse_matrix<storm::RationalNumber>(m, "Exact");
define_sparse_matrix<storm::RationalFunction>(m, "Parametric");
define_sparse_matrix_nt(m);
define_symbolic_model<storm::dd::DdType::Sylvan>(m, "Sylvan");
define_state(m);
define_state<double>(m, "");
define_state<storm::RationalNumber>(m, "Exact");
define_prism(m);
define_jani(m);
define_jani_transformers(m);
@ -41,6 +48,9 @@ PYBIND11_MODULE(storage, m) {
define_origins(m);
define_expressions(m);
define_scheduler<double>(m, "Double");
define_scheduler<storm::RationalNumber>(m, "Exact");
define_distribution<double>(m, "Double");
define_sparse_model_components(m);
define_sparse_model_components<double>(m, "");
define_sparse_model_components<storm::RationalNumber>(m, "Exact");
}

59
src/pomdp/tracker.cpp

@ -7,39 +7,39 @@
template<typename ValueType> using SparsePomdp = storm::models::sparse::Pomdp<ValueType>;
template<typename ValueType> using SparsePomdpTracker = storm::generator::BeliefSupportTracker<ValueType>;
template<typename ValueType> using NDPomdpTrackerSparse = storm::generator::NondeterministicBeliefTracker<double, storm::generator::SparseBeliefState<double>>;
template<typename ValueType> using NDPomdpTrackerDense = storm::generator::NondeterministicBeliefTracker<double, storm::generator::ObservationDenseBeliefState<double>>;
void define_tracker(py::module& m) {
py::class_<storm::generator::BeliefSupportTracker<double>> tracker(m, "BeliefSupportTrackerDouble", "Tracker for BeliefSupports");
tracker.def(py::init<SparsePomdp<double> const&>(), py::arg("pomdp"));
tracker.def("get_current_belief_support", &SparsePomdpTracker<double>::getCurrentBeliefSupport, "What is the support given the trace so far");
tracker.def("track", &SparsePomdpTracker<double>::track, py::arg("action"), py::arg("observation"));
py::class_<storm::generator::SparseBeliefState<double>> sbel(m, "SparseBeliefStateDouble", "Belief state in sparse format");
sbel.def("get", &storm::generator::SparseBeliefState<double>::get, py::arg("state"));
sbel.def_property_readonly("risk", &storm::generator::SparseBeliefState<double>::getRisk);
sbel.def("__str__", &storm::generator::SparseBeliefState<double>::toString);
sbel.def_property_readonly("is_valid", &storm::generator::SparseBeliefState<double>::isValid);
template<typename ValueType> using NDPomdpTrackerSparse = storm::generator::NondeterministicBeliefTracker<ValueType, storm::generator::SparseBeliefState<ValueType>>;
template<typename ValueType> using NDPomdpTrackerDense = storm::generator::NondeterministicBeliefTracker<ValueType, storm::generator::ObservationDenseBeliefState<ValueType>>;
template<typename ValueType>
void define_tracker(py::module& m, std::string const& vtSuffix) {
py::class_<storm::generator::BeliefSupportTracker<ValueType>> tracker(m, ("BeliefSupportTracker" + vtSuffix).c_str(), "Tracker for BeliefSupports");
tracker.def(py::init<SparsePomdp<ValueType> const&>(), py::arg("pomdp"));
tracker.def("get_current_belief_support", &SparsePomdpTracker<ValueType>::getCurrentBeliefSupport, "What is the support given the trace so far");
tracker.def("track", &SparsePomdpTracker<ValueType>::track, py::arg("action"), py::arg("observation"));
py::class_<storm::generator::SparseBeliefState<ValueType>> sbel(m, ("SparseBeliefState" + vtSuffix).c_str(), "Belief state in sparse format");
sbel.def("get", &storm::generator::SparseBeliefState<ValueType>::get, py::arg("state"));
sbel.def_property_readonly("risk", &storm::generator::SparseBeliefState<ValueType>::getRisk);
sbel.def("__str__", &storm::generator::SparseBeliefState<ValueType>::toString);
sbel.def_property_readonly("is_valid", &storm::generator::SparseBeliefState<ValueType>::isValid);
//
// py::class_<storm::generator::ObservationDenseBeliefState<double>> dbel(m, "DenseBeliefStateDouble", "Belief state in dense format");
// dbel.def("get", &storm::generator::ObservationDenseBeliefState<double>::get, py::arg("state"));
// dbel.def_property_readonly("risk", &storm::generator::ObservationDenseBeliefState<double>::getRisk);
// dbel.def("__str__", &storm::generator::ObservationDenseBeliefState<double>::toString);
py::class_<NDPomdpTrackerSparse<double>> ndetbelieftracker(m, "NondeterministicBeliefTrackerDoubleSparse", "Tracker for belief states and uncontrollable actions");
ndetbelieftracker.def(py::init<SparsePomdp<double> const&>(), py::arg("pomdp"));
ndetbelieftracker.def("reset", &NDPomdpTrackerSparse<double>::reset);
ndetbelieftracker.def("set_risk", &NDPomdpTrackerSparse<double>::setRisk, py::arg("risk"));
ndetbelieftracker.def("obtain_current_risk",&NDPomdpTrackerSparse<double>::getCurrentRisk, py::arg("max")=true);
ndetbelieftracker.def("track", &NDPomdpTrackerSparse<double>::track, py::arg("observation"));
ndetbelieftracker.def("obtain_beliefs", &NDPomdpTrackerSparse<double>::getCurrentBeliefs);
ndetbelieftracker.def("size", &NDPomdpTrackerSparse<double>::getNumberOfBeliefs);
ndetbelieftracker.def("dimension", &NDPomdpTrackerSparse<double>::getCurrentDimension);
ndetbelieftracker.def("obtain_last_observation", &NDPomdpTrackerSparse<double>::getCurrentObservation);
ndetbelieftracker.def("reduce",&NDPomdpTrackerSparse<double>::reduce);
py::class_<NDPomdpTrackerSparse<ValueType>> ndetbelieftracker(m, ("NondeterministicBeliefTracker" + vtSuffix + "Sparse").c_str(), "Tracker for belief states and uncontrollable actions");
ndetbelieftracker.def(py::init<SparsePomdp<ValueType> const&>(), py::arg("pomdp"));
ndetbelieftracker.def("reset", &NDPomdpTrackerSparse<ValueType>::reset);
ndetbelieftracker.def("set_risk", &NDPomdpTrackerSparse<ValueType>::setRisk, py::arg("risk"));
ndetbelieftracker.def("obtain_current_risk",&NDPomdpTrackerSparse<ValueType>::getCurrentRisk, py::arg("max")=true);
ndetbelieftracker.def("track", &NDPomdpTrackerSparse<ValueType>::track, py::arg("observation"));
ndetbelieftracker.def("obtain_beliefs", &NDPomdpTrackerSparse<ValueType>::getCurrentBeliefs);
ndetbelieftracker.def("size", &NDPomdpTrackerSparse<ValueType>::getNumberOfBeliefs);
ndetbelieftracker.def("dimension", &NDPomdpTrackerSparse<ValueType>::getCurrentDimension);
ndetbelieftracker.def("obtain_last_observation", &NDPomdpTrackerSparse<ValueType>::getCurrentObservation);
ndetbelieftracker.def("reduce",&NDPomdpTrackerSparse<ValueType>::reduce);
// py::class_<NDPomdpTrackerDense<double>> ndetbelieftrackerd(m, "NondeterministicBeliefTrackerDoubleDense", "Tracker for belief states and uncontrollable actions");
// ndetbelieftrackerd.def(py::init<SparsePomdp<double> const&>(), py::arg("pomdp"));
@ -51,4 +51,7 @@ void define_tracker(py::module& m) {
// ndetbelieftrackerd.def("obtain_last_observation", &NDPomdpTrackerDense<double>::getCurrentObservation);
// ndetbelieftrackerd.def("reduce",&NDPomdpTrackerDense<double>::reduce);
}
}
template void define_tracker<double>(py::module& m, std::string const& vtSuffix);
template void define_tracker<storm::RationalNumber>(py::module& m, std::string const& vtSuffix);

3
src/pomdp/tracker.h

@ -1,4 +1,5 @@
#pragma once
#include "common.h"
void define_tracker(py::module& m);
template<typename ValueType>
void define_tracker(py::module& m, std::string const& vtSuffix);

14
src/pomdp/transformations.cpp

@ -46,13 +46,6 @@ void define_transformations_nt(py::module &m) {
.value("full", storm::transformer::PomdpFscApplicationMode::FULL)
;
py::class_<storm::pomdp::ObservationTraceUnfolder<double>> unfolder(m, "ObservationTraceUnfolderDouble", "Unfolds observation traces in models");
unfolder.def(py::init<storm::models::sparse::Pomdp<double> const&, std::vector<double> const&, std::shared_ptr<storm::expressions::ExpressionManager>&>(), py::arg("model"), py::arg("risk"), py::arg("expression_manager"));
unfolder.def("transform", &storm::pomdp::ObservationTraceUnfolder<double>::transform, py::arg("trace"));
unfolder.def("extend", &storm::pomdp::ObservationTraceUnfolder<double>::extend, py::arg("new_observation"));
unfolder.def("reset", &storm::pomdp::ObservationTraceUnfolder<double>::reset, py::arg("new_observation"));
}
template<typename ValueType>
@ -63,8 +56,13 @@ void define_transformations(py::module& m, std::string const& vtSuffix) {
m.def(("_apply_unknown_fsc_" + vtSuffix).c_str(), &apply_unknown_fsc<ValueType>, "Apply unknown FSC",py::arg("pomdp"), py::arg("application_mode")=storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR);
//m.def(("_unfold_trace_" + vtSuffix).c_str(), &unfold_trace<ValueType>, "Unfold observed trace", py::arg("pomdp"), py::arg("expression_manager"),py::arg("observation_trace"), py::arg("risk_definition"));
py::class_<storm::pomdp::ObservationTraceUnfolder<ValueType>> unfolder(m, ("ObservationTraceUnfolder" + vtSuffix).c_str(), "Unfolds observation traces in models");
unfolder.def(py::init<storm::models::sparse::Pomdp<ValueType> const&, std::vector<ValueType> const&, std::shared_ptr<storm::expressions::ExpressionManager>&>(), py::arg("model"), py::arg("risk"), py::arg("expression_manager"));
unfolder.def("transform", &storm::pomdp::ObservationTraceUnfolder<ValueType>::transform, py::arg("trace"));
unfolder.def("extend", &storm::pomdp::ObservationTraceUnfolder<ValueType>::extend, py::arg("new_observation"));
unfolder.def("reset", &storm::pomdp::ObservationTraceUnfolder<ValueType>::reset, py::arg("new_observation"));
}
template void define_transformations<double>(py::module& m, std::string const& vtSuffix);
template void define_transformations<storm::RationalNumber>(py::module& m, std::string const& vtSuffix);
template void define_transformations<storm::RationalFunction>(py::module& m, std::string const& vtSuffix);

4
src/storage/distribution.cpp

@ -1,3 +1,4 @@
#include <storm/adapters/RationalNumberAdapter.h>
#include "distribution.h"
#include "src/helpers.h"
@ -14,4 +15,5 @@ void define_distribution(py::module& m, std::string vt_suffix) {
}
template void define_distribution<double>(py::module&, std::string vt_suffix);
template void define_distribution<double>(py::module&, std::string vt_suffix);
template void define_distribution<storm::RationalNumber>(py::module&, std::string vt_suffix);

1
src/storage/jani.cpp

@ -140,6 +140,7 @@ void define_jani(py::module& m) {
py::class_<Variable, std::shared_ptr<Variable>> variable(m, "JaniVariable", "A Variable in JANI");
variable.def_property_readonly("name", &Variable::getName, "name of constant")
.def_property_readonly("expression_variable", &Variable::getExpressionVariable, "expression variable for this variable")
//.def_property_readonly("initial_value_expression", &Variable::getInitialValue)
;
py::class_<BoundedIntegerVariable, std::shared_ptr<BoundedIntegerVariable>> bivariable(m, "JaniBoundedIntegerVariable", "A Bounded Integer", variable);

187
src/storage/matrix.cpp

@ -12,30 +12,29 @@ template<typename ValueType> using MatrixEntry = storm::storage::MatrixEntry<ent
using RationalFunction = storm::RationalFunction;
using row_index = unsigned int;
void define_sparse_matrix(py::module& m) {
void define_sparse_matrix_nt(py::module& m) {
m.def("_topological_sort_double", [](SparseMatrix<double>& matrix, std::vector<uint64_t> initial) { return storm::utility::graph::getTopologicalSort(matrix, initial); }, "matrix"_a, "initial"_a, "get topological sort w.r.t. a transition matrix");
m.def("_topological_sort_rf", [](SparseMatrix<storm::RationalFunction>& matrix, std::vector<uint64_t> initial) { return storm::utility::graph::getTopologicalSort(matrix, initial); }, "matrix"_a, "initial"_a, "get topological sort w.r.t. a transition matrix");
}
template<typename ValueType>
void define_sparse_matrix(py::module& m, std::string const& vtSuffix) {
// MatrixEntry
py::class_<MatrixEntry<double>>(m, "SparseMatrixEntry", "Entry of sparse matrix")
.def("__str__", &streamToString<MatrixEntry<double>>)
py::class_<MatrixEntry<ValueType>>(m, (vtSuffix + "SparseMatrixEntry").c_str(), "Entry of sparse matrix")
.def("__str__", &streamToString<MatrixEntry<ValueType>>)
//def_property threw "pointer being freed not allocated" after exiting
.def("value", &MatrixEntry<double>::getValue, "Value")
.def("set_value", &MatrixEntry<double>::setValue, py::arg("value"), "Set value")
.def_property_readonly("column", &MatrixEntry<double>::getColumn, "Column")
.def("value", &MatrixEntry<ValueType>::getValue, "Value")
.def("set_value", &MatrixEntry<ValueType>::setValue, py::arg("value"), "Set value")
.def_property_readonly("column", &MatrixEntry<ValueType>::getColumn, "Column")
;
py::class_<MatrixEntry<RationalFunction>>(m, "ParametricSparseMatrixEntry", "Entry of parametric sparse matrix")
.def("__str__", &streamToString<MatrixEntry<RationalFunction>>)
//def_property threw "pointer being freed not allocated" after exiting
.def("value", &MatrixEntry<RationalFunction>::getValue, "Value")
.def("set_value", &MatrixEntry<RationalFunction>::setValue, py::arg("value"), "Set value")
.def_property_readonly("column", &MatrixEntry<RationalFunction>::getColumn, "Column")
;
// SparseMatrixBuilder
py::class_<SparseMatrixBuilder<double>>(m, "SparseMatrixBuilder", "Builder of sparse matrix")
py::class_<SparseMatrixBuilder<ValueType>>(m, ( vtSuffix + "SparseMatrixBuilder").c_str(), "Builder of sparse matrix")
.def(py::init<double, double, double, bool, bool, double>(), "rows"_a = 0, "columns"_a = 0, "entries"_a = 0, "force_dimensions"_a = true, "has_custom_row_grouping"_a = false, "row_groups"_a = 0)
.def("add_next_value", &SparseMatrixBuilder<double>::addNextValue, R"dox(
.def("add_next_value", &SparseMatrixBuilder<ValueType>::addNextValue, R"dox(
Sets the matrix entry at the given row and column to the given value. After all entries have been added,
calling function build() is mandatory.
@ -50,45 +49,12 @@ void define_sparse_matrix(py::module& m) {
:param double value: The value that is to be set at the specified row and column
)dox", py::arg("row"), py::arg("column"), py::arg("value"))
.def("new_row_group", &SparseMatrixBuilder<double>::newRowGroup, py::arg("starting_row"), "Start a new row group in the matrix")
.def("build", &SparseMatrixBuilder<double>::build, py::arg("overridden_row_count") = 0, py::arg("overridden_column_count") = 0, py::arg("overridden-row_group_count") = 0, "Finalize the sparse matrix")
.def("get_last_row", &SparseMatrixBuilder<double>::getLastRow, "Get the most recently used row")
.def("get_current_row_group_count", &SparseMatrixBuilder<double>::getCurrentRowGroupCount, "Get the current row group count")
.def("get_last_column", &SparseMatrixBuilder<double>::getLastColumn, "the most recently used column")
.def("replace_columns", &SparseMatrixBuilder<double>::replaceColumns, R"dox(
Replaces all columns with id >= offset according to replacements.
Every state with id offset+i is replaced by the id in replacements[i]. Afterwards the columns are sorted.
:param std::vector<double> const& replacements: replacements Mapping indicating the replacements from offset+i -> value of i
:param int offset: Offset to add to each id in vector index.
)dox", py::arg("replacements"), py::arg("offset"))
;
py::class_<SparseMatrixBuilder<RationalFunction>>(m, "ParametricSparseMatrixBuilder", "Builder of parametric sparse matrix")
.def(py::init<double, double, double, bool, bool, double>(), "rows"_a = 0, "columns"_a = 0, "entries"_a = 0, "force_dimensions"_a = true, "has_custom_row_grouping"_a = false, "row_groups"_a = 0)
.def("add_next_value", &SparseMatrixBuilder<RationalFunction>::addNextValue, R"dox(
Sets the matrix entry at the given row and column to the given value. After all entries have been added,
calling function build() is mandatory.
Note: this is a linear setter. That is, it must be called consecutively for each entry, row by row and
column by column. As multiple entries per column are admitted, consecutive calls to this method are
admitted to mention the same row-column-pair. If rows are skipped entirely, the corresponding rows are
treated as empty. If these constraints are not met, an exception is thrown.
:param double row: The row in which the matrix entry is to be set
:param double column: The column in which the matrix entry is to be set
:param RationalFunction value: The value that is to be set at the specified row and column
)dox", py::arg("row"), py::arg("column"), py::arg("value"))
.def("new_row_group", &SparseMatrixBuilder<RationalFunction>::newRowGroup, py::arg("starting_row"), "Start a new row group in the matrix")
.def("build", &SparseMatrixBuilder<RationalFunction>::build, py::arg("overridden_row_count") = 0, py::arg("overridden_column_count") = 0, py::arg("overridden-row_group_count") = 0, "Finalize the sparse matrix")
.def("get_last_row", &SparseMatrixBuilder<RationalFunction>::getLastRow, "Get the most recently used row")
.def("get_current_row_group_count", &SparseMatrixBuilder<RationalFunction>::getCurrentRowGroupCount, "Get the current row group count")
.def("get_last_column", &SparseMatrixBuilder<RationalFunction>::getLastColumn, "the most recently used column")
.def("replace_columns", &SparseMatrixBuilder<RationalFunction>::replaceColumns, R"dox(
.def("new_row_group", &SparseMatrixBuilder<ValueType>::newRowGroup, py::arg("starting_row"), "Start a new row group in the matrix")
.def("build", &SparseMatrixBuilder<ValueType>::build, py::arg("overridden_row_count") = 0, py::arg("overridden_column_count") = 0, py::arg("overridden-row_group_count") = 0, "Finalize the sparse matrix")
.def("get_last_row", &SparseMatrixBuilder<ValueType>::getLastRow, "Get the most recently used row")
.def("get_current_row_group_count", &SparseMatrixBuilder<ValueType>::getCurrentRowGroupCount, "Get the current row group count")
.def("get_last_column", &SparseMatrixBuilder<ValueType>::getLastColumn, "the most recently used column")
.def("replace_columns", &SparseMatrixBuilder<ValueType>::replaceColumns, R"dox(
Replaces all columns with id >= offset according to replacements.
Every state with id offset+i is replaced by the id in replacements[i]. Afterwards the columns are sorted.
@ -99,26 +65,26 @@ void define_sparse_matrix(py::module& m) {
;
// SparseMatrix
py::class_<SparseMatrix<double>>(m, "SparseMatrix", "Sparse matrix")
.def("__iter__", [](SparseMatrix<double>& matrix) {
py::class_<SparseMatrix<ValueType>>(m, (vtSuffix + "SparseMatrix").c_str(), "Sparse matrix")
.def("__iter__", [](SparseMatrix<ValueType>& matrix) {
return py::make_iterator(matrix.begin(), matrix.end());
}, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */)
.def("__str__", &streamToString<SparseMatrix<double>>)
.def_property_readonly("nr_rows", &SparseMatrix<double>::getRowCount, "Number of rows")
.def_property_readonly("nr_columns", &SparseMatrix<double>::getColumnCount, "Number of columns")
.def_property_readonly("nr_entries", &SparseMatrix<double>::getEntryCount, "Number of non-zero entries")
.def_property_readonly("_row_group_indices", &SparseMatrix<double>::getRowGroupIndices, "Starting rows of row groups")
.def("get_row_group_start", [](SparseMatrix<double>& matrix, entry_index<double> row) {return matrix.getRowGroupIndices()[row];})
.def("get_row_group_end", [](SparseMatrix<double>& matrix, entry_index<double> row) {return matrix.getRowGroupIndices()[row+1];})
.def_property_readonly("has_trivial_row_grouping", &SparseMatrix<double>::hasTrivialRowGrouping, "Trivial row grouping")
.def("get_row", [](SparseMatrix<double>& matrix, entry_index<double> row) {
.def("__str__", &streamToString<SparseMatrix<ValueType>>)
.def_property_readonly("nr_rows", &SparseMatrix<ValueType>::getRowCount, "Number of rows")
.def_property_readonly("nr_columns", &SparseMatrix<ValueType>::getColumnCount, "Number of columns")
.def_property_readonly("nr_entries", &SparseMatrix<ValueType>::getEntryCount, "Number of non-zero entries")
.def_property_readonly("_row_group_indices", &SparseMatrix<ValueType>::getRowGroupIndices, "Starting rows of row groups")
.def("get_row_group_start", [](SparseMatrix<ValueType>& matrix, entry_index<ValueType> row) {return matrix.getRowGroupIndices()[row];})
.def("get_row_group_end", [](SparseMatrix<ValueType>& matrix, entry_index<ValueType> row) {return matrix.getRowGroupIndices()[row+1];})
.def_property_readonly("has_trivial_row_grouping", &SparseMatrix<ValueType>::hasTrivialRowGrouping, "Trivial row grouping")
.def("get_row", [](SparseMatrix<ValueType>& matrix, entry_index<ValueType> row) {
return matrix.getRows(row, row+1);
}, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row"), "Get row")
.def("get_rows", [](SparseMatrix<double>& matrix, entry_index<double> start, entry_index<double> end) {
.def("get_rows", [](SparseMatrix<ValueType>& matrix, entry_index<ValueType> start, entry_index<ValueType> end) {
return matrix.getRows(start, end);
}, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row_start"), py::arg("row_end"), "Get rows from start to end")
.def("print_row", [](SparseMatrix<double> const& matrix, entry_index<double> row) {
.def("print_row", [](SparseMatrix<ValueType> const& matrix, entry_index<ValueType> row) {
std::stringstream stream;
auto rows = matrix.getRows(row, row+1);
for (auto transition : rows) {
@ -126,22 +92,22 @@ void define_sparse_matrix(py::module& m) {
}
return stream.str();
}, py::arg("row"), "Print rows from start to end")
.def("submatrix", [](SparseMatrix<double> const& matrix, storm::storage::BitVector const& rowConstraint, storm::storage::BitVector const& columnConstraint, bool insertDiagonalEntries = false) {
.def("submatrix", [](SparseMatrix<ValueType> const& matrix, storm::storage::BitVector const& rowConstraint, storm::storage::BitVector const& columnConstraint, bool insertDiagonalEntries = false) {
return matrix.getSubmatrix(true, rowConstraint, columnConstraint, insertDiagonalEntries);
}, py::arg("row_constraint"), py::arg("column_constraint"), py::arg("insert_diagonal_entries") = false, "Get submatrix")
// Entry_index lead to problems
.def("row_iter", [](SparseMatrix<double>& matrix, row_index start, row_index end) {
.def("row_iter", [](SparseMatrix<ValueType>& matrix, row_index start, row_index end) {
return py::make_iterator(matrix.begin(start), matrix.end(end));
}, py::keep_alive<0, 1>() /* keep object alive while iterator exists */, py::arg("row_start"), py::arg("row_end"), "Get iterator from start to end")
// (partial) container interface to allow e.g. matrix[7:9]
.def("__len__", &SparseMatrix<double>::getRowCount)
.def("__getitem__", [](SparseMatrix<double>& matrix, entry_index<double> i) {
.def("__len__", &SparseMatrix<ValueType>::getRowCount)
.def("__getitem__", [](SparseMatrix<ValueType>& matrix, entry_index<ValueType> i) {
if (i >= matrix.getRowCount())
throw py::index_error();
return matrix.getRows(i, i+1);
}, py::return_value_policy::reference, py::keep_alive<1, 0>())
.def("__getitem__", [](SparseMatrix<double>& matrix, py::slice slice) {
.def("__getitem__", [](SparseMatrix<ValueType>& matrix, py::slice slice) {
size_t start, stop, step, slice_length;
if (!slice.compute(matrix.getRowCount(), &start, &stop, &step, &slice_length))
throw py::error_already_set();
@ -151,75 +117,18 @@ void define_sparse_matrix(py::module& m) {
}, py::return_value_policy::reference, py::keep_alive<1, 0>())
;
m.def("_topological_sort_double", [](SparseMatrix<double>& matrix, std::vector<uint64_t> initial) { return storm::utility::graph::getTopologicalSort(matrix, initial); }, "matrix"_a, "initial"_a, "get topological sort w.r.t. a transition matrix");
m.def("_topological_sort_rf", [](SparseMatrix<storm::RationalFunction>& matrix, std::vector<uint64_t> initial) { return storm::utility::graph::getTopologicalSort(matrix, initial); }, "matrix"_a, "initial"_a, "get topological sort w.r.t. a transition matrix");
py::class_<SparseMatrix<RationalFunction>>(m, "ParametricSparseMatrix", "Parametric sparse matrix")
.def("__iter__", [](SparseMatrix<RationalFunction>& matrix) {
return py::make_iterator(matrix.begin(), matrix.end());
}, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */)
.def("__str__", &streamToString<SparseMatrix<RationalFunction>>)
.def_property_readonly("nr_rows", &SparseMatrix<RationalFunction>::getRowCount, "Number of rows")
.def_property_readonly("nr_columns", &SparseMatrix<RationalFunction>::getColumnCount, "Number of columns")
.def_property_readonly("nr_entries", &SparseMatrix<RationalFunction>::getEntryCount, "Number of non-zero entries")
.def_property_readonly("_row_group_indices", &SparseMatrix<RationalFunction>::getRowGroupIndices, "Starting rows of row groups")
.def("get_row_group_start", [](SparseMatrix<RationalFunction>& matrix, entry_index<RationalFunction> row) {return matrix.getRowGroupIndices()[row];})
.def("get_row_group_end", [](SparseMatrix<RationalFunction>& matrix, entry_index<RationalFunction> row) {return matrix.getRowGroupIndices()[row+1];})
.def_property_readonly("has_trivial_row_grouping", &SparseMatrix<RationalFunction>::hasTrivialRowGrouping, "Trivial row grouping")
.def("get_row", [](SparseMatrix<RationalFunction>& matrix, entry_index<RationalFunction> row) {
return matrix.getRows(row, row+1);
}, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row"), "Get row")
.def("get_rows", [](SparseMatrix<RationalFunction>& matrix, entry_index<storm::RationalFunction> start, entry_index<storm::RationalFunction> end) {
return matrix.getRows(start, end);
}, py::return_value_policy::reference, py::keep_alive<1, 0>(), py::arg("row_start"), py::arg("row_end"), "Get rows from start to end")
.def("print_row", [](SparseMatrix<RationalFunction> const& matrix, entry_index<storm::RationalFunction> row) {
std::stringstream stream;
auto rows = matrix.getRows(row, row+1);
for (auto transition : rows) {
stream << transition << ", ";
}
return stream.str();
}, py::arg("row"), "Print row")
.def("submatrix", [](SparseMatrix<RationalFunction> const& matrix, storm::storage::BitVector const& rowConstraint, storm::storage::BitVector const& columnConstraint, bool insertDiagonalEntries = false) {
return matrix.getSubmatrix(true, rowConstraint, columnConstraint, insertDiagonalEntries);
}, py::arg("row_constraint"), py::arg("column_constraint"), py::arg("insert_diagonal_entries") = false, "Get submatrix")
// Entry_index lead to problems
.def("row_iter", [](SparseMatrix<RationalFunction>& matrix, row_index start, row_index end) {
return py::make_iterator(matrix.begin(start), matrix.end(end));
}, py::keep_alive<0, 1>() /* keep object alive while iterator exists */, py::arg("row_start"), py::arg("row_end"), "Get iterator from start to end")
// (partial) container interface to allow e.g. matrix[7:9]
.def("__len__", &SparseMatrix<RationalFunction>::getRowCount)
.def("__getitem__", [](SparseMatrix<RationalFunction>& matrix, entry_index<RationalFunction> i) {
if (i >= matrix.getRowCount())
throw py::index_error();
return matrix.getRows(i, i+1);
}, py::return_value_policy::reference, py::keep_alive<1, 0>())
.def("__getitem__", [](SparseMatrix<RationalFunction>& matrix, py::slice slice) {
size_t start, stop, step, slice_length;
if (!slice.compute(matrix.getRowCount(), &start, &stop, &step, &slice_length))
throw py::error_already_set();
if (step != 1)
throw py::value_error(); // not supported
return matrix.getRows(start, stop);
}, py::return_value_policy::reference, py::keep_alive<1, 0>())
;
// Rows
py::class_<SparseMatrix<double>::rows>(m, "SparseMatrixRows", "Set of rows in a sparse matrix")
.def("__iter__", [](SparseMatrix<double>::rows& rows) {
return py::make_iterator(rows.begin(), rows.end());
}, py::keep_alive<0, 1>())
.def("__str__", &containerToString<SparseMatrix<double>::rows>)
.def("__len__", &storm::storage::SparseMatrix<double>::rows::getNumberOfEntries)
;
py::class_<SparseMatrix<RationalFunction>::rows>(m, "ParametricSparseMatrixRows", "Set of rows in a parametric sparse matrix")
.def("__iter__", [](SparseMatrix<RationalFunction>::rows& rows) {
py::class_<typename SparseMatrix<ValueType>::rows>(m, (vtSuffix + "SparseMatrixRows").c_str(), "Set of rows in a sparse matrix")
.def("__iter__", [](typename SparseMatrix<ValueType>::rows& rows) {
return py::make_iterator(rows.begin(), rows.end());
}, py::keep_alive<0, 1>())
.def("__str__", &containerToString<SparseMatrix<RationalFunction>::rows>)
.def("__len__", &storm::storage::SparseMatrix<storm::RationalFunction>::rows::getNumberOfEntries)
.def("__str__", &containerToString<typename SparseMatrix<ValueType>::rows>)
.def("__len__", &storm::storage::SparseMatrix<ValueType>::rows::getNumberOfEntries)
;
}
template void define_sparse_matrix<double>(py::module& m, std::string const& vtSuffix);
template void define_sparse_matrix<storm::RationalNumber>(py::module& m, std::string const& vtSuffix);
template void define_sparse_matrix<storm::RationalFunction>(py::module& m, std::string const& vtSuffix);

5
src/storage/matrix.h

@ -3,6 +3,9 @@
#include "common.h"
void define_sparse_matrix(py::module& m);
template<typename ValueType>
void define_sparse_matrix(py::module& m, std::string const& vtSuffix);
void define_sparse_matrix_nt(py::module& m);
#endif /* PYTHON_STORAGE_MATRIX_H_ */

140
src/storage/model.cpp

@ -115,12 +115,18 @@ void define_model(py::module& m) {
.def("_as_sparse_dtmc", [](ModelBase &modelbase) {
return modelbase.as<SparseDtmc<double>>();
}, "Get model as sparse DTMC")
.def("_as_sparse_exact_dtmc", [](ModelBase &modelbase) {
return modelbase.as<SparseDtmc<storm::RationalNumber>>();
}, "Get model as sparse DTMC")
.def("_as_sparse_pdtmc", [](ModelBase &modelbase) {
return modelbase.as<SparseDtmc<RationalFunction>>();
}, "Get model as sparse pDTMC")
.def("_as_sparse_mdp", [](ModelBase &modelbase) {
return modelbase.as<SparseMdp<double>>();
}, "Get model as sparse MDP")
.def("_as_sparse_exact_mdp", [](ModelBase &modelbase) {
return modelbase.as<SparseMdp<storm::RationalNumber>>();
}, "Get model as sparse exact MDP")
.def("_as_sparse_pmdp", [](ModelBase &modelbase) {
return modelbase.as<SparseMdp<RationalFunction>>();
}, "Get model as sparse pMDP")
@ -171,90 +177,94 @@ void define_model(py::module& m) {
// Bindings for sparse models
void define_sparse_model(py::module& m) {
template<typename ValueType>
void define_sparse_model(py::module& m, std::string const& vtSuffix) {
// Models with double numbers
py::class_<SparseModel<double>, std::shared_ptr<SparseModel<double>>, ModelBase> model(m, "_SparseModel", "A probabilistic model where transitions are represented by doubles and saved in a sparse matrix");
model.def_property_readonly("labeling", &getLabeling<double>, "Labels")
.def("has_choice_labeling", [](SparseModel<double> const& model) {return model.hasChoiceLabeling();}, "Does the model have an associated choice labelling?")
.def_property_readonly("choice_labeling", [](SparseModel<double> const& model) {return model.getChoiceLabeling();}, "get choice labelling")
.def("has_choice_origins", [](SparseModel<double> const& model) {return model.hasChoiceOrigins();}, "has choice origins?")
.def_property_readonly("choice_origins", [](SparseModel<double> const& model) {return model.getChoiceOrigins();})
.def("labels_state", &SparseModel<double>::getLabelsOfState, py::arg("state"), "Get labels of state")
.def_property_readonly("initial_states", &getSparseInitialStates<double>, "Initial states")
.def_property_readonly("states", [](SparseModel<double>& model) {
return SparseModelStates<double>(model);
py::class_<SparseModel<ValueType>, std::shared_ptr<SparseModel<ValueType>>, ModelBase> model(m, ("_Sparse" + vtSuffix + "Model").c_str(),
"A probabilistic model where transitions are represented by doubles and saved in a sparse matrix");
model.def_property_readonly("labeling", &getLabeling<ValueType>, "Labels")
.def("has_choice_labeling", [](SparseModel<ValueType> const& model) {return model.hasChoiceLabeling();}, "Does the model have an associated choice labelling?")
.def_property_readonly("choice_labeling", [](SparseModel<ValueType> const& model) {return model.getChoiceLabeling();}, "get choice labelling")
.def("has_choice_origins", [](SparseModel<ValueType> const& model) {return model.hasChoiceOrigins();}, "has choice origins?")
.def_property_readonly("choice_origins", [](SparseModel<ValueType> const& model) {return model.getChoiceOrigins();})
.def("labels_state", &SparseModel<ValueType>::getLabelsOfState, py::arg("state"), "Get labels of state")
.def_property_readonly("initial_states", &getSparseInitialStates<ValueType>, "Initial states")
.def_property_readonly("states", [](SparseModel<ValueType>& model) {
return SparseModelStates<ValueType>(model);
}, "Get states")
.def_property_readonly("reward_models", [](SparseModel<double>& model) {return model.getRewardModels(); }, "Reward models")
.def_property_readonly("transition_matrix", &getTransitionMatrix<double>, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Transition matrix")
.def_property_readonly("backward_transition_matrix", &SparseModel<double>::getBackwardTransitions, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Backward transition matrix")
.def("get_reward_model", [](SparseModel<double>& model, std::string const& name) {return model.getRewardModel(name);}, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Reward model")
.def("has_state_valuations", [](SparseModel<double> const& model) {return model.hasStateValuations();}, "has state valuation?")
.def_property_readonly("state_valuations", [](SparseModel<double> const& model) {return model.getStateValuations();}, "state valuations")
.def("reduce_to_state_based_rewards", &SparseModel<double>::reduceToStateBasedRewards)
.def("is_sink_state", &SparseModel<double>::isSinkState, py::arg("state"))
.def_property_readonly("reward_models", [](SparseModel<ValueType>& model) {return model.getRewardModels(); }, "Reward models")
.def_property_readonly("transition_matrix", &getTransitionMatrix<ValueType>, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Transition matrix")
.def_property_readonly("backward_transition_matrix", &SparseModel<ValueType>::getBackwardTransitions, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Backward transition matrix")
.def("get_reward_model", [](SparseModel<ValueType>& model, std::string const& name) {return model.getRewardModel(name);}, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Reward model")
.def("has_state_valuations", [](SparseModel<ValueType> const& model) {return model.hasStateValuations();}, "has state valuation?")
.def_property_readonly("state_valuations", [](SparseModel<ValueType> const& model) {return model.getStateValuations();}, "state valuations")
.def("reduce_to_state_based_rewards", &SparseModel<ValueType>::reduceToStateBasedRewards)
.def("is_sink_state", &SparseModel<ValueType>::isSinkState, py::arg("state"))
.def("__str__", &getModelInfoPrinter)
.def("to_dot", [](SparseModel<double>& model) { std::stringstream ss; model.writeDotToStream(ss); return ss.str(); }, "Write dot to a string")
.def("to_dot", [](SparseModel<ValueType>& model) { std::stringstream ss; model.writeDotToStream(ss); return ss.str(); }, "Write dot to a string")
;
py::class_<SparseDtmc<double>, std::shared_ptr<SparseDtmc<double>>>(m, "SparseDtmc", "DTMC in sparse representation", model)
.def(py::init<SparseDtmc<double>>(), py::arg("other_model"))
.def(py::init<ModelComponents<double> const&>(), py::arg("components"))
py::class_<SparseDtmc<ValueType>, std::shared_ptr<SparseDtmc<ValueType>>>(m, ("Sparse" + vtSuffix + "Dtmc").c_str(), "DTMC in sparse representation", model)
.def(py::init<SparseDtmc<ValueType>>(), py::arg("other_model"))
.def(py::init<ModelComponents<ValueType> const&>(), py::arg("components"))
.def("__str__", &getModelInfoPrinter)
;
py::class_<SparseMdp<double>, std::shared_ptr<SparseMdp<double>>> mdp(m, "SparseMdp", "MDP in sparse representation", model);
mdp.def(py::init<SparseMdp<double>>(), py::arg("other_model"))
.def(py::init<ModelComponents<double> const&, storm::models::ModelType>(), py::arg("components"), py::arg("type")=storm::models::ModelType::Mdp)
.def_property_readonly("nondeterministic_choice_indices", [](SparseMdp<double> const& mdp) { return mdp.getNondeterministicChoiceIndices(); })
.def("get_nr_available_actions", [](SparseMdp<double> const& mdp, uint64_t stateIndex) { return mdp.getNondeterministicChoiceIndices()[stateIndex+1] - mdp.getNondeterministicChoiceIndices()[stateIndex] ; }, py::arg("state"))
.def("get_choice_index", [](SparseMdp<double> const& mdp, uint64_t state, uint64_t actOff) { return mdp.getNondeterministicChoiceIndices()[state]+actOff; }, py::arg("state"), py::arg("action_offset"), "gets the choice index for the offset action from the given state.")
.def("apply_scheduler", [](SparseMdp<double> const& mdp, storm::storage::Scheduler<double> const& scheduler, bool dropUnreachableStates) { return mdp.applyScheduler(scheduler, dropUnreachableStates); } , "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true)
py::class_<SparseMdp<ValueType>, std::shared_ptr<SparseMdp<ValueType>>> mdp(m, ("Sparse" + vtSuffix + "Mdp").c_str(), "MDP in sparse representation", model);
mdp.def(py::init<SparseMdp<ValueType>>(), py::arg("other_model"))
.def(py::init<ModelComponents<ValueType> const&, storm::models::ModelType>(), py::arg("components"), py::arg("type")=storm::models::ModelType::Mdp)
.def_property_readonly("nondeterministic_choice_indices", [](SparseMdp<ValueType> const& mdp) { return mdp.getNondeterministicChoiceIndices(); })
.def("get_nr_available_actions", [](SparseMdp<ValueType> const& mdp, uint64_t stateIndex) { return mdp.getNondeterministicChoiceIndices()[stateIndex+1] - mdp.getNondeterministicChoiceIndices()[stateIndex] ; }, py::arg("state"))
.def("get_choice_index", [](SparseMdp<ValueType> const& mdp, uint64_t state, uint64_t actOff) { return mdp.getNondeterministicChoiceIndices()[state]+actOff; }, py::arg("state"), py::arg("action_offset"), "gets the choice index for the offset action from the given state.")
.def("apply_scheduler", [](SparseMdp<ValueType> const& mdp, storm::storage::Scheduler<ValueType> const& scheduler, bool dropUnreachableStates) { return mdp.applyScheduler(scheduler, dropUnreachableStates); } , "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true)
.def("__str__", &getModelInfoPrinter)
;
py::class_<SparsePomdp<double>, std::shared_ptr<SparsePomdp<double>>>(m, "SparsePomdp", "POMDP in sparse representation", mdp)
.def(py::init<SparsePomdp<double>>(), py::arg("other_model"))
.def(py::init<ModelComponents<double> const&, bool>(), py::arg("components"), py::arg("canonic_flag")=false)
py::class_<SparsePomdp<ValueType>, std::shared_ptr<SparsePomdp<ValueType>>>(m, ("Sparse" + vtSuffix + "Pomdp").c_str(), "POMDP in sparse representation", mdp)
.def(py::init<SparsePomdp<ValueType>>(), py::arg("other_model"))
.def(py::init<ModelComponents<ValueType> const&, bool>(), py::arg("components"), py::arg("canonic_flag")=false)
.def("__str__", &getModelInfoPrinter)
.def("get_observation", &SparsePomdp<double>::getObservation, py::arg("state"))
.def_property_readonly("observations", &SparsePomdp<double>::getObservations)
.def_property_readonly("nr_observations", &SparsePomdp<double>::getNrObservations)
.def("has_observation_valuations", &SparsePomdp<double>::hasObservationValuations)
.def_property_readonly("observation_valuations", &SparsePomdp<double>::getObservationValuations)
.def("get_observation", &SparsePomdp<ValueType>::getObservation, py::arg("state"))
.def_property_readonly("observations", &SparsePomdp<ValueType>::getObservations)
.def_property_readonly("nr_observations", &SparsePomdp<ValueType>::getNrObservations)
.def("has_observation_valuations", &SparsePomdp<ValueType>::hasObservationValuations)
.def_property_readonly("observation_valuations", &SparsePomdp<ValueType>::getObservationValuations)
;
py::class_<SparseCtmc<double>, std::shared_ptr<SparseCtmc<double>>>(m, "SparseCtmc", "CTMC in sparse representation", model)
.def(py::init<SparseCtmc<double>>(), py::arg("other_model"))
.def(py::init<ModelComponents<double> const&>(), py::arg("components"))
.def_property_readonly("exit_rates", [](SparseCtmc<double> const& ctmc) { return ctmc.getExitRateVector(); })
py::class_<SparseCtmc<ValueType>, std::shared_ptr<SparseCtmc<ValueType>>>(m, ("Sparse" + vtSuffix + "Ctmc").c_str(), "CTMC in sparse representation", model)
.def(py::init<SparseCtmc<ValueType>>(), py::arg("other_model"))
.def(py::init<ModelComponents<ValueType> const&>(), py::arg("components"))
.def_property_readonly("exit_rates", [](SparseCtmc<ValueType> const& ctmc) { return ctmc.getExitRateVector(); })
.def("__str__", &getModelInfoPrinter)
;
py::class_<SparseMarkovAutomaton<double>, std::shared_ptr<SparseMarkovAutomaton<double>>>(m, "SparseMA", "MA in sparse representation", model)
.def(py::init<SparseMarkovAutomaton<double>>(), py::arg("other_model"))
.def(py::init<ModelComponents<double> const&>(), py::arg("components"))
.def_property_readonly("exit_rates", [](SparseMarkovAutomaton<double> const& ma) { return ma.getExitRates(); })
.def_property_readonly("markovian_states", [](SparseMarkovAutomaton<double> const& ma) { return ma.getMarkovianStates(); })
.def_property_readonly("nondeterministic_choice_indices", [](SparseMarkovAutomaton<double> const& ma) { return ma.getNondeterministicChoiceIndices(); })
.def("apply_scheduler", [](SparseMarkovAutomaton<double> const& ma, storm::storage::Scheduler<double> const& scheduler, bool dropUnreachableStates) { return ma.applyScheduler(scheduler, dropUnreachableStates); } , "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true)
py::class_<SparseMarkovAutomaton<ValueType>, std::shared_ptr<SparseMarkovAutomaton<ValueType>>>(m, ("Sparse" + vtSuffix + "MA").c_str(), "MA in sparse representation", model)
.def(py::init<SparseMarkovAutomaton<ValueType>>(), py::arg("other_model"))
.def(py::init<ModelComponents<ValueType> const&>(), py::arg("components"))
.def_property_readonly("exit_rates", [](SparseMarkovAutomaton<ValueType> const& ma) { return ma.getExitRates(); })
.def_property_readonly("markovian_states", [](SparseMarkovAutomaton<ValueType> const& ma) { return ma.getMarkovianStates(); })
.def_property_readonly("nondeterministic_choice_indices", [](SparseMarkovAutomaton<ValueType> const& ma) { return ma.getNondeterministicChoiceIndices(); })
.def("apply_scheduler", [](SparseMarkovAutomaton<ValueType> const& ma, storm::storage::Scheduler<ValueType> const& scheduler, bool dropUnreachableStates) { return ma.applyScheduler(scheduler, dropUnreachableStates); } , "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true)
.def("__str__", &getModelInfoPrinter)
.def_property_readonly("convertible_to_ctmc", &SparseMarkovAutomaton<double>::isConvertibleToCtmc, "Check whether the MA can be converted into a CTMC.")
.def("convert_to_ctmc", &SparseMarkovAutomaton<double>::convertToCtmc, "Convert the MA into a CTMC.")
.def_property_readonly("convertible_to_ctmc", &SparseMarkovAutomaton<ValueType>::isConvertibleToCtmc, "Check whether the MA can be converted into a CTMC.")
.def("convert_to_ctmc", &SparseMarkovAutomaton<ValueType>::convertToCtmc, "Convert the MA into a CTMC.")
;
py::class_<SparseRewardModel<double>>(m, "SparseRewardModel", "Reward structure for sparse models")
.def(py::init<boost::optional<std::vector<double>> const&, boost::optional<std::vector<double>> const&,
boost::optional<storm::storage::SparseMatrix<double>> const&>(), py::arg("optional_state_reward_vector") = boost::none,
py::class_<SparseRewardModel<ValueType>>(m, ("Sparse" + vtSuffix + "RewardModel").c_str(), "Reward structure for sparse models")
.def(py::init<boost::optional<std::vector<ValueType>> const&, boost::optional<std::vector<ValueType>> const&,
boost::optional<storm::storage::SparseMatrix<ValueType>> const&>(), py::arg("optional_state_reward_vector") = boost::none,
py::arg("optional_state_action_reward_vector") = boost::none, py::arg("optional_transition_reward_matrix") = boost::none)
.def_property_readonly("has_state_rewards", &SparseRewardModel<double>::hasStateRewards)
.def_property_readonly("has_state_action_rewards", &SparseRewardModel<double>::hasStateActionRewards)
.def_property_readonly("has_transition_rewards", &SparseRewardModel<double>::hasTransitionRewards)
.def_property_readonly("transition_rewards", [](SparseRewardModel<double>& rewardModel) {return rewardModel.getTransitionRewardMatrix();})
.def_property_readonly("state_rewards", [](SparseRewardModel<double>& rewardModel) {return rewardModel.getStateRewardVector();})
.def("get_state_reward", [](SparseRewardModel<double>& rewardModel, uint64_t state) {return rewardModel.getStateReward(state);})
.def("get_zero_reward_states", &SparseRewardModel<double>::getStatesWithZeroReward<double>, "get states where all rewards are zero", py::arg("transition_matrix"))
.def("get_state_action_reward", [](SparseRewardModel<double>& rewardModel, uint64_t action_index) {return rewardModel.getStateActionReward(action_index);})
.def_property_readonly("state_action_rewards", [](SparseRewardModel<double>& rewardModel) {return rewardModel.getStateActionRewardVector();})
.def("reduce_to_state_based_rewards", [](SparseRewardModel<double>& rewardModel, storm::storage::SparseMatrix<double> const& transitions, bool onlyStateRewards){return rewardModel.reduceToStateBasedRewards(transitions, onlyStateRewards);}, py::arg("transition_matrix"), py::arg("only_state_rewards"), "Reduce to state-based rewards")
.def_property_readonly("has_state_rewards", &SparseRewardModel<ValueType>::hasStateRewards)
.def_property_readonly("has_state_action_rewards", &SparseRewardModel<ValueType>::hasStateActionRewards)
.def_property_readonly("has_transition_rewards", &SparseRewardModel<ValueType>::hasTransitionRewards)
.def_property_readonly("transition_rewards", [](SparseRewardModel<ValueType>& rewardModel) {return rewardModel.getTransitionRewardMatrix();})
.def_property_readonly("state_rewards", [](SparseRewardModel<ValueType>& rewardModel) {return rewardModel.getStateRewardVector();})
.def("get_state_reward", [](SparseRewardModel<ValueType>& rewardModel, uint64_t state) {return rewardModel.getStateReward(state);})
.def("get_zero_reward_states", &SparseRewardModel<ValueType>::template getStatesWithZeroReward<ValueType>, "get states where all rewards are zero", py::arg("transition_matrix"))
.def("get_state_action_reward", [](SparseRewardModel<ValueType>& rewardModel, uint64_t action_index) {return rewardModel.getStateActionReward(action_index);})
.def_property_readonly("state_action_rewards", [](SparseRewardModel<ValueType>& rewardModel) {return rewardModel.getStateActionRewardVector();})
.def("reduce_to_state_based_rewards", [](SparseRewardModel<ValueType>& rewardModel, storm::storage::SparseMatrix<ValueType> const& transitions, bool onlyStateRewards){return rewardModel.reduceToStateBasedRewards(transitions, onlyStateRewards);}, py::arg("transition_matrix"), py::arg("only_state_rewards"), "Reduce to state-based rewards")
;
}
void define_sparse_parametric_model(py::module& m) {
// Parametric models
py::class_<SparseModel<RationalFunction>, std::shared_ptr<SparseModel<RationalFunction>>, ModelBase> modelRatFunc(m, "_SparseParametricModel", "A probabilistic model where transitions are represented by rational functions and saved in a sparse matrix");
modelRatFunc.def("collect_probability_parameters", &probabilityVariables, "Collect parameters")
@ -393,3 +403,5 @@ void define_symbolic_model(py::module& m, std::string vt_suffix) {
}
template void define_symbolic_model<storm::dd::DdType::Sylvan>(py::module& m, std::string vt_suffix);
template void define_sparse_model<double>(py::module& m, std::string const& vt_suffix);
template void define_sparse_model<storm::RationalNumber>(py::module& m, std::string const& vt_suffix);

4
src/storage/model.h

@ -4,7 +4,9 @@
#include "storm/storage/dd/DdType.h"
void define_model(py::module& m);
void define_sparse_model(py::module& m);
template<typename ValueType>
void define_sparse_model(py::module& m, std::string const& vtSuffix);
void define_sparse_parametric_model(py::module& m);
template<storm::dd::DdType DdType>
void define_symbolic_model(py::module& m, std::string vt_suffix);

39
src/storage/model_components.cpp

@ -16,36 +16,39 @@ template<typename ValueType> using SparseRewardModel = storm::models::sparse::St
template<typename ValueType> using SparseModelComponents = storm::storage::sparse::ModelComponents<ValueType>;
// Parametric models, Valuetype: <storm::RationalFunction> todo
template<typename ValueType>
void define_sparse_model_components(py::module& m, std::string const& vtSuffix) {
void define_sparse_model_components(py::module& m) {
py::class_<SparseModelComponents<ValueType>, std::shared_ptr<SparseModelComponents<ValueType>>>(m, ("Sparse" + vtSuffix + "ModelComponents").c_str(), "Components required for building a sparse model")
py::class_<SparseModelComponents<double>, std::shared_ptr<SparseModelComponents<double>>>(m, "SparseModelComponents", "Components required for building a sparse model")
.def(py::init<SparseMatrix<double> const&, StateLabeling const&, std::unordered_map<std::string, SparseRewardModel<double>> const&,
.def(py::init<SparseMatrix<ValueType> const&, StateLabeling const&, std::unordered_map<std::string, SparseRewardModel<ValueType>> const&,
bool, boost::optional<BitVector> const&, boost::optional<SparseMatrix<storm::storage::sparse::state_type>> const&>(),
py::arg("transition_matrix") = SparseMatrix<double>(), py::arg("state_labeling") = storm::models::sparse::StateLabeling(),
py::arg("reward_models") = std::unordered_map<std::string, SparseRewardModel<double>>(), py::arg("rate_transitions") = false,
py::arg("transition_matrix") = SparseMatrix<ValueType>(), py::arg("state_labeling") = storm::models::sparse::StateLabeling(),
py::arg("reward_models") = std::unordered_map<std::string, SparseRewardModel<ValueType>>(), py::arg("rate_transitions") = false,
py::arg("markovian_states") = boost::none, py::arg("player1_matrix") = boost::none)
// General components (for all model types)
.def_readwrite("transition_matrix", &SparseModelComponents<double>::transitionMatrix, "The transition matrix")
.def_readwrite("state_labeling", &SparseModelComponents<double>::stateLabeling, "The state labeling")
.def_readwrite("reward_models", &SparseModelComponents<double>::rewardModels, "Reward models associated with the model")
.def_readwrite("choice_labeling", &SparseModelComponents<double>::choiceLabeling, "A list that stores a labeling for each choice")
.def_readwrite("state_valuations", &SparseModelComponents<double>::stateValuations, "A list that stores for each state to which variable valuation it belongs")
.def_readwrite("choice_origins", &SparseModelComponents<double>::choiceOrigins, "Stores for each choice from which parts of the input model description it originates")
.def_readwrite("transition_matrix", &SparseModelComponents<ValueType>::transitionMatrix, "The transition matrix")
.def_readwrite("state_labeling", &SparseModelComponents<ValueType>::stateLabeling, "The state labeling")
.def_readwrite("reward_models", &SparseModelComponents<ValueType>::rewardModels, "Reward models associated with the model")
.def_readwrite("choice_labeling", &SparseModelComponents<ValueType>::choiceLabeling, "A list that stores a labeling for each choice")
.def_readwrite("state_valuations", &SparseModelComponents<ValueType>::stateValuations, "A list that stores for each state to which variable valuation it belongs")
.def_readwrite("choice_origins", &SparseModelComponents<ValueType>::choiceOrigins, "Stores for each choice from which parts of the input model description it originates")
// POMDP specific components
.def_readwrite("observability_classes", &SparseModelComponents<double>::observabilityClasses, "The POMDP observations")
.def_readwrite("observability_classes", &SparseModelComponents<ValueType>::observabilityClasses, "The POMDP observations")
// Continuous time specific components (CTMCs, Markov Automata):
.def_readwrite("rate_transitions", &SparseModelComponents<double>::rateTransitions, "True iff the transition values (for Markovian choices) are interpreted as rates")
.def_readwrite("exit_rates", &SparseModelComponents<double>::exitRates, "The exit rate for each state. Must be given for CTMCs and MAs, if rate_transitions is false. Otherwise, it is optional.")
.def_readwrite("markovian_states", &SparseModelComponents<double>::markovianStates, "A list that stores which states are Markovian (only for Markov Automata)")
.def_readwrite("rate_transitions", &SparseModelComponents<ValueType>::rateTransitions, "True iff the transition values (for Markovian choices) are interpreted as rates")
.def_readwrite("exit_rates", &SparseModelComponents<ValueType>::exitRates, "The exit rate for each state. Must be given for CTMCs and MAs, if rate_transitions is false. Otherwise, it is optional.")
.def_readwrite("markovian_states", &SparseModelComponents<ValueType>::markovianStates, "A list that stores which states are Markovian (only for Markov Automata)")
// Stochastic two player game specific components:
.def_readwrite("player1_matrix", &SparseModelComponents<double>::observabilityClasses, "Matrix of player 1 choices (needed for stochastic two player games")
.def_readwrite("player1_matrix", &SparseModelComponents<ValueType>::observabilityClasses, "Matrix of player 1 choices (needed for stochastic two player games")
;
}
template void define_sparse_model_components<double>(py::module& m, std::string const& vtSuffix);
template void define_sparse_model_components<storm::RationalNumber>(py::module& m, std::string const& vtSuffix);

3
src/storage/model_components.h

@ -3,6 +3,7 @@
#include "common.h"
void define_sparse_model_components(py::module& m);
template<typename ValueType>
void define_sparse_model_components(py::module& m, std::string const& vtSuffix);
#endif /* PYTHON_STORAGE_SPARSEMODELCOMPONENTS_H */

3
src/storage/scheduler.cpp

@ -36,4 +36,5 @@ void define_scheduler(py::module& m, std::string vt_suffix) {
}
template void define_scheduler<double>(py::module& m, std::string vt_suffix);
template void define_scheduler<double>(py::module& m, std::string vt_suffix);
template void define_scheduler<storm::RationalNumber>(py::module& m, std::string vt_suffix);

64
src/storage/state.cpp

@ -1,51 +1,39 @@
#include "state.h"
void define_state(py::module& m) {
template<typename ValueType>
void define_state(py::module& m, std::string const& vtSuffix) {
// SparseModelStates
py::class_<SparseModelStates<double>>(m, "SparseModelStates", "States in sparse model")
.def("__getitem__", &SparseModelStates<double>::getState)
.def("__len__", &SparseModelStates<double>::getSize)
;
py::class_<SparseModelStates<storm::RationalFunction>>(m, "SparseParametricModelStates", "States in sparse parametric model")
.def("__getitem__", &SparseModelStates<storm::RationalFunction>::getState)
.def("__len__", &SparseModelStates<storm::RationalFunction>::getSize)
py::class_<SparseModelStates<ValueType>>(m, ("Sparse" + vtSuffix + "ModelStates").c_str(), "States in sparse model")
.def("__getitem__", &SparseModelStates<ValueType>::getState)
.def("__len__", &SparseModelStates<ValueType>::getSize)
;
// SparseModelState
py::class_<SparseModelState<double>>(m, "SparseModelState", "State in sparse model")
.def("__str__", &SparseModelState<double>::toString)
.def_property_readonly("id", &SparseModelState<double>::getIndex, "Id")
.def_property_readonly("labels", &SparseModelState<double>::getLabels, "Labels")
.def_property_readonly("actions", &SparseModelState<double>::getActions, "Get actions")
.def("__int__",&SparseModelState<double>::getIndex)
;
py::class_<SparseModelState<storm::RationalFunction>>(m, "SparseParametricModelState", "State in sparse parametric model")
.def("__str__", &SparseModelState<storm::RationalFunction>::toString)
.def_property_readonly("id", &SparseModelState<storm::RationalFunction>::getIndex, "Id")
.def_property_readonly("labels", &SparseModelState<storm::RationalFunction>::getLabels, "Labels")
.def_property_readonly("actions", &SparseModelState<storm::RationalFunction>::getActions, "Get actions")
.def("__int__",&SparseModelState<storm::RationalFunction>::getIndex)
py::class_<SparseModelState<ValueType>>(m, ("Sparse" + vtSuffix + "ModelState").c_str(), "State in sparse model")
.def("__str__", &SparseModelState<ValueType>::toString)
.def_property_readonly("id", &SparseModelState<ValueType>::getIndex, "Id")
.def_property_readonly("labels", &SparseModelState<ValueType>::getLabels, "Labels")
.def_property_readonly("actions", &SparseModelState<ValueType>::getActions, "Get actions")
.def("__int__",&SparseModelState<ValueType>::getIndex)
;
// SparseModelActions
py::class_<SparseModelActions<double>>(m, "SparseModelActions", "Actions for state in sparse model")
.def("__getitem__", &SparseModelActions<double>::getAction)
.def("__len__", &SparseModelActions<double>::getSize)
;
py::class_<SparseModelActions<storm::RationalFunction>>(m, "SparseParametricModelActions", "Actions for state in sparse parametric model")
.def("__getitem__", &SparseModelActions<storm::RationalFunction>::getAction)
.def("__len__", &SparseModelActions<storm::RationalFunction>::getSize)
py::class_<SparseModelActions<ValueType>>(m, ("Sparse" + vtSuffix + "ModelActions").c_str(), "Actions for state in sparse model")
.def("__getitem__", &SparseModelActions<ValueType>::getAction)
.def("__len__", &SparseModelActions<ValueType>::getSize)
;
// SparseModelAction
py::class_<SparseModelAction<double>>(m, "SparseModelAction", "Action for state in sparse model")
.def("__str__", &SparseModelAction<double>::toString)
.def_property_readonly("id", &SparseModelAction<double>::getIndex, "Id")
.def_property_readonly("transitions", &SparseModelAction<double>::getTransitions, "Get transitions")
;
py::class_<SparseModelAction<storm::RationalFunction>>(m, "SparseParametricModelAction", "Action for state in sparse parametric model")
.def("__str__", &SparseModelAction<storm::RationalFunction>::toString)
.def_property_readonly("id", &SparseModelAction<storm::RationalFunction>::getIndex, "Id")
.def_property_readonly("transitions", &SparseModelAction<storm::RationalFunction>::getTransitions, "Get transitions")
py::class_<SparseModelAction<ValueType>>(m, ("Sparse" + vtSuffix + "ModelAction").c_str(), "Action for state in sparse model")
.def("__str__", &SparseModelAction<ValueType>::toString)
.def_property_readonly("id", &SparseModelAction<ValueType>::getIndex, "Id")
.def_property_readonly("transitions", &SparseModelAction<ValueType>::getTransitions, "Get transitions")
;
}
template void define_state<double>(py::module& m, std::string const& vtSuffix);
template void define_state<storm::RationalNumber>(py::module& m, std::string const& vtSuffix);
template void define_state<storm::RationalFunction>(py::module& m, std::string const& vtSuffix);

3
src/storage/state.h

@ -125,6 +125,7 @@ class SparseModelActions {
storm::models::sparse::Model<ValueType>& model;
};
void define_state(py::module& m);
template<typename ValueType>
void define_state(py::module& m, std::string const& vtSuffix);
#endif /* PYTHON_STORAGE_STATE_H_ */
Loading…
Cancel
Save