From d3d0d3f399c918728db73c13a777fcee41bda4cc Mon Sep 17 00:00:00 2001 From: Auto Format Date: Tue, 10 Mar 2026 17:03:28 +0000 Subject: [PATCH 1/3] Applied code formatting for C++ --- src/boost.h | 10 +- src/common.h | 2 +- src/core/analysis.cpp | 14 +- src/core/bisimulation.cpp | 30 +- src/core/bisimulation.h | 1 - src/core/common.h | 2 +- src/core/core.cpp | 235 +++++--- src/core/counterexample.cpp | 97 +-- src/core/environment.cpp | 41 +- src/core/environment.h | 1 - src/core/input.cpp | 63 +- src/core/modelchecking.cpp | 159 +++-- src/core/modelchecking.h | 1 - src/core/result.cpp | 250 +++++--- src/core/result.h | 1 - src/core/simulator.cpp | 39 +- src/core/transformation.cpp | 106 ++-- src/dft/analysis.cpp | 64 +- src/dft/dft.cpp | 64 +- src/dft/dft_elements.cpp | 39 +- src/dft/dft_state.cpp | 51 +- src/dft/io.cpp | 15 +- src/dft/module.cpp | 4 +- src/dft/simulator.cpp | 37 +- src/dft/transformations.cpp | 7 +- src/gspn/gspn.cpp | 116 ++-- src/gspn/gspn.h | 2 - src/gspn/gspn_io.cpp | 22 +- src/gspn/gspn_io.h | 1 - src/helpers.h | 1 - src/logic/formulae.cpp | 192 +++--- src/mod_core.cpp | 13 +- src/mod_dft.cpp | 2 +- src/mod_info.cpp | 21 +- src/mod_pars.cpp | 2 +- src/mod_pomdp.cpp | 8 +- src/mod_storage.cpp | 17 +- src/mod_utility.cpp | 6 +- src/pars/common.h | 4 +- src/pars/model_instantiator.cpp | 230 ++++--- src/pars/pars.cpp | 56 +- src/pars/pla.cpp | 149 +++-- src/pomdp/memory.cpp | 23 +- src/pomdp/qualitative_analysis.cpp | 30 +- src/pomdp/quantitative_analysis.cpp | 42 +- src/pomdp/tracker.cpp | 54 +- src/pomdp/transformations.cpp | 51 +- src/pycarl/common.h | 36 +- src/pycarl/core/bound_type.cpp | 6 +- src/pycarl/core/monomial.cpp | 53 +- src/pycarl/core/variable.cpp | 84 +-- src/pycarl/formula/formula_type.cpp | 3 +- src/pycarl/formula/relation.cpp | 3 +- src/pycarl/helpers.h | 2 +- src/pycarl/mod_cln.cpp | 10 +- src/pycarl/mod_core.cpp | 4 +- src/pycarl/mod_formula.cpp | 12 +- src/pycarl/mod_gmp.cpp | 10 +- src/pycarl/mod_parse.cpp | 6 +- src/pycarl/mod_typed_formula.cpp | 14 +- src/pycarl/mod_typed_parse.cpp | 4 +- src/pycarl/typed_core/factorization.cpp | 38 +- .../typed_core/factorizedpolynomial.cpp | 47 +- src/pycarl/typed_core/factorizedpolynomial.h | 1 - .../typed_core/factorizedrationalfunction.cpp | 48 +- src/pycarl/typed_core/integer.cpp | 96 ++- src/pycarl/typed_core/interval.h | 213 ++++--- src/pycarl/typed_core/polynomial.cpp | 56 +- src/pycarl/typed_core/rational.cpp | 183 +++--- src/pycarl/typed_core/rationalfunction.cpp | 81 ++- src/pycarl/typed_core/term.cpp | 61 +- src/pycarl/typed_formula/common.h | 2 +- src/pycarl/typed_formula/constraint.cpp | 71 +-- src/pycarl/typed_formula/formula.cpp | 54 +- src/pycarl/typed_formula/types.h | 3 +- src/pycarl/typed_parse/parser.h | 6 +- src/pycarl/types.h | 4 +- src/pycarl/types/cln_types.h | 4 +- src/pycarl/types/gmp_types.h | 1 - src/storage/bitvector.cpp | 43 +- src/storage/choiceorigins.cpp | 49 +- src/storage/choiceorigins.h | 1 - src/storage/dd.cpp | 34 +- src/storage/decomposition.cpp | 27 +- src/storage/distribution.cpp | 4 +- src/storage/expressions.cpp | 182 +++--- src/storage/geometry.cpp | 11 +- src/storage/jani.cpp | 216 ++++--- src/storage/labeling.cpp | 47 +- src/storage/matrix.cpp | 136 +++-- src/storage/memorystructure.cpp | 24 +- src/storage/model.cpp | 565 ++++++++++-------- src/storage/model_components.cpp | 52 +- src/storage/prism.cpp | 535 +++++++++-------- src/storage/prism.h | 2 +- src/storage/scheduler.cpp | 48 +- src/storage/scheduler.h | 1 - src/storage/state.cpp | 14 +- src/storage/state.h | 210 ++++--- src/storage/valuation.cpp | 62 +- src/utility/chrono.cpp | 8 +- src/utility/json.cpp | 12 +- src/utility/shortestPaths.cpp | 46 +- src/utility/smtsolver.cpp | 42 +- 104 files changed, 3111 insertions(+), 2851 deletions(-) diff --git a/src/boost.h b/src/boost.h index 92e5e67b37..60b88871c2 100644 --- a/src/boost.h +++ b/src/boost.h @@ -6,11 +6,11 @@ namespace pybind11 { namespace detail { -template +template struct type_caster> : optional_caster> {}; -template<> struct type_caster - : public void_caster {}; +template<> +struct type_caster : public void_caster {}; -} -} +} // namespace detail +} // namespace pybind11 diff --git a/src/common.h b/src/common.h index da1e0f200d..b04792b8fd 100644 --- a/src/common.h +++ b/src/common.h @@ -2,8 +2,8 @@ #include "config.h" -#include #include +#include #include #include diff --git a/src/core/analysis.cpp b/src/core/analysis.cpp index 71d029eba8..685c2a2370 100644 --- a/src/core/analysis.cpp +++ b/src/core/analysis.cpp @@ -4,12 +4,12 @@ // Define python bindings void define_graph_constraints(py::module& m) { - // ConstraintCollector - py::class_, std::shared_ptr>>(m, "ConstraintCollector", "Collector for constraints on parametric Markov chains") - .def(py::init const&>(), py::arg("model")) - .def_property_readonly("wellformed_constraints", &storm::analysis::ConstraintCollector::getWellformedConstraints, "Get the constraints ensuring a wellformed model") - .def_property_readonly("graph_preserving_constraints", &storm::analysis::ConstraintCollector::getGraphPreservingConstraints, "Get the constraints ensuring the graph is preserved") - ; - + py::class_, std::shared_ptr>>( + m, "ConstraintCollector", "Collector for constraints on parametric Markov chains") + .def(py::init const&>(), py::arg("model")) + .def_property_readonly("wellformed_constraints", &storm::analysis::ConstraintCollector::getWellformedConstraints, + "Get the constraints ensuring a wellformed model") + .def_property_readonly("graph_preserving_constraints", &storm::analysis::ConstraintCollector::getGraphPreservingConstraints, + "Get the constraints ensuring the graph is preserved"); } diff --git a/src/core/bisimulation.cpp b/src/core/bisimulation.cpp index 62df91fc32..b123befde9 100644 --- a/src/core/bisimulation.cpp +++ b/src/core/bisimulation.cpp @@ -2,31 +2,33 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/models/symbolic/StandardRewardModel.h" - -template -std::shared_ptr> performBisimulationMinimization(std::shared_ptr> const& model, std::vector> const& formulas, storm::storage::BisimulationType const& bisimulationType, storm::dd::bisimulation::QuotientFormat const& quotientFormat) { - return storm::api::performBisimulationMinimization(model, formulas, bisimulationType, storm::dd::bisimulation::SignatureMode::Eager, quotientFormat); +template +std::shared_ptr> performBisimulationMinimization( + std::shared_ptr> const& model, std::vector> const& formulas, + storm::storage::BisimulationType const& bisimulationType, storm::dd::bisimulation::QuotientFormat const& quotientFormat) { + return storm::api::performBisimulationMinimization(model, formulas, bisimulationType, + storm::dd::bisimulation::SignatureMode::Eager, quotientFormat); } // Define python bindings void define_bisimulation(py::module& m) { - // Bisimulation - m.def("_perform_bisimulation", &storm::api::performBisimulationMinimization, "Perform bisimulation", py::arg("model"), py::arg("formulas"), py::arg("bisimulation_type"), py::arg("graph_preserving")); - m.def("_perform_parametric_bisimulation", &storm::api::performBisimulationMinimization, "Perform bisimulation on parametric model", py::arg("model"), py::arg("formulas"), py::arg("bisimulation_type"), py::arg("graph_preserving")); - m.def("_perform_symbolic_bisimulation", &performBisimulationMinimization, "Perform bisimulation", py::arg("model"), py::arg("formulas"), py::arg("bisimulation_type"), py::arg("quotient_format")); - m.def("_perform_symbolic_parametric_bisimulation", &performBisimulationMinimization, "Perform bisimulation on parametric model", py::arg("model"), py::arg("formulas"), py::arg("bisimulation_type"), py::arg("quotient_format")); + m.def("_perform_bisimulation", &storm::api::performBisimulationMinimization, "Perform bisimulation", py::arg("model"), py::arg("formulas"), + py::arg("bisimulation_type"), py::arg("graph_preserving")); + m.def("_perform_parametric_bisimulation", &storm::api::performBisimulationMinimization, "Perform bisimulation on parametric model", + py::arg("model"), py::arg("formulas"), py::arg("bisimulation_type"), py::arg("graph_preserving")); + m.def("_perform_symbolic_bisimulation", &performBisimulationMinimization, "Perform bisimulation", py::arg("model"), + py::arg("formulas"), py::arg("bisimulation_type"), py::arg("quotient_format")); + m.def("_perform_symbolic_parametric_bisimulation", &performBisimulationMinimization, + "Perform bisimulation on parametric model", py::arg("model"), py::arg("formulas"), py::arg("bisimulation_type"), py::arg("quotient_format")); // BisimulationType py::enum_(m, "BisimulationType", "Types of bisimulation") .value("STRONG", storm::storage::BisimulationType::Strong) - .value("WEAK", storm::storage::BisimulationType::Weak) - ; + .value("WEAK", storm::storage::BisimulationType::Weak); // QuotientFormat py::enum_(m, "QuotientFormat", "Return format of bisimulation quotient") .value("SPARSE", storm::dd::bisimulation::QuotientFormat::Sparse) - .value("DD", storm::dd::bisimulation::QuotientFormat::Dd) - ; - + .value("DD", storm::dd::bisimulation::QuotientFormat::Dd); } diff --git a/src/core/bisimulation.h b/src/core/bisimulation.h index cdff5d150f..3f2ada1e30 100644 --- a/src/core/bisimulation.h +++ b/src/core/bisimulation.h @@ -2,4 +2,3 @@ #include "common.h" void define_bisimulation(py::module& m); - diff --git a/src/core/common.h b/src/core/common.h index 19d6646576..7168e46f2e 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -1,5 +1,5 @@ #pragma once +#include #include "src/common.h" #include "storm/api/storm.h" -#include diff --git a/src/core/core.cpp b/src/core/core.cpp index b93e53f1b2..80e546a377 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -1,61 +1,61 @@ #include #include "core.h" +#include "storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.h" +#include "storm-parsers/api/storm-parsers.h" #include "storm/adapters/RationalFunctionAdapter.h" -#include "storm/utility/initialize.h" -#include "storm/utility/SignalHandler.h" -#include "storm/io/file.h" +#include "storm/generator/NextStateGenerator.h" #include "storm/io/DirectEncodingExporter.h" +#include "storm/io/file.h" +#include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/solver/OptimizationDirection.h" +#include "storm/solver/UncertaintyResolutionMode.h" #include "storm/storage/ModelFormulasPair.h" #include "storm/storage/dd/DdType.h" #include "storm/storage/jani/Property.h" -#include "storm/solver/OptimizationDirection.h" -#include "storm/solver/UncertaintyResolutionMode.h" -#include "storm/models/symbolic/StandardRewardModel.h" -#include "storm/generator/NextStateGenerator.h" -#include "storm-parsers/api/storm-parsers.h" -#include "storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.h" +#include "storm/utility/SignalHandler.h" +#include "storm/utility/initialize.h" void define_core(py::module& m) { // Init - m.def("_set_up", [](std::string const& args) { + m.def( + "_set_up", + [](std::string const& args) { storm::utility::setUp(); storm::settings::initializeAll("stormpy", "stormpy"); storm::settings::addModule(); storm::settings::mutableManager().setFromString(args); - }, "Initialize Storm", py::arg("arguments")); - m.def("set_settings", [](std::vector const& args) { - storm::settings::mutableManager().setFromExplodedString(args); - }, "Set settings", py::arg("arguments")); - m.def("set_loglevel_debug", []() { - storm::utility::setLogLevel(l3pp::LogLevel::DEBUG); - }, "set loglevel for storm to debug"); - m.def("set_loglevel_trace", []() { - storm::utility::setLogLevel(l3pp::LogLevel::TRACE); - }); - m.def("set_loglevel_error", []() { - storm::utility::setLogLevel(l3pp::LogLevel::ERR); - }); + }, + "Initialize Storm", py::arg("arguments")); + m.def( + "set_settings", [](std::vector const& args) { storm::settings::mutableManager().setFromExplodedString(args); }, "Set settings", + py::arg("arguments")); + m.def("set_loglevel_debug", []() { storm::utility::setLogLevel(l3pp::LogLevel::DEBUG); }, "set loglevel for storm to debug"); + m.def("set_loglevel_trace", []() { storm::utility::setLogLevel(l3pp::LogLevel::TRACE); }); + m.def("set_loglevel_error", []() { storm::utility::setLogLevel(l3pp::LogLevel::ERR); }); m.def("set_timeout", &storm::utility::resources::setTimeoutAlarm, py::arg("timeout"), "Set timeout in seconds"); m.def("reset_timeout", &storm::utility::resources::resetTimeoutAlarm, "Reset timeout"); m.def("install_signal_handlers", &storm::utility::resources::installSignalHandler); - } void define_parse(py::module& m) { // Parse formulas - m.def("parse_properties_without_context", [](std::string const& inputString, boost::optional> const& propertyFilter = boost::none) { - return storm::api::parseProperties(inputString, propertyFilter); - }, R"dox( + m.def( + "parse_properties_without_context", + [](std::string const& inputString, boost::optional> const& propertyFilter = boost::none) { + return storm::api::parseProperties(inputString, propertyFilter); + }, + R"dox( Parse properties given in the prism format. :param str formula_str: A string of formulas :param str property_filter: A filter :return: A list of properties - )dox", py::arg("formula_string"), py::arg("property_filter") = boost::none); - m.def("parse_properties_for_prism_program", &storm::api::parsePropertiesForPrismProgram, R"dox( + )dox", + py::arg("formula_string"), py::arg("property_filter") = boost::none); + m.def("parse_properties_for_prism_program", &storm::api::parsePropertiesForPrismProgram, R"dox( Parses properties given in the prism format, allows references to variables in the prism program. @@ -63,24 +63,23 @@ void define_parse(py::module& m) { :param PrismProgram prism_program: A prism program :param str property_filter: A filter :return: A list of properties - )dox", py::arg("formula_string"), py::arg("prism_program"), py::arg("property_filter") = boost::none); + )dox", + py::arg("formula_string"), py::arg("prism_program"), py::arg("property_filter") = boost::none); - m.def("parse_properties_for_jani_model", &storm::api::parsePropertiesForJaniModel, py::arg("formula_string"), py::arg("jani_model"), py::arg("property_filter") = boost::none); + m.def("parse_properties_for_jani_model", &storm::api::parsePropertiesForJaniModel, py::arg("formula_string"), py::arg("jani_model"), + py::arg("property_filter") = boost::none); // Pair py::class_(m, "ModelFormulasPair", "Pair of model and formulas") - .def_property_readonly("model", [](storm::storage::ModelFormulasPair const& pair) { - return pair.model; - }, "The model") - .def_property_readonly("formulas", [](storm::storage::ModelFormulasPair const& pair) { - return pair.formulas; - }, "The formulas") - ; + .def_property_readonly( + "model", [](storm::storage::ModelFormulasPair const& pair) { return pair.model; }, "The model") + .def_property_readonly("formulas", [](storm::storage::ModelFormulasPair const& pair) { return pair.formulas; }, "The formulas"); } // Thin wrapper for model building using sparse representation template -std::shared_ptr> buildSparseModel(storm::storage::SymbolicModelDescription const& modelDescription, std::vector> const& formulas) { +std::shared_ptr> buildSparseModel(storm::storage::SymbolicModelDescription const& modelDescription, + std::vector> const& formulas) { if (formulas.empty()) { // Build all labels and rewards storm::builder::BuilderOptions options(true, true); @@ -92,18 +91,21 @@ std::shared_ptr> buildSparseModel(storm: } template -std::shared_ptr buildSparseModelWithOptions(storm::storage::SymbolicModelDescription const& modelDescription, storm::builder::BuilderOptions const& options) { +std::shared_ptr buildSparseModelWithOptions(storm::storage::SymbolicModelDescription const& modelDescription, + storm::builder::BuilderOptions const& options) { return storm::api::buildSparseModel(modelDescription, options); } template -storm::builder::ExplicitModelBuilder makeExplicitModelBuilder(storm::storage::SymbolicModelDescription const& model, storm::builder::BuilderOptions const& options) { - return storm::api::makeExplicitModelBuilder(model, options, nullptr); // Do not set ActionMask +storm::builder::ExplicitModelBuilder makeExplicitModelBuilder(storm::storage::SymbolicModelDescription const& model, + storm::builder::BuilderOptions const& options) { + return storm::api::makeExplicitModelBuilder(model, options, nullptr); // Do not set ActionMask } // Thin wrapper for model building using symbolic representation template -std::shared_ptr> buildSymbolicModel(storm::storage::SymbolicModelDescription const& modelDescription, std::vector> const& formulas) { +std::shared_ptr> buildSymbolicModel( + storm::storage::SymbolicModelDescription const& modelDescription, std::vector> const& formulas) { if (formulas.empty()) { // Build full model return storm::api::buildSymbolicModel(modelDescription, formulas, true); @@ -114,80 +116,113 @@ std::shared_ptr> buildSymbolic } void define_build(py::module& m) { - py::class_(m, "DirectEncodingParserOptions", "Options for the .drn parser") - .def(py::init<>(), "initialise") - .def_readwrite("build_choice_labels", &storm::parser::DirectEncodingParserOptions::buildChoiceLabeling, "Build with choice labels"); + .def(py::init<>(), "initialise") + .def_readwrite("build_choice_labels", &storm::parser::DirectEncodingParserOptions::buildChoiceLabeling, "Build with choice labels"); // Build model - m.def("_build_sparse_model_from_symbolic_description", &buildSparseModel, "Build the model in sparse representation", py::arg("model_description"), py::arg("formulas") = std::vector>()); - m.def("_build_sparse_exact_model_from_symbolic_description", &buildSparseModel, "Build the model in sparse representation with exact number representation", py::arg("model_description"), py::arg("formulas") = std::vector>()); - m.def("_build_sparse_parametric_model_from_symbolic_description", &buildSparseModel, "Build the parametric model in sparse representation", py::arg("model_description"), py::arg("formulas") = std::vector>()); - m.def("_build_sparse_interval_model_from_symbolic_description", &buildSparseModel, "Build the interval model in sparse representation", py::arg("model_description"), py::arg("formulas") = std::vector>()); - m.def("build_sparse_model_with_options", &buildSparseModelWithOptions, "Build the model in sparse representation", py::arg("model_description"), py::arg("options")); - m.def("build_sparse_exact_model_with_options", &buildSparseModelWithOptions, "Build the model in sparse representation with exact number representation", py::arg("model_description"), py::arg("options")); - m.def("build_sparse_parametric_model_with_options", &buildSparseModelWithOptions, "Build the model in sparse representation", py::arg("model_description"), py::arg("options")); - m.def("build_sparse_interval_model_with_options", &buildSparseModelWithOptions, "Build the interval model in sparse representation", py::arg("model_description"), py::arg("options")); - m.def("_build_symbolic_model_from_symbolic_description", &buildSymbolicModel, "Build the model in symbolic representation", py::arg("model_description"), py::arg("formulas") = std::vector>()); - m.def("_build_symbolic_parametric_model_from_symbolic_description", &buildSymbolicModel, "Build the parametric model in symbolic representation", py::arg("model_description"), py::arg("formulas") = std::vector>()); - m.def("_build_sparse_model_from_drn", &storm::api::buildExplicitDRNModel, "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, "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, "Build the parametric model from DRN", py::arg("file"), py::arg("options") = storm::parser::DirectEncodingParserOptions()); - m.def("_build_sparse_interval_model_from_drn", &storm::api::buildExplicitDRNModel, "Build the interval model from DRN", py::arg("file"), py::arg("options") = storm::parser::DirectEncodingParserOptions()); - m.def("build_sparse_model_from_explicit", &storm::api::buildExplicitModel, "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, "Construct a builder instance", py::arg("model_description"), py::arg("options"), py::arg("action_mask") = nullptr); - m.def("make_sparse_model_builder_exact", &storm::api::makeExplicitModelBuilder, "Construct a builder instance", py::arg("model_description"), py::arg("options"), py::arg("action_mask") = nullptr); - m.def("make_sparse_model_builder_parametric", &storm::api::makeExplicitModelBuilder, "Construct a builder instance", py::arg("model_description"), py::arg("options"), py::arg("action_mask") = nullptr); + m.def("_build_sparse_model_from_symbolic_description", &buildSparseModel, "Build the model in sparse representation", py::arg("model_description"), + py::arg("formulas") = std::vector>()); + m.def("_build_sparse_exact_model_from_symbolic_description", &buildSparseModel, + "Build the model in sparse representation with exact number representation", py::arg("model_description"), + py::arg("formulas") = std::vector>()); + m.def("_build_sparse_parametric_model_from_symbolic_description", &buildSparseModel, + "Build the parametric model in sparse representation", py::arg("model_description"), + py::arg("formulas") = std::vector>()); + m.def("_build_sparse_interval_model_from_symbolic_description", &buildSparseModel, "Build the interval model in sparse representation", + py::arg("model_description"), py::arg("formulas") = std::vector>()); + m.def("build_sparse_model_with_options", &buildSparseModelWithOptions, "Build the model in sparse representation", py::arg("model_description"), + py::arg("options")); + m.def("build_sparse_exact_model_with_options", &buildSparseModelWithOptions, + "Build the model in sparse representation with exact number representation", py::arg("model_description"), py::arg("options")); + m.def("build_sparse_parametric_model_with_options", &buildSparseModelWithOptions, "Build the model in sparse representation", + py::arg("model_description"), py::arg("options")); + m.def("build_sparse_interval_model_with_options", &buildSparseModelWithOptions, "Build the interval model in sparse representation", + py::arg("model_description"), py::arg("options")); + m.def("_build_symbolic_model_from_symbolic_description", &buildSymbolicModel, + "Build the model in symbolic representation", py::arg("model_description"), + py::arg("formulas") = std::vector>()); + m.def("_build_symbolic_parametric_model_from_symbolic_description", &buildSymbolicModel, + "Build the parametric model in symbolic representation", py::arg("model_description"), + py::arg("formulas") = std::vector>()); + m.def("_build_sparse_model_from_drn", &storm::api::buildExplicitDRNModel, "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, "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, "Build the parametric model from DRN", + py::arg("file"), py::arg("options") = storm::parser::DirectEncodingParserOptions()); + m.def("_build_sparse_interval_model_from_drn", &storm::api::buildExplicitDRNModel, "Build the interval model from DRN", py::arg("file"), + py::arg("options") = storm::parser::DirectEncodingParserOptions()); + m.def("build_sparse_model_from_explicit", &storm::api::buildExplicitModel, "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, "Construct a builder instance", py::arg("model_description"), + py::arg("options"), py::arg("action_mask") = nullptr); + m.def("make_sparse_model_builder_exact", &storm::api::makeExplicitModelBuilder, "Construct a builder instance", + py::arg("model_description"), py::arg("options"), py::arg("action_mask") = nullptr); + m.def("make_sparse_model_builder_parametric", &storm::api::makeExplicitModelBuilder, "Construct a builder instance", + py::arg("model_description"), py::arg("options"), py::arg("action_mask") = nullptr); py::class_>(m, "ExplicitModelBuilder", "Model builder for sparse models") - .def("build", &storm::builder::ExplicitModelBuilder::build, "Build the model", py::call_guard()) - .def("export_lookup", &storm::builder::ExplicitModelBuilder::exportExplicitStateLookup, "Export a lookup model") - ; + .def("build", &storm::builder::ExplicitModelBuilder::build, "Build the model", py::call_guard()) + .def("export_lookup", &storm::builder::ExplicitModelBuilder::exportExplicitStateLookup, "Export a lookup model"); py::class_>(m, "ExplicitParametricModelBuilder", "Model builder for sparse models") .def("build", &storm::builder::ExplicitModelBuilder::build, "Build the model", py::call_guard()) - .def("export_lookup", &storm::builder::ExplicitModelBuilder::exportExplicitStateLookup, "Export a lookup model") - ; + .def("export_lookup", &storm::builder::ExplicitModelBuilder::exportExplicitStateLookup, "Export a lookup model"); py::class_>(m, "ExplicitStateLookup", "Lookup model for states") - .def("lookup", [](storm::builder::ExplicitStateLookupconst& lookup, std::map const& stateDescription) -> py::object - { auto res = lookup.lookup(stateDescription); if (res==lookup.size()) {return py::none();} else {return py::cast(res);}} , py::arg("state_description")) - - ; + .def( + "lookup", + [](storm::builder::ExplicitStateLookup const& lookup, + std::map const& stateDescription) -> py::object { + auto res = lookup.lookup(stateDescription); + if (res == lookup.size()) { + return py::none(); + } else { + return py::cast(res); + } + }, + py::arg("state_description")) + + ; py::class_(m, "BuilderOptions", "Options for building process") - .def(py::init> const&>(), "Initialise with formulae to preserve", py::arg("formulae")) - .def(py::init(), "Initialise without formulae", py::arg("build_all_reward_models")=true, py::arg("build_all_labels")=true) - .def_property_readonly("preserved_label_names", &storm::builder::BuilderOptions::getLabelNames, "Labels preserved") - .def("set_build_state_valuations", &storm::builder::BuilderOptions::setBuildStateValuations, "Build state valuations", py::arg("new_value")=true) - .def("set_build_observation_valuations", &storm::builder::BuilderOptions::setBuildObservationValuations, "Build observation valuations", py::arg("new_value")=true) - .def("set_build_with_choice_origins", &storm::builder::BuilderOptions::setBuildChoiceOrigins, "Build choice origins", py::arg("new_value")=true) - .def("set_add_out_of_bounds_state", &storm::builder::BuilderOptions::setAddOutOfBoundsState, "Build with out of bounds state", py::arg("new_value")=true) - .def("set_add_overlapping_guards_label", &storm::builder::BuilderOptions::setAddOverlappingGuardsLabel, "Build with overlapping guards state labeled", py::arg("new_value")=true) - .def("set_build_choice_labels", &storm::builder::BuilderOptions::setBuildChoiceLabels, "Build with choice labels", py::arg("new_value")=true) - .def("set_exploration_checks", &storm::builder::BuilderOptions::setExplorationChecks, "Perform extra checks during exploration", py::arg("new_value")=true) - .def("set_build_all_labels" , &storm::builder::BuilderOptions::setBuildAllLabels, "Build with all state labels", py::arg("new_value")=true) - .def("set_build_all_reward_models", &storm::builder::BuilderOptions::setBuildAllRewardModels, "Build with all reward models", py::arg("new_value")=true); + .def(py::init> const&>(), "Initialise with formulae to preserve", py::arg("formulae")) + .def(py::init(), "Initialise without formulae", py::arg("build_all_reward_models") = true, py::arg("build_all_labels") = true) + .def_property_readonly("preserved_label_names", &storm::builder::BuilderOptions::getLabelNames, "Labels preserved") + .def("set_build_state_valuations", &storm::builder::BuilderOptions::setBuildStateValuations, "Build state valuations", py::arg("new_value") = true) + .def("set_build_observation_valuations", &storm::builder::BuilderOptions::setBuildObservationValuations, "Build observation valuations", + py::arg("new_value") = true) + .def("set_build_with_choice_origins", &storm::builder::BuilderOptions::setBuildChoiceOrigins, "Build choice origins", py::arg("new_value") = true) + .def("set_add_out_of_bounds_state", &storm::builder::BuilderOptions::setAddOutOfBoundsState, "Build with out of bounds state", + py::arg("new_value") = true) + .def("set_add_overlapping_guards_label", &storm::builder::BuilderOptions::setAddOverlappingGuardsLabel, "Build with overlapping guards state labeled", + py::arg("new_value") = true) + .def("set_build_choice_labels", &storm::builder::BuilderOptions::setBuildChoiceLabels, "Build with choice labels", py::arg("new_value") = true) + .def("set_exploration_checks", &storm::builder::BuilderOptions::setExplorationChecks, "Perform extra checks during exploration", + py::arg("new_value") = true) + .def("set_build_all_labels", &storm::builder::BuilderOptions::setBuildAllLabels, "Build with all state labels", py::arg("new_value") = true) + .def("set_build_all_reward_models", &storm::builder::BuilderOptions::setBuildAllRewardModels, "Build with all reward models", + py::arg("new_value") = true); py::class_, std::shared_ptr>> actionmask(m, "ActionMaskDouble"); - py::class_, std::shared_ptr>> actfuncmask(m, "StateValuationFunctionActionMaskDouble", actionmask); - actfuncmask.def(py::init>(), py::arg("f")); + py::class_, std::shared_ptr>> actfuncmask( + m, "StateValuationFunctionActionMaskDouble", actionmask); + actfuncmask.def(py::init>(), py::arg("f")); } void define_optimality_type(py::module& m) { py::enum_(m, "OptimizationDirection") .value("Minimize", storm::solver::OptimizationDirection::Minimize) - .value("Maximize", storm::solver::OptimizationDirection::Maximize) - ; + .value("Maximize", storm::solver::OptimizationDirection::Maximize); py::enum_(m, "UncertaintyResolutionMode") .value("MINIMIZE", storm::solver::UncertaintyResolutionMode::Minimize) .value("MAXIMIZE", storm::solver::UncertaintyResolutionMode::Maximize) .value("ROBUST", storm::solver::UncertaintyResolutionMode::Robust) .value("COOPERATIVE", storm::solver::UncertaintyResolutionMode::Cooperative) - .value("UNSET", storm::solver::UncertaintyResolutionMode::Unset) - ; + .value("UNSET", storm::solver::UncertaintyResolutionMode::Unset); } // Thin wrapper for exporting model @@ -197,16 +232,18 @@ void exportDRN(std::shared_ptr> model, s } void define_export(py::module& m) { - py::class_(m, "DirectEncodingExporterOptions") .def(py::init<>()) .def_readwrite("allow_placeholders", &storm::io::DirectEncodingExporterOptions::allowPlaceholders) - .def_readwrite("outputPrecision", &storm::io::DirectEncodingExporterOptions::outputPrecision) - ; + .def_readwrite("outputPrecision", &storm::io::DirectEncodingExporterOptions::outputPrecision); // Export - m.def("_export_to_drn", &exportDRN, "Export model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::io::DirectEncodingExporterOptions()); - m.def("_export_to_drn_interval", &exportDRN, "Export model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::io::DirectEncodingExporterOptions()); - m.def("_export_exact_to_drn", &exportDRN, "Export model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::io::DirectEncodingExporterOptions()); - m.def("_export_parametric_to_drn", &exportDRN, "Export parametric model in DRN format", py::arg("model"), py::arg("file"), py::arg("options")=storm::io::DirectEncodingExporterOptions()); + m.def("_export_to_drn", &exportDRN, "Export model in DRN format", py::arg("model"), py::arg("file"), + py::arg("options") = storm::io::DirectEncodingExporterOptions()); + m.def("_export_to_drn_interval", &exportDRN, "Export model in DRN format", py::arg("model"), py::arg("file"), + py::arg("options") = storm::io::DirectEncodingExporterOptions()); + m.def("_export_exact_to_drn", &exportDRN, "Export model in DRN format", py::arg("model"), py::arg("file"), + py::arg("options") = storm::io::DirectEncodingExporterOptions()); + m.def("_export_parametric_to_drn", &exportDRN, "Export parametric model in DRN format", py::arg("model"), py::arg("file"), + py::arg("options") = storm::io::DirectEncodingExporterOptions()); } diff --git a/src/core/counterexample.cpp b/src/core/counterexample.cpp index 1123157720..3900899e3d 100644 --- a/src/core/counterexample.cpp +++ b/src/core/counterexample.cpp @@ -1,63 +1,72 @@ #include "counterexample.h" -#include "storm/environment/Environment.h" #include "storm-counterexamples/api/counterexamples.h" - +#include "storm/environment/Environment.h" using namespace storm::counterexamples; // Define python bindings void define_counterexamples(py::module& m) { - using FlatSet = boost::container::flat_set, boost::container::new_allocator>; py::class_(m, "FlatSet", "Container to pass to program") - .def(py::init<>()) - .def(py::init(), "other"_a) - .def("insert", [](FlatSet& flatset, uint64_t value) {flatset.insert(value);}) - .def("is_subset_of", [](FlatSet const& left, FlatSet const& right) {return std::includes(right.begin(), right.end(), left.begin(), left.end()); }) - .def("insert_set", [](FlatSet& left, FlatSet const& additional) { for(auto const& i : additional) {left.insert(i);}}) - .def("__str__", [](FlatSet const& set) { std::stringstream str; str << "["; for(auto const& i : set) { str << i << ", ";} str << "]"; return str.str(); }) - .def("__len__", [](FlatSet const& set) { return set.size();}) - .def("__iter__", [](FlatSet &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ - ; + .def(py::init<>()) + .def(py::init(), "other"_a) + .def("insert", [](FlatSet& flatset, uint64_t value) { flatset.insert(value); }) + .def("is_subset_of", [](FlatSet const& left, FlatSet const& right) { return std::includes(right.begin(), right.end(), left.begin(), left.end()); }) + .def("insert_set", + [](FlatSet& left, FlatSet const& additional) { + for (auto const& i : additional) { + left.insert(i); + } + }) + .def("__str__", + [](FlatSet const& set) { + std::stringstream str; + str << "["; + for (auto const& i : set) { + str << i << ", "; + } + str << "]"; + return str.str(); + }) + .def("__len__", [](FlatSet const& set) { return set.size(); }) + .def( + "__iter__", [](FlatSet& v) { return py::make_iterator(v.begin(), v.end()); }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ + ; using CexGeneratorStats = SMTMinimalLabelSetGenerator::GeneratorStats; py::class_(m, "SMTCounterExampleGeneratorStats", "Stats for highlevel counterexample generation") - .def(py::init<>()) - .def_readonly("analysis_time", &CexGeneratorStats::analysisTime) - .def_readonly("setup_time", &CexGeneratorStats::setupTime) - .def_readonly("model_checking_time", &CexGeneratorStats::modelCheckingTime) - .def_readonly("solver_time", &CexGeneratorStats::solverTime) - .def_readonly("cut_time", &CexGeneratorStats::cutTime) - .def_readonly("iterations", &CexGeneratorStats::iterations); - - using CexGeneratorOptions = SMTMinimalLabelSetGenerator::Options; - py::class_(m, "SMTCounterExampleGeneratorOptions", "Options for highlevel counterexample generation") - .def(py::init<>()) - .def_readwrite("check_threshold_feasible", &CexGeneratorOptions::checkThresholdFeasible) - .def_readwrite("encode_reachability", &CexGeneratorOptions::encodeReachability) - .def_readwrite("silent", &CexGeneratorOptions::silent) - .def_readwrite("add_backward_implication_cuts", &CexGeneratorOptions::addBackwardImplicationCuts) - .def_readwrite("use_dynamic_constraints", &CexGeneratorOptions::useDynamicConstraints) - .def_readwrite("maximum_counterexamples", &CexGeneratorOptions::maximumCounterexamples) - .def_readwrite("continue_after_first_counterexample", &CexGeneratorOptions::continueAfterFirstCounterexampleUntil) - .def_readwrite("maximum_iterations_after_counterexample", &CexGeneratorOptions::maximumExtraIterations) - ; - py::class_>(m, "SMTCounterExampleGenerator", "Highlevel Counterexample Generator with SMT as backend"). - def_static("precompute", &SMTMinimalLabelSetGenerator::precompute, "Precompute input for counterexample generation", py::arg("env"), py::arg("symbolic_model"), py::arg("model"), py::arg("formula")). - def_static("build", &SMTMinimalLabelSetGenerator::computeCounterexampleLabelSet, "Compute counterexample", py::arg("env"), py::arg("stats"), py::arg("symbolic_model"), py::arg("model"), py::arg("cex_input"), py::arg("dontcare"), py::arg("options")) - - - ; - - using CexInput = SMTMinimalLabelSetGenerator::CexInput; - py::class_(m, "SMTCounterExampleInput", "Precomputed input for counterexample generation") - .def("add_reward_and_threshold", &CexInput::addRewardThresholdCombination, "add another reward structure and threshold", py::arg("reward_name"), py::arg("threshold")); + .def(py::init<>()) + .def_readonly("analysis_time", &CexGeneratorStats::analysisTime) + .def_readonly("setup_time", &CexGeneratorStats::setupTime) + .def_readonly("model_checking_time", &CexGeneratorStats::modelCheckingTime) + .def_readonly("solver_time", &CexGeneratorStats::solverTime) + .def_readonly("cut_time", &CexGeneratorStats::cutTime) + .def_readonly("iterations", &CexGeneratorStats::iterations); + using CexGeneratorOptions = SMTMinimalLabelSetGenerator::Options; + py::class_(m, "SMTCounterExampleGeneratorOptions", "Options for highlevel counterexample generation") + .def(py::init<>()) + .def_readwrite("check_threshold_feasible", &CexGeneratorOptions::checkThresholdFeasible) + .def_readwrite("encode_reachability", &CexGeneratorOptions::encodeReachability) + .def_readwrite("silent", &CexGeneratorOptions::silent) + .def_readwrite("add_backward_implication_cuts", &CexGeneratorOptions::addBackwardImplicationCuts) + .def_readwrite("use_dynamic_constraints", &CexGeneratorOptions::useDynamicConstraints) + .def_readwrite("maximum_counterexamples", &CexGeneratorOptions::maximumCounterexamples) + .def_readwrite("continue_after_first_counterexample", &CexGeneratorOptions::continueAfterFirstCounterexampleUntil) + .def_readwrite("maximum_iterations_after_counterexample", &CexGeneratorOptions::maximumExtraIterations); + py::class_>(m, "SMTCounterExampleGenerator", "Highlevel Counterexample Generator with SMT as backend") + .def_static("precompute", &SMTMinimalLabelSetGenerator::precompute, "Precompute input for counterexample generation", py::arg("env"), + py::arg("symbolic_model"), py::arg("model"), py::arg("formula")) + .def_static("build", &SMTMinimalLabelSetGenerator::computeCounterexampleLabelSet, "Compute counterexample", py::arg("env"), py::arg("stats"), + py::arg("symbolic_model"), py::arg("model"), py::arg("cex_input"), py::arg("dontcare"), py::arg("options")) + ; + using CexInput = SMTMinimalLabelSetGenerator::CexInput; + py::class_(m, "SMTCounterExampleInput", "Precomputed input for counterexample generation") + .def("add_reward_and_threshold", &CexInput::addRewardThresholdCombination, "add another reward structure and threshold", py::arg("reward_name"), + py::arg("threshold")); } diff --git a/src/core/environment.cpp b/src/core/environment.cpp index e89007057c..92779ce739 100644 --- a/src/core/environment.cpp +++ b/src/core/environment.cpp @@ -1,8 +1,8 @@ #include "environment.h" #include "src/helpers.h" #include "storm/environment/Environment.h" -#include "storm/environment/solver/SolverEnvironment.h" #include "storm/environment/solver/AllSolverEnvironments.h" +#include "storm/environment/solver/SolverEnvironment.h" void define_environment(py::module& m) { py::enum_(m, "EquationSolverType", "Solver type for equation systems") @@ -10,10 +10,10 @@ void define_environment(py::module& m) { .value("eigen", storm::solver::EquationSolverType::Eigen) .value("elimination", storm::solver::EquationSolverType::Elimination) .value("gmmxx", storm::solver::EquationSolverType::Gmmxx) - .value("topological", storm::solver::EquationSolverType::Topological) - ; + .value("topological", storm::solver::EquationSolverType::Topological); - py::enum_(m, "NativeLinearEquationSolverMethod", "Method for linear equation systems with the native solver") + py::enum_(m, "NativeLinearEquationSolverMethod", + "Method for linear equation systems with the native solver") .value("power_iteration", storm::solver::NativeLinearEquationSolverMethod::Power) .value("sound_value_iteration", storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration) .value("optimistic_value_iteration", storm::solver::NativeLinearEquationSolverMethod::OptimisticValueIteration) @@ -22,8 +22,7 @@ void define_environment(py::module& m) { .value("jacobi", storm::solver::NativeLinearEquationSolverMethod::Jacobi) .value("SOR", storm::solver::NativeLinearEquationSolverMethod::SOR) .value("gauss_seidel", storm::solver::NativeLinearEquationSolverMethod::GaussSeidel) - .value("walker_chae", storm::solver::NativeLinearEquationSolverMethod::WalkerChae) - ; + .value("walker_chae", storm::solver::NativeLinearEquationSolverMethod::WalkerChae); py::enum_(m, "MinMaxMethod", "Method for min-max equation systems") .value("policy_iteration", storm::solver::MinMaxMethod::PolicyIteration) @@ -33,33 +32,29 @@ void define_environment(py::module& m) { .value("rational_search", storm::solver::MinMaxMethod::RationalSearch) .value("interval_iteration", storm::solver::MinMaxMethod::IntervalIteration) .value("sound_value_iteration", storm::solver::MinMaxMethod::SoundValueIteration) - .value("optimistic_value_iteration", storm::solver::MinMaxMethod::OptimisticValueIteration) - ; + .value("optimistic_value_iteration", storm::solver::MinMaxMethod::OptimisticValueIteration); py::class_(m, "Environment", "Environment") .def(py::init<>(), "Construct default environment") - .def_property_readonly("solver_environment", [](storm::Environment& env) -> auto& {return env.solver();}, "solver part of environment") - ; + .def_property_readonly("solver_environment", [](storm::Environment& env) -> auto& { return env.solver(); }, "solver part of environment"); py::class_(m, "SolverEnvironment", "Environment for solvers") .def("set_force_sound", &storm::SolverEnvironment::setForceSoundness, "force soundness", py::arg("new_value") = true) .def("set_force_exact", &storm::SolverEnvironment::setForceExact, "force exact solving", py::arg("new_value") = true) - .def("set_linear_equation_solver_type", &storm::SolverEnvironment::setLinearEquationSolverType, "set solver type to use", py::arg("new_value"), py::arg("set_from_default") = false) + .def("set_linear_equation_solver_type", &storm::SolverEnvironment::setLinearEquationSolverType, "set solver type to use", py::arg("new_value"), + py::arg("set_from_default") = false) .def_property_readonly("minmax_solver_environment", [](storm::SolverEnvironment& senv) -> auto& { return senv.minMax(); }) - .def_property_readonly("native_solver_environment", [](storm::SolverEnvironment& senv) -> auto& {return senv.native(); }) - ; + .def_property_readonly("native_solver_environment", [](storm::SolverEnvironment& senv) -> auto& { return senv.native(); }); py::class_(m, "NativeSolverEnvironment", "Environment for Native solvers") - .def_property("method", &storm::NativeSolverEnvironment::getMethod, [](storm::NativeSolverEnvironment& nsenv, storm::solver::NativeLinearEquationSolverMethod const& m) {nsenv.setMethod(m);}) - .def_property("maximum_iterations", &storm::NativeSolverEnvironment::getMaximalNumberOfIterations, [](storm::NativeSolverEnvironment& nsenv, uint64_t iters) {nsenv.setMaximalNumberOfIterations(iters);} ) - .def_property("precision", &storm::NativeSolverEnvironment::getPrecision, &storm::NativeSolverEnvironment::setPrecision) - ; + .def_property("method", &storm::NativeSolverEnvironment::getMethod, + [](storm::NativeSolverEnvironment& nsenv, storm::solver::NativeLinearEquationSolverMethod const& m) { nsenv.setMethod(m); }) + .def_property("maximum_iterations", &storm::NativeSolverEnvironment::getMaximalNumberOfIterations, + [](storm::NativeSolverEnvironment& nsenv, uint64_t iters) { nsenv.setMaximalNumberOfIterations(iters); }) + .def_property("precision", &storm::NativeSolverEnvironment::getPrecision, &storm::NativeSolverEnvironment::setPrecision); py::class_(m, "MinMaxSolverEnvironment", "Environment for Min-Max-Solvers") - .def_property("method", &storm::MinMaxSolverEnvironment::getMethod, [](storm::MinMaxSolverEnvironment& mmenv, storm::solver::MinMaxMethod const& m) { mmenv.setMethod(m, false); } ) - .def_property("precision", &storm::MinMaxSolverEnvironment::getPrecision, &storm::MinMaxSolverEnvironment::setPrecision); - - - + .def_property("method", &storm::MinMaxSolverEnvironment::getMethod, + [](storm::MinMaxSolverEnvironment& mmenv, storm::solver::MinMaxMethod const& m) { mmenv.setMethod(m, false); }) + .def_property("precision", &storm::MinMaxSolverEnvironment::getPrecision, &storm::MinMaxSolverEnvironment::setPrecision); } - diff --git a/src/core/environment.h b/src/core/environment.h index 7c147b7def..fd71bf466f 100644 --- a/src/core/environment.h +++ b/src/core/environment.h @@ -3,4 +3,3 @@ #include "common.h" void define_environment(py::module& m); - diff --git a/src/core/input.cpp b/src/core/input.cpp index 00402ce0b2..581eeda66c 100644 --- a/src/core/input.cpp +++ b/src/core/input.cpp @@ -1,39 +1,45 @@ #include "input.h" +#include #include "src/helpers.h" #include "storm-parsers/api/storm-parsers.h" #include "storm/storage/jani/Property.h" -#include void define_property(py::module& m) { py::class_(m, "Property", "Property") - .def(py::init const&, std::set const&, std::string const&>(), "Construct property from formula", py::arg("name"), py::arg("formula"), py::arg("undefined_constants") = std::set(), py::arg("comment") = "") + .def(py::init const&, std::set const&, + std::string const&>(), + "Construct property from formula", py::arg("name"), py::arg("formula"), py::arg("undefined_constants") = std::set(), + py::arg("comment") = "") .def(py::init()) .def_property_readonly("name", &storm::jani::Property::getName, "Obtain the name of the property") .def_property_readonly("raw_formula", &storm::jani::Property::getRawFormula, "Obtain the formula directly") - .def("__str__", &streamToString) - ; + .def("__str__", &streamToString); } -std::map parse_constants_string(storm::expressions::ExpressionManager const& m, std::string const& input) { +std::map parse_constants_string(storm::expressions::ExpressionManager const& m, + std::string const& input) { return storm::utility::cli::parseConstantDefinitionString(m, input); } // Define python bindings void define_input(py::module& m) { - m.def("parse_constants_string", &parse_constants_string, "Parse constants definition", py::arg("expression_manager"), py::arg("definition_string")); // Parse Prism program - m.def("parse_prism_program", &storm::api::parseProgram, "Parse Prism program", py::arg("path"), py::arg("prism_compat") = false, py::arg("simplify") = true); + m.def("parse_prism_program", &storm::api::parseProgram, "Parse Prism program", py::arg("path"), py::arg("prism_compat") = false, + py::arg("simplify") = true); // Parse Jani model - m.def("parse_jani_model", [](std::string const& path) -> std::pair>{ - return storm::api::parseJaniModel(path); - }, "Parse Jani model", py::arg("path")); - m.def("parse_jani_model_from_string", [](std::string const& jsonstring){ - return storm::api::parseJaniModelFromString(jsonstring); - }, "Parse Jani model from string", py::arg("json_string")); + m.def( + "parse_jani_model", + [](std::string const& path) -> std::pair> { return storm::api::parseJaniModel(path); }, + "Parse Jani model", py::arg("path")); + m.def( + "parse_jani_model_from_string", [](std::string const& jsonstring) { return storm::api::parseJaniModelFromString(jsonstring); }, + "Parse Jani model from string", py::arg("json_string")); - m.def("preprocess_symbolic_input", [](storm::storage::SymbolicModelDescription const& input, std::vector properties, std::string constantDefinitionString){ + m.def( + "preprocess_symbolic_input", + [](storm::storage::SymbolicModelDescription const& input, std::vector properties, std::string constantDefinitionString) { // Substitute constant definitions in symbolic input. std::map constantDefinitions; storm::storage::SymbolicModelDescription output; @@ -43,9 +49,10 @@ void define_input(py::module& m) { if (!properties.empty()) { outputProperties = storm::api::substituteConstantsInProperties(properties, constantDefinitions); } - //ensureNoUndefinedPropertyConstants(outputProperties); + // ensureNoUndefinedPropertyConstants(outputProperties); return std::pair>(output, outputProperties); - }, "Preprocess symoblic input", py::arg("symbolic_model_description"), py::arg("properties"), py::arg("constant_definition_string")); + }, + "Preprocess symoblic input", py::arg("symbolic_model_description"), py::arg("properties"), py::arg("constant_definition_string")); // JaniType py::enum_(m, "JaniModelType", "Type of the Jani model") @@ -61,8 +68,7 @@ void define_input(py::module& m) { .value("HA", storm::jani::ModelType::HA) .value("PHA", storm::jani::ModelType::PHA) .value("SHA", storm::jani::ModelType::SHA) - .value("UNDEFINED", storm::jani::ModelType::UNDEFINED) - ; + .value("UNDEFINED", storm::jani::ModelType::UNDEFINED); // SymbolicModelDescription py::class_(m, "SymbolicModelDescription", "Symbolic description of model") @@ -70,17 +76,18 @@ void define_input(py::module& m) { .def(py::init(), "Construct from Jani model", py::arg("jani_model")) .def_property_readonly("is_prism_program", &storm::storage::SymbolicModelDescription::isPrismProgram, "Flag if program is in Prism format") .def_property_readonly("is_jani_model", &storm::storage::SymbolicModelDescription::isJaniModel, "Flag if program is in Jani format") - .def("parse_constant_definitions", &storm::storage::SymbolicModelDescription::parseConstantDefinitions, "Parse given constant definitions", py::arg("String containing constants and their values")) - .def("instantiate_constants", [](storm::storage::SymbolicModelDescription const& description, std::map const& constantDefinitions) { + .def("parse_constant_definitions", &storm::storage::SymbolicModelDescription::parseConstantDefinitions, "Parse given constant definitions", + py::arg("String containing constants and their values")) + .def( + "instantiate_constants", + [](storm::storage::SymbolicModelDescription const& description, + std::map const& constantDefinitions) { return description.preprocess(constantDefinitions); - }, "Instantiate constants in symbolic model description", py::arg("constant_definitions")) - .def("as_jani_model", [](storm::storage::SymbolicModelDescription& description) { - return description.asJaniModel(); - }, "Return Jani model") - .def("as_prism_program", [](storm::storage::SymbolicModelDescription& description) { - return description.asPrismProgram(); - }, "Return Prism program") - ; + }, + "Instantiate constants in symbolic model description", py::arg("constant_definitions")) + .def( + "as_jani_model", [](storm::storage::SymbolicModelDescription& description) { return description.asJaniModel(); }, "Return Jani model") + .def("as_prism_program", [](storm::storage::SymbolicModelDescription& description) { return description.asPrismProgram(); }, "Return Prism program"); // PrismProgram and JaniModel can be converted into SymbolicModelDescription py::implicitly_convertible(); diff --git a/src/core/modelchecking.cpp b/src/core/modelchecking.cpp index 5ebf428f76..b754e84f5f 100644 --- a/src/core/modelchecking.cpp +++ b/src/core/modelchecking.cpp @@ -4,11 +4,11 @@ #include "storm/api/verification.h" #include "storm/environment/Environment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" -#include "storm/models/symbolic/StandardRewardModel.h" -#include "storm/modelchecker/results/CheckResult.h" -#include "storm/modelchecker/hints/ExplicitModelCheckerHint.h" #include "storm/modelchecker/csl/helper/SparseCtmcCslHelper.h" +#include "storm/modelchecker/hints/ExplicitModelCheckerHint.h" #include "storm/modelchecker/multiobjective/MultiObjectiveModelChecking.h" +#include "storm/modelchecker/results/CheckResult.h" +#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/utility/graph.h" template @@ -16,91 +16,115 @@ using CheckTask = storm::modelchecker::CheckTask -std::shared_ptr modelCheckingSparseEngine(std::shared_ptr> model, CheckTask const& task, storm::Environment const& env) { +std::shared_ptr modelCheckingSparseEngine(std::shared_ptr> model, + CheckTask const& task, storm::Environment const& env) { return storm::api::verifyWithSparseEngine(env, model, task); } template std::shared_ptr multiObjectiveModelChecking(std::shared_ptr> model, - storm::logic::MultiObjectiveFormula const& formula, storm::Environment const& env) { + storm::logic::MultiObjectiveFormula const& formula, + storm::Environment const& env) { if (model->isOfType(storm::models::ModelType::Mdp)) { - return storm::modelchecker::multiobjective::performMultiObjectiveModelChecking>(env, *(model->template as>()), formula); + return storm::modelchecker::multiobjective::performMultiObjectiveModelChecking>( + env, *(model->template as>()), formula); } else if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { - return storm::modelchecker::multiobjective::performMultiObjectiveModelChecking>(env, *(model->template as>()), formula); + return storm::modelchecker::multiobjective::performMultiObjectiveModelChecking>( + env, *(model->template as>()), formula); } else { throw storm::exceptions::NotSupportedException("Only systems with Nondeterminism are supported"); } } template -std::shared_ptr modelCheckingFullyObservableSparseEngine(std::shared_ptr> model, CheckTask const& task, storm::Environment const& env) { +std::shared_ptr modelCheckingFullyObservableSparseEngine(std::shared_ptr> model, + CheckTask const& task, storm::Environment const& env) { return storm::api::verifyWithSparseEngine(env, model->template as>(), task); } // Thin wrapper for model checking using dd engine template -std::shared_ptr modelCheckingDdEngine(std::shared_ptr> model, CheckTask const& task, storm::Environment const& env) { +std::shared_ptr modelCheckingDdEngine(std::shared_ptr> model, + CheckTask const& task, storm::Environment const& env) { return storm::api::verifyWithDdEngine(env, model, task); } // Thin wrapper for model checking using hybrid engine template -std::shared_ptr modelCheckingHybridEngine(std::shared_ptr> model, CheckTask const& task, storm::Environment const& env) { +std::shared_ptr modelCheckingHybridEngine(std::shared_ptr> model, + CheckTask const& task, storm::Environment const& env) { return storm::api::verifyWithHybridEngine(env, model, task); } -std::shared_ptr checkIntervalDtmc(std::shared_ptr> dtmc, CheckTask const& task, storm::Environment& env) { +std::shared_ptr checkIntervalDtmc(std::shared_ptr> dtmc, + CheckTask const& task, storm::Environment& env) { auto checker = storm::modelchecker::SparseDtmcPrctlModelChecker>(*dtmc); return checker.check(env, task); } -std::shared_ptr checkIntervalMdp(std::shared_ptr> mdp, CheckTask const& task, storm::Environment& env) { +std::shared_ptr checkIntervalMdp(std::shared_ptr> mdp, + CheckTask const& task, storm::Environment& env) { auto checker = storm::modelchecker::SparseMdpPrctlModelChecker>(*mdp); return checker.check(env, task); } -std::vector computeAllUntilProbabilities(storm::Environment const& env, CheckTask const& task, std::shared_ptr> ctmc, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { +std::vector computeAllUntilProbabilities(storm::Environment const& env, CheckTask const& task, + std::shared_ptr> ctmc, storm::storage::BitVector const& phiStates, + storm::storage::BitVector const& psiStates) { storm::solver::SolveGoal goal(*ctmc, task); - return storm::modelchecker::helper::SparseCtmcCslHelper::computeAllUntilProbabilities(env, std::move(goal), ctmc->getTransitionMatrix(), ctmc->getExitRateVector(), ctmc->getInitialStates(), phiStates, psiStates); + return storm::modelchecker::helper::SparseCtmcCslHelper::computeAllUntilProbabilities( + env, std::move(goal), ctmc->getTransitionMatrix(), ctmc->getExitRateVector(), ctmc->getInitialStates(), phiStates, psiStates); } -std::vector computeTransientProbabilities(storm::Environment const& env, std::shared_ptr> ctmc, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double timeBound) { - return storm::modelchecker::helper::SparseCtmcCslHelper::computeAllTransientProbabilities(env, ctmc->getTransitionMatrix(), ctmc->getInitialStates(), phiStates, psiStates, ctmc->getExitRateVector(), timeBound); +std::vector computeTransientProbabilities(storm::Environment const& env, std::shared_ptr> ctmc, + storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double timeBound) { + return storm::modelchecker::helper::SparseCtmcCslHelper::computeAllTransientProbabilities(env, ctmc->getTransitionMatrix(), ctmc->getInitialStates(), + phiStates, psiStates, ctmc->getExitRateVector(), timeBound); } // Thin wrapper for computing prob01 states template -std::pair computeProb01(storm::models::sparse::Dtmc const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { +std::pair computeProb01(storm::models::sparse::Dtmc const& model, + storm::storage::BitVector const& phiStates, + storm::storage::BitVector const& psiStates) { return storm::utility::graph::performProb01(model, phiStates, psiStates); } template -std::pair computeProb01min(storm::models::sparse::Mdp const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { +std::pair computeProb01min(storm::models::sparse::Mdp const& model, + storm::storage::BitVector const& phiStates, + storm::storage::BitVector const& psiStates) { return storm::utility::graph::performProb01Min(model, phiStates, psiStates); } template -std::pair computeProb01max(storm::models::sparse::Mdp const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { +std::pair computeProb01max(storm::models::sparse::Mdp const& model, + storm::storage::BitVector const& phiStates, + storm::storage::BitVector const& psiStates) { return storm::utility::graph::performProb01Max(model, phiStates, psiStates); } template -std::shared_ptr getExpectedNumberOfVisits(storm::Environment const& env, std::shared_ptr> const& model) { +std::shared_ptr getExpectedNumberOfVisits(storm::Environment const& env, + std::shared_ptr> const& model) { return storm::api::computeExpectedVisitingTimesWithSparseEngine(env, model); } template -std::shared_ptr getSteadyStateDistribution(storm::Environment const& env, std::shared_ptr> const& model) { +std::shared_ptr getSteadyStateDistribution(storm::Environment const& env, + std::shared_ptr> const& model) { return storm::api::computeSteadyStateDistributionWithSparseEngine(env, model); } template -storm::storage::BitVector getReachableStates(storm::models::sparse::Model const& model, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, boost::optional maximalStep, boost::optional const& choiceFilter) { +storm::storage::BitVector getReachableStates(storm::models::sparse::Model const& model, storm::storage::BitVector const& initialStates, + storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, + boost::optional maximalStep, boost::optional const& choiceFilter) { uint64_t steps = 0; if (maximalStep != boost::none) { steps = maximalStep.get(); } - return storm::utility::graph::getReachableStates(model.getTransitionMatrix(), initialStates, constraintStates, targetStates, maximalStep != boost::none, steps, choiceFilter); - + return storm::utility::graph::getReachableStates(model.getTransitionMatrix(), initialStates, constraintStates, targetStates, maximalStep != boost::none, + steps, choiceFilter); } // TODO: use consistent suffix instead of name @@ -109,54 +133,81 @@ void define_check_task(py::module& m, std::string const& name) { // CheckTask py::class_, std::shared_ptr>>(m, name.c_str(), "Task for model checking") .def(py::init(), py::arg("formula"), py::arg("only_initial_states") = false) - .def("set_produce_schedulers", &CheckTask::setProduceSchedulers, "Set whether schedulers should be produced (if possible)", py::arg("produce_schedulers") = true) + .def("set_produce_schedulers", &CheckTask::setProduceSchedulers, "Set whether schedulers should be produced (if possible)", + py::arg("produce_schedulers") = true) .def("set_hint", &CheckTask::setHint, "Sets a hint that may speed up the solver") - .def("set_uncertainty_resolution_mode", &CheckTask::setUncertaintyResolutionMode, "Sets the mode which decides how the uncertainty will be resolved.") - ; + .def("set_uncertainty_resolution_mode", &CheckTask::setUncertaintyResolutionMode, + "Sets the mode which decides how the uncertainty will be resolved."); } void define_modelchecking(py::module& m) { - - py::class_> mchint(m, "ModelCheckerHint", "Information that may accelerate the model checking process"); - py::class_>(m, "ExplicitModelCheckerHintDouble", "Information that may accelerate an explicit state model checker", mchint) + py::class_> mchint( + m, "ModelCheckerHint", "Information that may accelerate the model checking process"); + py::class_>(m, "ExplicitModelCheckerHintDouble", + "Information that may accelerate an explicit state model checker", mchint) .def(py::init<>()) - .def("set_scheduler_hint", py::overload_cast> const&>(&storm::modelchecker::ExplicitModelCheckerHint::setSchedulerHint), "scheduler_hint"_a, "Set a scheduler that is close to the optimal scheduler") - .def("set_maybe_states", py::overload_cast(&storm::modelchecker::ExplicitModelCheckerHint::setMaybeStates), "sets the maybe states. This is assumed to be correct.") + .def("set_scheduler_hint", + py::overload_cast> const&>( + &storm::modelchecker::ExplicitModelCheckerHint::setSchedulerHint), + "scheduler_hint"_a, "Set a scheduler that is close to the optimal scheduler") + .def("set_maybe_states", py::overload_cast(&storm::modelchecker::ExplicitModelCheckerHint::setMaybeStates), + "sets the maybe states. This is assumed to be correct.") .def("set_compute_only_maybe_states", &storm::modelchecker::ExplicitModelCheckerHint::setComputeOnlyMaybeStates, "value") - .def("set_result_hint", py::overload_cast> const&>(&storm::modelchecker::ExplicitModelCheckerHint::setResultHint), "result_hint"_a); + .def("set_result_hint", + py::overload_cast> const&>(&storm::modelchecker::ExplicitModelCheckerHint::setResultHint), + "result_hint"_a); - m.def("_get_reachable_states_double", &getReachableStates, py::arg("model"), py::arg("initial_states"), py::arg("constraint_states"), py::arg("target_states"), py::arg("maximal_steps") = boost::none, py::arg("choice_filter") = boost::none); - m.def("_get_reachable_states_exact", &getReachableStates, py::arg("model"), py::arg("initial_states"), py::arg("constraint_states"), py::arg("target_states"), py::arg("maximal_steps") = boost::none, py::arg("choice_filter") = boost::none); - m.def("_get_reachable_states_rf", &getReachableStates, py::arg("model"), py::arg("initial_states"), py::arg("constraint_states"), py::arg("target_states"), py::arg("maximal_steps") = boost::none, py::arg("choice_filter") = boost::none); + m.def("_get_reachable_states_double", &getReachableStates, py::arg("model"), py::arg("initial_states"), py::arg("constraint_states"), + py::arg("target_states"), py::arg("maximal_steps") = boost::none, py::arg("choice_filter") = boost::none); + m.def("_get_reachable_states_exact", &getReachableStates, py::arg("model"), py::arg("initial_states"), py::arg("constraint_states"), + py::arg("target_states"), py::arg("maximal_steps") = boost::none, py::arg("choice_filter") = boost::none); + m.def("_get_reachable_states_rf", &getReachableStates, py::arg("model"), py::arg("initial_states"), py::arg("constraint_states"), + py::arg("target_states"), py::arg("maximal_steps") = boost::none, py::arg("choice_filter") = boost::none); m.def("_compute_expected_number_of_visits_double", &getExpectedNumberOfVisits, py::arg("env"), py::arg("model")); - m.def("_compute_expected_number_of_visits_exact", &getExpectedNumberOfVisits, py::arg("env"), py::arg("model")); + m.def("_compute_expected_number_of_visits_exact", &getExpectedNumberOfVisits, py::arg("env"), py::arg("model")); m.def("_compute_steady_state_distribution_double", &getSteadyStateDistribution, py::arg("env"), py::arg("model")); - m.def("_compute_steady_state_distribution_exact", &getSteadyStateDistribution, py::arg("env"), py::arg("model")); + m.def("_compute_steady_state_distribution_exact", &getSteadyStateDistribution, py::arg("env"), py::arg("model")); // Model checking - m.def("_model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine, py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); - m.def("_exact_model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine, py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); - m.def("_model_checking_sparse_engine", &modelCheckingSparseEngine, "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, "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, "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, "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, "Perform parametric model checking using the dd engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); - m.def("_model_checking_hybrid_engine", &modelCheckingHybridEngine, "Perform model checking using the hybrid engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); - m.def("_parametric_model_checking_hybrid_engine", &modelCheckingHybridEngine, "Perform parametric model checking using the hybrid engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); + m.def("_model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine, py::arg("model"), py::arg("task"), + py::arg("environment") = storm::Environment()); + m.def("_exact_model_checking_fully_observable", &modelCheckingFullyObservableSparseEngine, py::arg("model"), py::arg("task"), + py::arg("environment") = storm::Environment()); + m.def("_model_checking_sparse_engine", &modelCheckingSparseEngine, "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, "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, + "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, "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, + "Perform parametric model checking using the dd engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); + m.def("_model_checking_hybrid_engine", &modelCheckingHybridEngine, "Perform model checking using the hybrid engine", + py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); + m.def("_parametric_model_checking_hybrid_engine", &modelCheckingHybridEngine, + "Perform parametric model checking using the hybrid engine", py::arg("model"), py::arg("task"), py::arg("environment") = storm::Environment()); m.def("check_interval_dtmc", &checkIntervalDtmc, "Check interval DTMC"); m.def("check_interval_mdp", &checkIntervalMdp, "Check interval MDP"); m.def("compute_all_until_probabilities", &computeAllUntilProbabilities, "Compute forward until probabilities"); m.def("compute_transient_probabilities", &computeTransientProbabilities, "Compute transient probabilities"); m.def("_compute_prob01states_double", &computeProb01, "Compute prob-0-1 states", py::arg("model"), py::arg("phi_states"), py::arg("psi_states")); - m.def("_compute_prob01states_rationalfunc", &computeProb01, "Compute prob-0-1 states", py::arg("model"), py::arg("phi_states"), py::arg("psi_states")); - m.def("_compute_prob01states_min_double", &computeProb01min, "Compute prob-0-1 states (min)", py::arg("model"), py::arg("phi_states"), py::arg("psi_states")); - m.def("_compute_prob01states_max_double", &computeProb01max, "Compute prob-0-1 states (max)", py::arg("model"), py::arg("phi_states"), py::arg("psi_states")); - m.def("_compute_prob01states_min_rationalfunc", &computeProb01min, "Compute prob-0-1 states (min)", py::arg("model"), py::arg("phi_states"), py::arg("psi_states")); - m.def("_compute_prob01states_max_rationalfunc", &computeProb01max, "Compute prob-0-1 states (max)", py::arg("model"), py::arg("phi_states"), py::arg("psi_states")); - m.def("_multi_objective_model_checking_double", &multiObjectiveModelChecking, "Run multi-objective model checking", py::arg("model"), py::arg("formula"), py::arg("environment") = storm::Environment()); - m.def("_multi_objective_model_checking_exact", &multiObjectiveModelChecking, "Run multi-objective model checking", py::arg("model"), py::arg("formula"), py::arg("environment") = storm::Environment()); + m.def("_compute_prob01states_rationalfunc", &computeProb01, "Compute prob-0-1 states", py::arg("model"), py::arg("phi_states"), + py::arg("psi_states")); + m.def("_compute_prob01states_min_double", &computeProb01min, "Compute prob-0-1 states (min)", py::arg("model"), py::arg("phi_states"), + py::arg("psi_states")); + m.def("_compute_prob01states_max_double", &computeProb01max, "Compute prob-0-1 states (max)", py::arg("model"), py::arg("phi_states"), + py::arg("psi_states")); + m.def("_compute_prob01states_min_rationalfunc", &computeProb01min, "Compute prob-0-1 states (min)", py::arg("model"), + py::arg("phi_states"), py::arg("psi_states")); + m.def("_compute_prob01states_max_rationalfunc", &computeProb01max, "Compute prob-0-1 states (max)", py::arg("model"), + py::arg("phi_states"), py::arg("psi_states")); + m.def("_multi_objective_model_checking_double", &multiObjectiveModelChecking, "Run multi-objective model checking", py::arg("model"), + py::arg("formula"), py::arg("environment") = storm::Environment()); + m.def("_multi_objective_model_checking_exact", &multiObjectiveModelChecking, "Run multi-objective model checking", py::arg("model"), + py::arg("formula"), py::arg("environment") = storm::Environment()); } template void define_check_task(py::module&, std::string const&); diff --git a/src/core/modelchecking.h b/src/core/modelchecking.h index 8003dbaeae..201b30a135 100644 --- a/src/core/modelchecking.h +++ b/src/core/modelchecking.h @@ -6,4 +6,3 @@ template void define_check_task(py::module& m, std::string const& name); void define_modelchecking(py::module& m); - diff --git a/src/core/result.cpp b/src/core/result.cpp index 8a633a21ee..5b1e41ed6c 100644 --- a/src/core/result.cpp +++ b/src/core/result.cpp @@ -1,11 +1,11 @@ #include "result.h" #include "storm/analysis/GraphConditions.h" +#include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" +#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" +#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" -#include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" -#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" -#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" -#include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" #include "storm/models/symbolic/StandardRewardModel.h" @@ -15,129 +15,183 @@ std::shared_ptr createFilterInitial } template -std::shared_ptr createFilterInitialStatesSymbolic(std::shared_ptr> model) { - return std::make_unique>(model->getReachableStates(), model->getInitialStates()); +std::shared_ptr createFilterInitialStatesSymbolic( + std::shared_ptr> model) { + return std::make_unique>(model->getReachableStates(), model->getInitialStates()); } template -std::shared_ptr createFilterSymbolic(std::shared_ptr> model, storm::expressions::Expression const& expr) { +std::shared_ptr createFilterSymbolic(std::shared_ptr> model, + storm::expressions::Expression const& expr) { return std::make_unique>(model->getReachableStates(), model->getStates(expr)); } // Define python bindings void define_result(py::module& m) { - // CheckResult - py::class_> checkResult(m, "_CheckResult", "Base class for all modelchecking results"); + py::class_> checkResult(m, "_CheckResult", + "Base class for all modelchecking results"); checkResult.def_property_readonly("_symbolic", &storm::modelchecker::CheckResult::isSymbolic, "Flag if result is symbolic") .def_property_readonly("_hybrid", &storm::modelchecker::CheckResult::isHybrid, "Flag if result is hybrid") .def_property_readonly("_quantitative", &storm::modelchecker::CheckResult::isQuantitative, "Flag if result is quantitative") .def_property_readonly("_qualitative", &storm::modelchecker::CheckResult::isQualitative, "Flag if result is qualitative") - .def_property_readonly("_explicit_qualitative", &storm::modelchecker::CheckResult::isExplicitQualitativeCheckResult, "Flag if result is explicit qualitative") - .def_property_readonly("_explicit_quantitative", &storm::modelchecker::CheckResult::isExplicitQuantitativeCheckResult, "Flag if result is explicit quantitative") - .def_property_readonly("_symbolic_qualitative", &storm::modelchecker::CheckResult::isSymbolicQualitativeCheckResult, "Flag if result is symbolic qualitative") - .def_property_readonly("_symbolic_quantitative", &storm::modelchecker::CheckResult::isSymbolicQuantitativeCheckResult, "Flag if result is symbolic quantitative") - .def_property_readonly("_hybrid_quantitative", &storm::modelchecker::CheckResult::isHybridQuantitativeCheckResult, "Flag if result is hybrid quantitative") + .def_property_readonly("_explicit_qualitative", &storm::modelchecker::CheckResult::isExplicitQualitativeCheckResult, + "Flag if result is explicit qualitative") + .def_property_readonly("_explicit_quantitative", &storm::modelchecker::CheckResult::isExplicitQuantitativeCheckResult, + "Flag if result is explicit quantitative") + .def_property_readonly("_symbolic_qualitative", &storm::modelchecker::CheckResult::isSymbolicQualitativeCheckResult, + "Flag if result is symbolic qualitative") + .def_property_readonly("_symbolic_quantitative", &storm::modelchecker::CheckResult::isSymbolicQuantitativeCheckResult, + "Flag if result is symbolic quantitative") + .def_property_readonly("_hybrid_quantitative", &storm::modelchecker::CheckResult::isHybridQuantitativeCheckResult, + "Flag if result is hybrid quantitative") .def_property_readonly("_pareto_curve", &storm::modelchecker::CheckResult::isParetoCurveCheckResult, "Flag if result is a pareto curve") .def_property_readonly("result_for_all_states", &storm::modelchecker::CheckResult::isResultForAllStates, "Flag if result is for all states") .def_property_readonly("has_scheduler", &storm::modelchecker::CheckResult::hasScheduler, "Flag if a scheduler is present") - .def("as_explicit_qualitative", [](storm::modelchecker::CheckResult const& result) { - return result.asExplicitQualitativeCheckResult(); - }, "Convert into explicit qualitative result") - .def("as_explicit_quantitative", [](storm::modelchecker::CheckResult const& result) { - return result.asExplicitQuantitativeCheckResult(); - }, "Convert into explicit quantitative result") - .def("as_explicit_exact_quantitative", [](storm::modelchecker::CheckResult const& result) { - return result.asExplicitQuantitativeCheckResult(); - }, "Convert into explicit quantitative result") - .def("as_explicit_parametric_quantitative", [](storm::modelchecker::CheckResult const& result) { - return result.asExplicitQuantitativeCheckResult(); - }, "Convert into explicit quantitative result") + .def( + "as_explicit_qualitative", [](storm::modelchecker::CheckResult const& result) { return result.asExplicitQualitativeCheckResult(); }, + "Convert into explicit qualitative result") + .def( + "as_explicit_quantitative", [](storm::modelchecker::CheckResult const& result) { return result.asExplicitQuantitativeCheckResult(); }, + "Convert into explicit quantitative result") + .def( + "as_explicit_exact_quantitative", + [](storm::modelchecker::CheckResult const& result) { return result.asExplicitQuantitativeCheckResult(); }, + "Convert into explicit quantitative result") + .def( + "as_explicit_parametric_quantitative", + [](storm::modelchecker::CheckResult const& result) { return result.asExplicitQuantitativeCheckResult(); }, + "Convert into explicit quantitative result") .def("filter", &storm::modelchecker::CheckResult::filter, py::arg("filter"), "Filter the result") - .def("__str__", [](storm::modelchecker::CheckResult const& result) { - std::stringstream stream; - result.writeToStream(stream); - return stream.str(); - }) - ; + .def("__str__", [](storm::modelchecker::CheckResult const& result) { + std::stringstream stream; + result.writeToStream(stream); + return stream.str(); + }); // QualitativeCheckResult - py::class_> qualitativeCheckResult(m, "_QualitativeCheckResult", "Abstract class for qualitative model checking results", checkResult); - py::class_>(m, "ExplicitQualitativeCheckResult", "Explicit qualitative model checking result", qualitativeCheckResult) - .def("at", [](storm::modelchecker::ExplicitQualitativeCheckResult const& result, storm::storage::sparse::state_type state) { - return result[state]; - }, py::arg("state"), "Get result for given state") - .def("get_truth_values", &storm::modelchecker::ExplicitQualitativeCheckResult::getTruthValuesVector, "Get BitVector representing the truth values") - ; - py::class_, std::shared_ptr>>(m, "SymbolicQualitativeCheckResult", "Symbolic qualitative model checking result", qualitativeCheckResult) - .def("get_truth_values", &storm::modelchecker::SymbolicQualitativeCheckResult::getTruthValuesVector, "Get Dd representing the truth values") - ; + py::class_> qualitativeCheckResult( + m, "_QualitativeCheckResult", "Abstract class for qualitative model checking results", checkResult); + py::class_>( + m, "ExplicitQualitativeCheckResult", "Explicit qualitative model checking result", qualitativeCheckResult) + .def( + "at", [](storm::modelchecker::ExplicitQualitativeCheckResult const& result, storm::storage::sparse::state_type state) { return result[state]; }, + py::arg("state"), "Get result for given state") + .def("get_truth_values", &storm::modelchecker::ExplicitQualitativeCheckResult::getTruthValuesVector, "Get BitVector representing the truth values"); + py::class_, + std::shared_ptr>>( + m, "SymbolicQualitativeCheckResult", "Symbolic qualitative model checking result", qualitativeCheckResult) + .def("get_truth_values", &storm::modelchecker::SymbolicQualitativeCheckResult::getTruthValuesVector, + "Get Dd representing the truth values"); // QuantitativeCheckResult - py::class_, std::shared_ptr>> quantitativeCheckResult(m, "_QuantitativeCheckResult", "Abstract class for quantitative model checking results", checkResult); + py::class_, std::shared_ptr>> + quantitativeCheckResult(m, "_QuantitativeCheckResult", "Abstract class for quantitative model checking results", checkResult); quantitativeCheckResult.def_property_readonly("min", &storm::modelchecker::QuantitativeCheckResult::getMin, "Minimal value") - .def_property_readonly("max", &storm::modelchecker::QuantitativeCheckResult::getMax, "Maximal value") - ; + .def_property_readonly("max", &storm::modelchecker::QuantitativeCheckResult::getMax, "Maximal value"); - py::class_, std::shared_ptr>>(m, "ExplicitQuantitativeCheckResult", "Explicit quantitative model checking result", quantitativeCheckResult) + py::class_, std::shared_ptr>>( + m, "ExplicitQuantitativeCheckResult", "Explicit quantitative model checking result", quantitativeCheckResult) .def(py::init>(), py::arg("values")) - .def("at", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& result, storm::storage::sparse::state_type state) { - return result[state]; - }, py::arg("state"), "Get result for given state") - .def("get_values", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) {return res.getValueVector();}, "Get model checking result values for all states") - .def_property_readonly("scheduler", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) {return res.getScheduler();}, "get scheduler") - ; - py::class_, std::shared_ptr>>(m, "SymbolicQuantitativeCheckResult", "Symbolic quantitative model checking result", quantitativeCheckResult) - .def("clone", [](storm::modelchecker::SymbolicQuantitativeCheckResult const& dd) {return dd.clone()->asSymbolicQuantitativeCheckResult(); }) - .def("get_values", &storm::modelchecker::SymbolicQuantitativeCheckResult::getValueVector); - ; - py::class_, std::shared_ptr>>(m, "HybridQuantitativeCheckResult", "Hybrid quantitative model checking result", quantitativeCheckResult) - .def("get_values", &storm::modelchecker::HybridQuantitativeCheckResult::getExplicitValueVector, "Get model checking result values for all states") + .def( + "at", + [](storm::modelchecker::ExplicitQuantitativeCheckResult const& result, storm::storage::sparse::state_type state) { return result[state]; }, + py::arg("state"), "Get result for given state") + .def( + "get_values", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getValueVector(); }, + "Get model checking result values for all states") + .def_property_readonly( + "scheduler", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getScheduler(); }, "get scheduler"); + py::class_, + std::shared_ptr>>( + m, "SymbolicQuantitativeCheckResult", "Symbolic quantitative model checking result", quantitativeCheckResult) + .def("clone", + [](storm::modelchecker::SymbolicQuantitativeCheckResult const& dd) { + return dd.clone()->asSymbolicQuantitativeCheckResult(); + }) + .def("get_values", &storm::modelchecker::SymbolicQuantitativeCheckResult::getValueVector); ; - - py::class_, std::shared_ptr>> exactQuantitativeCheckResult(m, "_ExactQuantitativeCheckResult", "Abstract class for exact quantitative model checking results", checkResult); - py::class_, std::shared_ptr>>(m, "ExplicitExactQuantitativeCheckResult", "Explicit exact quantitative model checking result", exactQuantitativeCheckResult) + py::class_, + std::shared_ptr>>( + m, "HybridQuantitativeCheckResult", "Hybrid quantitative model checking result", quantitativeCheckResult) + .def("get_values", &storm::modelchecker::HybridQuantitativeCheckResult::getExplicitValueVector, + "Get model checking result values for all states"); + + py::class_, + std::shared_ptr>> + exactQuantitativeCheckResult(m, "_ExactQuantitativeCheckResult", "Abstract class for exact quantitative model checking results", checkResult); + py::class_, + std::shared_ptr>>( + m, "ExplicitExactQuantitativeCheckResult", "Explicit exact quantitative model checking result", exactQuantitativeCheckResult) .def(py::init>(), py::arg("values")) - .def("at", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& result, storm::storage::sparse::state_type state) { - return result[state]; - }, py::arg("state"), "Get result for given state") - .def("get_values", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getValueVector();}, "Get model checking result values for all states") - .def_property_readonly("scheduler", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) {return res.getScheduler();}, "get scheduler") - ; - py::class_, std::shared_ptr>>(m, "SymbolicExactQuantitativeCheckResult", "Symbolic exact quantitative model checking result", quantitativeCheckResult) - .def("clone", [](storm::modelchecker::SymbolicQuantitativeCheckResult const& dd) {return dd.clone()->asSymbolicQuantitativeCheckResult(); }) - ; - py::class_, std::shared_ptr>>(m, "HybridExactQuantitativeCheckResult", "Symbolic exact hybrid quantitative model checking result", quantitativeCheckResult) - .def("get_values", &storm::modelchecker::HybridQuantitativeCheckResult::getExplicitValueVector, "Get model checking result values for all states") - ; - - py::class_, std::shared_ptr>> parametricQuantitativeCheckResult(m, "_ParametricQuantitativeCheckResult", "Abstract class for parametric quantitative model checking results", checkResult); - py::class_, std::shared_ptr>>(m, "ExplicitParametricQuantitativeCheckResult", "Explicit parametric quantitative model checking result", parametricQuantitativeCheckResult) - .def("at", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& result, storm::storage::sparse::state_type state) { - return result[state]; - }, py::arg("state"), "Get result for given state") - .def("get_values", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getValueVector();}, "Get model checking result values for all states") - .def_property_readonly("scheduler", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) {return res.getScheduler();}, "get scheduler") - ; - py::class_, std::shared_ptr>>(m, "SymbolicParametricQuantitativeCheckResult", "Symbolic parametric quantitative model checking result", quantitativeCheckResult) - .def("clone", [](storm::modelchecker::SymbolicQuantitativeCheckResult const& dd) {return dd.clone()->asSymbolicQuantitativeCheckResult(); }) - ; - py::class_, std::shared_ptr>>(m, "HybridParametricQuantitativeCheckResult", "Symbolic parametric hybrid quantitative model checking result", quantitativeCheckResult) - .def("get_values", &storm::modelchecker::HybridQuantitativeCheckResult::getExplicitValueVector, "Get model checking result values for all states") - ; - - py::class_, std::shared_ptr>> pccheckresult(m, "ParetoCurveCheckResultDouble", "Result for multiobjective model checking", checkResult); + .def( + "at", + [](storm::modelchecker::ExplicitQuantitativeCheckResult const& result, storm::storage::sparse::state_type state) { + return result[state]; + }, + py::arg("state"), "Get result for given state") + .def( + "get_values", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getValueVector(); }, + "Get model checking result values for all states") + .def_property_readonly( + "scheduler", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getScheduler(); }, + "get scheduler"); + py::class_, + std::shared_ptr>>( + m, "SymbolicExactQuantitativeCheckResult", "Symbolic exact quantitative model checking result", quantitativeCheckResult) + .def("clone", [](storm::modelchecker::SymbolicQuantitativeCheckResult const& dd) { + return dd.clone()->asSymbolicQuantitativeCheckResult(); + }); + py::class_, + std::shared_ptr>>( + m, "HybridExactQuantitativeCheckResult", "Symbolic exact hybrid quantitative model checking result", quantitativeCheckResult) + .def("get_values", &storm::modelchecker::HybridQuantitativeCheckResult::getExplicitValueVector, + "Get model checking result values for all states"); + + py::class_, + std::shared_ptr>> + parametricQuantitativeCheckResult(m, "_ParametricQuantitativeCheckResult", "Abstract class for parametric quantitative model checking results", + checkResult); + py::class_, + std::shared_ptr>>( + m, "ExplicitParametricQuantitativeCheckResult", "Explicit parametric quantitative model checking result", parametricQuantitativeCheckResult) + .def( + "at", + [](storm::modelchecker::ExplicitQuantitativeCheckResult const& result, storm::storage::sparse::state_type state) { + return result[state]; + }, + py::arg("state"), "Get result for given state") + .def( + "get_values", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getValueVector(); }, + "Get model checking result values for all states") + .def_property_readonly( + "scheduler", [](storm::modelchecker::ExplicitQuantitativeCheckResult const& res) { return res.getScheduler(); }, + "get scheduler"); + py::class_, + std::shared_ptr>>( + m, "SymbolicParametricQuantitativeCheckResult", "Symbolic parametric quantitative model checking result", quantitativeCheckResult) + .def("clone", [](storm::modelchecker::SymbolicQuantitativeCheckResult const& dd) { + return dd.clone()->asSymbolicQuantitativeCheckResult(); + }); + py::class_, + std::shared_ptr>>( + m, "HybridParametricQuantitativeCheckResult", "Symbolic parametric hybrid quantitative model checking result", quantitativeCheckResult) + .def("get_values", &storm::modelchecker::HybridQuantitativeCheckResult::getExplicitValueVector, + "Get model checking result values for all states"); + + py::class_, std::shared_ptr>> pccheckresult( + m, "ParetoCurveCheckResultDouble", "Result for multiobjective model checking", checkResult); pccheckresult.def("get_underapproximation", &storm::modelchecker::ParetoCurveCheckResult::getUnderApproximation); pccheckresult.def("get_overapproximation", &storm::modelchecker::ParetoCurveCheckResult::getOverApproximation); - py::class_, std::shared_ptr>> epccheckresult(m, "ExplicitParetoCurveCheckResultDouble", "Result for explicit multiobjective model checking", pccheckresult); - - - m.def("create_filter_symbolic", &createFilterSymbolic, "Creates a filter for the given states and a symbolic model", py::arg("model"), py::arg("states")); - m.def("create_filter_initial_states_sparse", &createFilterInitialStatesSparse, "Create a filter for the initial states on a sparse model", py::arg("model")); - m.def("create_filter_initial_states_symbolic", &createFilterInitialStatesSymbolic, "Create a filter for the initial states on a symbolic model", py::arg("model")); - + py::class_, std::shared_ptr>> + epccheckresult(m, "ExplicitParetoCurveCheckResultDouble", "Result for explicit multiobjective model checking", pccheckresult); + m.def("create_filter_symbolic", &createFilterSymbolic, "Creates a filter for the given states and a symbolic model", + py::arg("model"), py::arg("states")); + m.def("create_filter_initial_states_sparse", &createFilterInitialStatesSparse, "Create a filter for the initial states on a sparse model", + py::arg("model")); + m.def("create_filter_initial_states_symbolic", &createFilterInitialStatesSymbolic, + "Create a filter for the initial states on a symbolic model", py::arg("model")); } - diff --git a/src/core/result.h b/src/core/result.h index 77601aad5d..c8c121dc0c 100644 --- a/src/core/result.h +++ b/src/core/result.h @@ -3,4 +3,3 @@ #include "common.h" void define_result(py::module& m); - diff --git a/src/core/simulator.cpp b/src/core/simulator.cpp index 0e2f99a81d..f2bdb6323c 100644 --- a/src/core/simulator.cpp +++ b/src/core/simulator.cpp @@ -4,12 +4,13 @@ #include #include -template +template using PLSim = storm::simulator::DiscreteTimePrismProgramSimulator; template void define_sparse_model_simulator(py::module& m, std::string const& vtSuffix) { - py::class_> dtsmsd(m, ("_DiscreteTimeSparseModelSimulator" + vtSuffix).c_str(), "Simulator for sparse discrete-time models in memory (for ValueType)"); + py::class_> dtsmsd(m, ("_DiscreteTimeSparseModelSimulator" + vtSuffix).c_str(), + "Simulator for sparse discrete-time models in memory (for ValueType)"); dtsmsd.def(py::init const&>()); dtsmsd.def("set_seed", &storm::simulator::DiscreteTimeSparseModelSimulator::setSeed, py::arg("seed")); dtsmsd.def("step", &storm::simulator::DiscreteTimeSparseModelSimulator::step, py::arg("action")); @@ -21,22 +22,38 @@ void define_sparse_model_simulator(py::module& m, std::string const& vtSuffix) { template void define_prism_program_simulator(py::module& m, std::string const& vtSuffix) { - py::class_> dtpps(m, ("_DiscreteTimePrismProgramSimulator" + vtSuffix).c_str(), "Simulator for prism programs"); + py::class_> dtpps(m, ("_DiscreteTimePrismProgramSimulator" + vtSuffix).c_str(), + "Simulator for prism programs"); dtpps.def(py::init(), py::arg("program"), py::arg("options")); dtpps.def("set_seed", &storm::simulator::DiscreteTimePrismProgramSimulator::setSeed, py::arg("seed")); - dtpps.def("step", &storm::simulator::DiscreteTimePrismProgramSimulator::step, py::arg("action_index"), "Make a step and randomly select the successor. The action is given as an argument, the index reflects the index of the getChoices vector that can be accessed."); - dtpps.def("get_action_indices", [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) { std::vector actionIndices; for(auto const& c : sim.getChoices()) {actionIndices.push_back(c.getActionIndex());} return actionIndices;}, "A list of choices that encode the possibilities in the current state."); - dtpps.def("get_number_of_current_choices", [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) {return sim.getChoices().size();}); + dtpps.def("step", &storm::simulator::DiscreteTimePrismProgramSimulator::step, py::arg("action_index"), + "Make a step and randomly select the successor. The action is given as an argument, the index reflects the index of the getChoices vector that " + "can be accessed."); + dtpps.def( + "get_action_indices", + [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) { + std::vector actionIndices; + for (auto const& c : sim.getChoices()) { + actionIndices.push_back(c.getActionIndex()); + } + return actionIndices; + }, + "A list of choices that encode the possibilities in the current state."); + dtpps.def("get_number_of_current_choices", + [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) { return sim.getChoices().size(); }); dtpps.def("get_current_state", &PLSim::getCurrentState, "Get current state"); dtpps.def("get_current_state_as_json", [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) { return sim.getStateAsJson(); }); - dtpps.def("get_current_observation_as_json", [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) { return sim.getObservationAsJson(); }); + dtpps.def("get_current_observation_as_json", + [](storm::simulator::DiscreteTimePrismProgramSimulator const& sim) { return sim.getObservationAsJson(); }); dtpps.def("get_current_state_is_sink", &storm::simulator::DiscreteTimePrismProgramSimulator::isSinkState); - dtpps.def("get_current_labels", &storm::simulator::DiscreteTimePrismProgramSimulator::getCurrentStateLabelling, "What are the state labels at the current state?"); + dtpps.def("get_current_labels", &storm::simulator::DiscreteTimePrismProgramSimulator::getCurrentStateLabelling, + "What are the state labels at the current state?"); dtpps.def("get_last_reward", &storm::simulator::DiscreteTimePrismProgramSimulator::getLastRewards); dtpps.def("reset_to_initial_state", &storm::simulator::DiscreteTimePrismProgramSimulator::resetToInitial, "Reset to the initial state"); - dtpps.def("_reset_to_state_from_valuation", [](PLSim& sim, storm::expressions::SimpleValuation const& state) {sim.resetToState(state);}); - dtpps.def("_reset_to_state_from_compressed_state", [](PLSim& sim, storm::generator::CompressedState const& state) {sim.resetToState(state);}); - dtpps.def("get_reward_names", &storm::simulator::DiscreteTimePrismProgramSimulator::getRewardNames, "Get names of the rewards provided by the simulator"); + dtpps.def("_reset_to_state_from_valuation", [](PLSim& sim, storm::expressions::SimpleValuation const& state) { sim.resetToState(state); }); + dtpps.def("_reset_to_state_from_compressed_state", [](PLSim& sim, storm::generator::CompressedState const& state) { sim.resetToState(state); }); + dtpps.def("get_reward_names", &storm::simulator::DiscreteTimePrismProgramSimulator::getRewardNames, + "Get names of the rewards provided by the simulator"); } template void define_sparse_model_simulator(py::module& m, std::string const& vtSuffix); diff --git a/src/core/transformation.cpp b/src/core/transformation.cpp index c7d99ac6ed..65d51ec05a 100644 --- a/src/core/transformation.cpp +++ b/src/core/transformation.cpp @@ -3,84 +3,92 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/api/transformation.h" #include "storm/models/symbolic/StandardRewardModel.h" -#include "storm/transformer/SubsystemBuilder.h" #include "storm/transformer/EndComponentEliminator.h" +#include "storm/transformer/SubsystemBuilder.h" // Thin wrappers. template -storm::transformer::SubsystemBuilderReturnType constructSubsystem(storm::models::sparse::Model const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates, storm::transformer::SubsystemBuilderOptions options) { +storm::transformer::SubsystemBuilderReturnType constructSubsystem(storm::models::sparse::Model const& originalModel, + storm::storage::BitVector const& subsystemStates, + storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates, + storm::transformer::SubsystemBuilderOptions options) { return storm::transformer::buildSubsystem(originalModel, subsystemStates, subsystemActions, keepUnreachableStates, options); } template -std::pair>, std::vector>> transformContinuousToDiscreteTimeSparseModel(std::shared_ptr> const& model, std::vector> const& formulas) { +std::pair>, std::vector>> +transformContinuousToDiscreteTimeSparseModel(std::shared_ptr> const& model, + std::vector> const& formulas) { return storm::api::transformContinuousToDiscreteTimeSparseModel(model, formulas); } template -typename storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType eliminateECs(storm::storage::SparseMatrix const& matrix, - storm::storage::BitVector const& subsystemStates, - storm::storage::BitVector const& possibleECRows, - storm::storage::BitVector const& addSinkRowStates, - bool addSelfLoopAtSinkStates) { +typename storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType eliminateECs( + storm::storage::SparseMatrix const& matrix, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& possibleECRows, + storm::storage::BitVector const& addSinkRowStates, bool addSelfLoopAtSinkStates) { return storm::transformer::EndComponentEliminator::transform(matrix, subsystemStates, possibleECRows, addSinkRowStates, addSelfLoopAtSinkStates); } - - void define_transformation(py::module& m) { // Transform model - m.def("_transform_to_sparse_model", &storm::api::transformSymbolicToSparseModel, "Transform symbolic model into sparse model", py::arg("model"), py::arg("formulae") = std::vector>()); - m.def("_transform_to_sparse_parametric_model", &storm::api::transformSymbolicToSparseModel, "Transform symbolic parametric model into sparse parametric model", py::arg("model"), py::arg("formulae") = std::vector>()); - - m.def("_transform_to_discrete_time_model", &transformContinuousToDiscreteTimeSparseModel, "Transform continuous time model to discrete time model", py::arg("model"), py::arg("formulae") = std::vector>()); - m.def("_transform_to_discrete_time_parametric_model", &transformContinuousToDiscreteTimeSparseModel, "Transform parametric continuous time model to parametric discrete time model", py::arg("model"), py::arg("formulae") = std::vector>()); + m.def("_transform_to_sparse_model", &storm::api::transformSymbolicToSparseModel, + "Transform symbolic model into sparse model", py::arg("model"), py::arg("formulae") = std::vector>()); + m.def("_transform_to_sparse_parametric_model", &storm::api::transformSymbolicToSparseModel, + "Transform symbolic parametric model into sparse parametric model", py::arg("model"), + py::arg("formulae") = std::vector>()); + + m.def("_transform_to_discrete_time_model", &transformContinuousToDiscreteTimeSparseModel, "Transform continuous time model to discrete time model", + py::arg("model"), py::arg("formulae") = std::vector>()); + m.def("_transform_to_discrete_time_parametric_model", &transformContinuousToDiscreteTimeSparseModel, + "Transform parametric continuous time model to parametric discrete time model", py::arg("model"), + py::arg("formulae") = std::vector>()); py::class_(m, "SubsystemBuilderOptions", "Options for constructing the subsystem") - .def(py::init<>()) - .def_readwrite("check_transitions_outside", &storm::transformer::SubsystemBuilderOptions::checkTransitionsOutside) - .def_readwrite("build_state_mapping", &storm::transformer::SubsystemBuilderOptions::buildStateMapping) - .def_readwrite("build_action_mapping", &storm::transformer::SubsystemBuilderOptions::buildActionMapping) - .def_readwrite("build_kept_actions", &storm::transformer::SubsystemBuilderOptions::buildKeptActions) - .def_readwrite("fix_deadlocks", &storm::transformer::SubsystemBuilderOptions::fixDeadlocks) - ; + .def(py::init<>()) + .def_readwrite("check_transitions_outside", &storm::transformer::SubsystemBuilderOptions::checkTransitionsOutside) + .def_readwrite("build_state_mapping", &storm::transformer::SubsystemBuilderOptions::buildStateMapping) + .def_readwrite("build_action_mapping", &storm::transformer::SubsystemBuilderOptions::buildActionMapping) + .def_readwrite("build_kept_actions", &storm::transformer::SubsystemBuilderOptions::buildKeptActions) + .def_readwrite("fix_deadlocks", &storm::transformer::SubsystemBuilderOptions::fixDeadlocks); // Non-Markovian chain elimination py::enum_(m, "EliminationLabelBehavior", "Behavior of labels while eliminating non-Markovian chains") .value("KEEP_LABELS", storm::transformer::EliminationLabelBehavior::KeepLabels) .value("MERGE_LABELS", storm::transformer::EliminationLabelBehavior::MergeLabels) - .value("DELETE_LABELS", storm::transformer::EliminationLabelBehavior::DeleteLabels) - ; - - m.def("_eliminate_non_markovian_chains", &storm::api::eliminateNonMarkovianChains, "Eliminate chains of non-Markovian states in Markov automaton.", py::arg("ma"), py::arg("formulae"), py::arg("label_behavior")); - m.def("_eliminate_non_markovian_chains_parametric", &storm::api::eliminateNonMarkovianChains, "Eliminate chains of non-Markovian states in Markov automaton.", py::arg("ma"), py::arg("formulae"), py::arg("label_behavior")); - - py::class_::EndComponentEliminatorReturnType>(m, "EndComponentEliminatorReturnTypeDouble", "Container for result of endcomponent elimination") - .def_readonly("matrix", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::matrix, "The resulting matrix") - .def_readonly("new_to_old_row_mapping", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::newToOldRowMapping, "Index mapping that gives for each row fo the new matrix the corresponding row in the original matrix") - .def_readonly("old_to_new_state_mapping", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::oldToNewStateMapping, "For each state of the original matrix (and subsystem) the corresponding state in the result. Removed states are mapped to the EC.") - .def_readonly("sink_rows", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::sinkRows, "Rows that indicate staying in the EC forever"); - - m.def("_eliminate_end_components_double", &eliminateECs, "Eliminate ECs in the subystem", py::arg("matrix"), py::arg("subsystem"), py::arg("possible_ec_rows"),py::arg("addSinkRowStates"), py::arg("addSelfLoopAtSinkStates")); - + .value("DELETE_LABELS", storm::transformer::EliminationLabelBehavior::DeleteLabels); + + m.def("_eliminate_non_markovian_chains", &storm::api::eliminateNonMarkovianChains, "Eliminate chains of non-Markovian states in Markov automaton.", + py::arg("ma"), py::arg("formulae"), py::arg("label_behavior")); + m.def("_eliminate_non_markovian_chains_parametric", &storm::api::eliminateNonMarkovianChains, + "Eliminate chains of non-Markovian states in Markov automaton.", py::arg("ma"), py::arg("formulae"), py::arg("label_behavior")); + + py::class_::EndComponentEliminatorReturnType>(m, "EndComponentEliminatorReturnTypeDouble", + "Container for result of endcomponent elimination") + .def_readonly("matrix", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::matrix, "The resulting matrix") + .def_readonly("new_to_old_row_mapping", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::newToOldRowMapping, + "Index mapping that gives for each row fo the new matrix the corresponding row in the original matrix") + .def_readonly("old_to_new_state_mapping", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::oldToNewStateMapping, + "For each state of the original matrix (and subsystem) the corresponding state in the result. Removed states are mapped to the EC.") + .def_readonly("sink_rows", &storm::transformer::EndComponentEliminator::EndComponentEliminatorReturnType::sinkRows, + "Rows that indicate staying in the EC forever"); + + m.def("_eliminate_end_components_double", &eliminateECs, "Eliminate ECs in the subystem", py::arg("matrix"), py::arg("subsystem"), + py::arg("possible_ec_rows"), py::arg("addSinkRowStates"), py::arg("addSelfLoopAtSinkStates")); } template void define_transformation_typed(py::module& m, std::string const& vtSuffix) { - py::class_>(m, ("SubsystemBuilderReturnType" + - vtSuffix).c_str(), + py::class_>(m, ("SubsystemBuilderReturnType" + vtSuffix).c_str(), "Result of the construction of a subsystem") - .def_readonly("model", &storm::transformer::SubsystemBuilderReturnType::model, "the submodel") - .def_readonly("new_to_old_state_mapping", - &storm::transformer::SubsystemBuilderReturnType::newToOldStateIndexMapping, - "for each state in result, the state index in the original model") - .def_readonly("new_to_old_action_mapping", - &storm::transformer::SubsystemBuilderReturnType::newToOldActionIndexMapping, - "for each action in result, the action index in the original model") - .def_readonly("kept_actions", &storm::transformer::SubsystemBuilderReturnType::keptActions, - "Actions of the subsystem available in the original system") - .def_readonly("deadlock_label", &storm::transformer::SubsystemBuilderReturnType::deadlockLabel, - "If set, deadlock states have been introduced and have been assigned this label"); + .def_readonly("model", &storm::transformer::SubsystemBuilderReturnType::model, "the submodel") + .def_readonly("new_to_old_state_mapping", &storm::transformer::SubsystemBuilderReturnType::newToOldStateIndexMapping, + "for each state in result, the state index in the original model") + .def_readonly("new_to_old_action_mapping", &storm::transformer::SubsystemBuilderReturnType::newToOldActionIndexMapping, + "for each action in result, the action index in the original model") + .def_readonly("kept_actions", &storm::transformer::SubsystemBuilderReturnType::keptActions, + "Actions of the subsystem available in the original system") + .def_readonly("deadlock_label", &storm::transformer::SubsystemBuilderReturnType::deadlockLabel, + "If set, deadlock states have been introduced and have been assigned this label"); m.def(("_construct_subsystem_" + vtSuffix).c_str(), &constructSubsystem, "build a subsystem of a sparse model"); } diff --git a/src/dft/analysis.cpp b/src/dft/analysis.cpp index 0ac72989c1..2c026966c8 100644 --- a/src/dft/analysis.cpp +++ b/src/dft/analysis.cpp @@ -1,16 +1,19 @@ #include "analysis.h" -#include "storm/adapters/RationalFunctionAdapter.h" -#include "storm-dft/parser/DFTJsonParser.h" #include "storm-dft/builder/ExplicitDFTModelBuilder.h" +#include "storm-dft/parser/DFTJsonParser.h" #include "storm-dft/storage/DftSymmetries.h" +#include "storm/adapters/RationalFunctionAdapter.h" -template using ExplicitDFTModelBuilder = storm::dft::builder::ExplicitDFTModelBuilder; +template +using ExplicitDFTModelBuilder = storm::dft::builder::ExplicitDFTModelBuilder; // Thin wrapper for DFT analysis template -std::vector analyzeDFT(storm::dft::storage::DFT const& dft, std::vector> const& properties, bool symred, bool allowModularisation, storm::dft::utility::RelevantEvents const& relevantEvents, bool allowDCForRelevant) { - typename storm::dft::modelchecker::DFTModelChecker::dft_results dftResults = storm::dft::api::analyzeDFT(dft, properties, symred, allowModularisation, relevantEvents, allowDCForRelevant, 0.0, storm::dft::builder::ApproximationHeuristic::DEPTH, false); +std::vector analyzeDFT(storm::dft::storage::DFT const& dft, std::vector> const& properties, + bool symred, bool allowModularisation, storm::dft::utility::RelevantEvents const& relevantEvents, bool allowDCForRelevant) { + typename storm::dft::modelchecker::DFTModelChecker::dft_results dftResults = storm::dft::api::analyzeDFT( + dft, properties, symred, allowModularisation, relevantEvents, allowDCForRelevant, 0.0, storm::dft::builder::ApproximationHeuristic::DEPTH, false); std::vector results; for (auto result : dftResults) { @@ -21,7 +24,9 @@ std::vector analyzeDFT(storm::dft::storage::DFT const& dft // Thin wrapper for building state space from DFT template -std::shared_ptr> buildModel(storm::dft::storage::DFT const& dft, storm::dft::storage::DftSymmetries const& symmetries, storm::dft::utility::RelevantEvents const& relevantEvents, bool allowDCForRelevant) { +std::shared_ptr> buildModel(storm::dft::storage::DFT const& dft, + storm::dft::storage::DftSymmetries const& symmetries, + storm::dft::utility::RelevantEvents const& relevantEvents, bool allowDCForRelevant) { dft.setRelevantEvents(relevantEvents, allowDCForRelevant); storm::dft::builder::ExplicitDFTModelBuilder builder(dft, symmetries); builder.buildModel(0, 0.0); @@ -30,44 +35,51 @@ std::shared_ptr> buildModel(storm::dft:: // Define python bindings void define_analysis(py::module& m) { - py::enum_(m, "ApproximationHeuristic", "Heuristic for selecting states to explore next") .value("DEPTH", storm::dft::builder::ApproximationHeuristic::DEPTH) .value("PROBABILITY", storm::dft::builder::ApproximationHeuristic::PROBABILITY) - .value("BOUNDDIFFERENCE", storm::dft::builder::ApproximationHeuristic::BOUNDDIFFERENCE) - ; + .value("BOUNDDIFFERENCE", storm::dft::builder::ApproximationHeuristic::BOUNDDIFFERENCE); // RelevantEvents - py::class_>(m, "RelevantEvents", "Relevant events which should be observed") + py::class_>(m, "RelevantEvents", + "Relevant events which should be observed") .def(py::init<>(), "Create empty list of relevant events") - .def("is_relevant", &storm::dft::utility::RelevantEvents::isRelevant, "Check whether the given name is a relevant event", py::arg("name")) - ; + .def("is_relevant", &storm::dft::utility::RelevantEvents::isRelevant, "Check whether the given name is a relevant event", py::arg("name")); - m.def("compute_relevant_events", &storm::dft::api::computeRelevantEvents, "Compute relevant event ids from properties and additional relevant names", py::arg("properties"), py::arg("additional_relevant_names") = std::vector()); + m.def("compute_relevant_events", &storm::dft::api::computeRelevantEvents, "Compute relevant event ids from properties and additional relevant names", + py::arg("properties"), py::arg("additional_relevant_names") = std::vector()); } template void define_analysis_typed(py::module& m, std::string const& vt_suffix) { - - py::class_, std::shared_ptr>>(m, ("ExplicitDFTModelBuilder"+vt_suffix).c_str(), "Builder to generate explicit model from DFT") - .def(py::init const&, storm::dft::storage::DftSymmetries const&>(), "Constructor", py::arg("dft"), py::arg("symmetries")=storm::dft::storage::DftSymmetries()) - .def("build", &ExplicitDFTModelBuilder::buildModel, "Build state space of model", py::arg("iteration"), py::arg("approximation_threshold")=0.0, py::arg("approximation_heuristic")=storm::dft::builder::ApproximationHeuristic::DEPTH) + py::class_, std::shared_ptr>>(m, ("ExplicitDFTModelBuilder" + vt_suffix).c_str(), + "Builder to generate explicit model from DFT") + .def(py::init const&, storm::dft::storage::DftSymmetries const&>(), "Constructor", py::arg("dft"), + py::arg("symmetries") = storm::dft::storage::DftSymmetries()) + .def("build", &ExplicitDFTModelBuilder::buildModel, "Build state space of model", py::arg("iteration"), + py::arg("approximation_threshold") = 0.0, py::arg("approximation_heuristic") = storm::dft::builder::ApproximationHeuristic::DEPTH) .def("get_model", &ExplicitDFTModelBuilder::getModel, "Get complete model") - .def("get_partial_model", &ExplicitDFTModelBuilder::getModelApproximation, "Get partial model", py::arg("lower_bound"), py::arg("expected_time")) - ; + .def("get_partial_model", &ExplicitDFTModelBuilder::getModelApproximation, "Get partial model", py::arg("lower_bound"), + py::arg("expected_time")); - m.def(("_analyze_dft"+vt_suffix).c_str(), &analyzeDFT, "Analyze the DFT", py::arg("dft"), py::arg("properties"), py::arg("symred")=true, py::arg("allow_modularisation")=false, py::arg("relevant_events")=storm::dft::utility::RelevantEvents(), py::arg("allow_dc_for_relevant")=false); + m.def(("_analyze_dft" + vt_suffix).c_str(), &analyzeDFT, "Analyze the DFT", py::arg("dft"), py::arg("properties"), py::arg("symred") = true, + py::arg("allow_modularisation") = false, py::arg("relevant_events") = storm::dft::utility::RelevantEvents(), + py::arg("allow_dc_for_relevant") = false); - m.def(("_build_model"+vt_suffix).c_str(), &buildModel, "Build state-space model (CTMC or MA) for DFT", py::arg("dft"), py::arg("symmetries"), py::arg("relevant_events")=storm::dft::utility::RelevantEvents(), py::arg("allow_dc_for_relevant")=false); + m.def(("_build_model" + vt_suffix).c_str(), &buildModel, "Build state-space model (CTMC or MA) for DFT", py::arg("dft"), py::arg("symmetries"), + py::arg("relevant_events") = storm::dft::utility::RelevantEvents(), py::arg("allow_dc_for_relevant") = false); - m.def(("_transform_dft"+vt_suffix).c_str(), &storm::dft::api::applyTransformations, "Apply transformations on DFT", py::arg("dft"), py::arg("unique_constant_be"), py::arg("binary_fdeps"), py::arg("exponential_distributions")); + m.def(("_transform_dft" + vt_suffix).c_str(), &storm::dft::api::applyTransformations, "Apply transformations on DFT", py::arg("dft"), + py::arg("unique_constant_be"), py::arg("binary_fdeps"), py::arg("exponential_distributions")); - m.def(("_compute_dependency_conflicts"+vt_suffix).c_str(), &storm::dft::api::computeDependencyConflicts, "Set conflicts between FDEPs. Is used in analysis.", py::arg("dft"), py::arg("use_smt") = false, py::arg("solver_timeout") = 0); + m.def(("_compute_dependency_conflicts" + vt_suffix).c_str(), &storm::dft::api::computeDependencyConflicts, + "Set conflicts between FDEPs. Is used in analysis.", py::arg("dft"), py::arg("use_smt") = false, py::arg("solver_timeout") = 0); - m.def(("_is_well_formed"+vt_suffix).c_str(), &storm::dft::api::isWellFormed, "Check whether DFT is well-formed.", py::arg("dft"), py::arg("check_valid_for_analysis") = true); - m.def(("_has_potential_modeling_issues"+vt_suffix).c_str(), &storm::dft::api::hasPotentialModelingIssues, "Check whether DFT has potential modeling issues.", py::arg("dft")); + m.def(("_is_well_formed" + vt_suffix).c_str(), &storm::dft::api::isWellFormed, "Check whether DFT is well-formed.", py::arg("dft"), + py::arg("check_valid_for_analysis") = true); + m.def(("_has_potential_modeling_issues" + vt_suffix).c_str(), &storm::dft::api::hasPotentialModelingIssues, + "Check whether DFT has potential modeling issues.", py::arg("dft")); } - template void define_analysis_typed(py::module& m, std::string const& vt_suffix); template void define_analysis_typed(py::module& m, std::string const& vt_suffix); diff --git a/src/dft/dft.cpp b/src/dft/dft.cpp index 5e2638e2c9..7bafe18a00 100644 --- a/src/dft/dft.cpp +++ b/src/dft/dft.cpp @@ -1,18 +1,19 @@ #include "dft.h" #include "src/helpers.h" -#include "storm/adapters/RationalFunctionAdapter.h" -#include "storm/settings/SettingsManager.h" -#include "storm-dft/settings/modules/FaultTreeSettings.h" #include "storm-dft/settings/modules/DftIOSettings.h" +#include "storm-dft/settings/modules/FaultTreeSettings.h" #include "storm-dft/storage/DFT.h" #include "storm-dft/storage/DftSymmetries.h" #include "storm-dft/utility/DftModularizer.h" #include "storm-dft/utility/SymmetryFinder.h" +#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/settings/SettingsManager.h" - -template using DFT = storm::dft::storage::DFT; -template using DFTElement = storm::dft::storage::elements::DFTElement; +template +using DFT = storm::dft::storage::DFT; +template +using DFTElement = storm::dft::storage::elements::DFTElement; // requires pycarl.Variable std::set getParameters(DFT const& dft) { @@ -20,11 +21,13 @@ std::set getParameters(DFT(); storm::settings::addModule(); - }, "Initialize Storm-dft"); + }, + "Initialize Storm-dft"); m.def("get_parameters", &getParameters, "Collect parameters in parametric DFT", py::arg("dft")); } @@ -32,46 +35,43 @@ void define_dft(py::module& m) { template void define_dft_typed(py::module& m, std::string const& vt_suffix) { // DFT class - py::class_, std::shared_ptr>>(m, ("DFT"+vt_suffix).c_str(), "Dynamic Fault Tree") + py::class_, std::shared_ptr>>(m, ("DFT" + vt_suffix).c_str(), "Dynamic Fault Tree") .def("nr_elements", &DFT::nrElements, "Total number of elements") .def("nr_be", &DFT::nrBasicElements, "Number of basic elements") .def("nr_dynamic", &DFT::nrDynamicElements, "Number of dynamic elements") .def("can_have_nondeterminism", &DFT::canHaveNondeterminism, "Whether the model can contain non-deterministic choices") .def("__str__", &DFT::getInfoString) .def("str_long", &DFT::getElementsString) - .def_property_readonly("top_level_element", [](DFT& dft) { - return dft.getElement(dft.getTopLevelIndex()); - }, "Get top level element") + .def_property_readonly( + "top_level_element", [](DFT& dft) { return dft.getElement(dft.getTopLevelIndex()); }, "Get top level element") .def("get_element", &DFT::getElement, "Get DFT element at index", py::arg("index")) - .def("get_element_by_name", [](DFT& dft, std::string const& name) { - return dft.getElement(dft.getIndex(name)); - }, "Get DFT element by name", py::arg("name")) - .def("modules", [](DFT const& dft) { + .def( + "get_element_by_name", [](DFT& dft, std::string const& name) { return dft.getElement(dft.getIndex(name)); }, "Get DFT element by name", + py::arg("name")) + .def( + "modules", + [](DFT const& dft) { storm::dft::utility::DftModularizer modularizer; return modularizer.computeModules(dft); - }, "Compute independent modules of DFT") - .def("symmetries", [](DFT& dft) { - return storm::dft::utility::SymmetryFinder::findSymmetries(dft); - }, "Compute symmetries in DFT") - .def("state_generation_info", &DFT::buildStateGenerationInfo, "Build state generation information", py::arg("symmetries")=storm::dft::storage::DftSymmetries()) - .def("set_relevant_events", &DFT::setRelevantEvents, py::arg("relevant_events"), py::arg("allow_dc_for_revelant")) - ; + }, + "Compute independent modules of DFT") + .def( + "symmetries", [](DFT& dft) { return storm::dft::utility::SymmetryFinder::findSymmetries(dft); }, "Compute symmetries in DFT") + .def("state_generation_info", &DFT::buildStateGenerationInfo, "Build state generation information", + py::arg("symmetries") = storm::dft::storage::DftSymmetries()) + .def("set_relevant_events", &DFT::setRelevantEvents, py::arg("relevant_events"), py::arg("allow_dc_for_revelant")); } - void define_symmetries(py::module& m) { - py::class_>(m, "DftSymmetries", "Symmetries in DFT") .def(py::init<>(), "Constructor for empty symmetry") .def("__len__", &storm::dft::storage::DftSymmetries::nrSymmetries) - .def("__iter__", [](storm::dft::storage::DftSymmetries const& symmetries) { - return py::make_iterator(symmetries.begin(), symmetries.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def( + "__iter__", [](storm::dft::storage::DftSymmetries const& symmetries) { return py::make_iterator(symmetries.begin(), symmetries.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) .def("get_group", &storm::dft::storage::DftSymmetries::getSymmetryGroup, "Get symmetry group", py::arg("index")) - .def("__str__", &streamToString) - ; + .def("__str__", &streamToString); } - template void define_dft_typed(py::module& m, std::string const& vt_suffix); template void define_dft_typed(py::module& m, std::string const& vt_suffix); diff --git a/src/dft/dft_elements.cpp b/src/dft/dft_elements.cpp index 1cfd2fe6ff..7539c87efa 100644 --- a/src/dft/dft_elements.cpp +++ b/src/dft/dft_elements.cpp @@ -1,16 +1,16 @@ #include "dft_elements.h" #include "src/helpers.h" -#include "storm/adapters/RationalFunctionAdapter.h" #include "storm-dft/storage/elements/DFTElements.h" +#include "storm/adapters/RationalFunctionAdapter.h" - -template using DFTElement = storm::dft::storage::elements::DFTElement; -template using BE = storm::dft::storage::elements::DFTBE; -template using Dependency = storm::dft::storage::elements::DFTDependency; - +template +using DFTElement = storm::dft::storage::elements::DFTElement; +template +using BE = storm::dft::storage::elements::DFTBE; +template +using Dependency = storm::dft::storage::elements::DFTDependency; void define_dft_elements(py::module& m) { - // DFT element type py::enum_(m, "DFTElementType") .value("BE", storm::dft::storage::elements::DFTElementType::BE) @@ -23,35 +23,28 @@ void define_dft_elements(py::module& m) { .value("PDEP", storm::dft::storage::elements::DFTElementType::PDEP) .value("SEQ", storm::dft::storage::elements::DFTElementType::SEQ) .value("MUTEX", storm::dft::storage::elements::DFTElementType::MUTEX) - .def("__str__", [](storm::dft::storage::elements::DFTElementType type) { - return storm::dft::storage::elements::toString(type); - }, py::prepend() /* use custom method instead of default enum overload */) - ; + .def( + "__str__", [](storm::dft::storage::elements::DFTElementType type) { return storm::dft::storage::elements::toString(type); }, + py::prepend() /* use custom method instead of default enum overload */); } template void define_dft_elements_typed(py::module& m, std::string const& vt_suffix) { - // DFT elements - py::class_, std::shared_ptr>> element(m, ("DFTElement"+vt_suffix).c_str(), "DFT element"); + py::class_, std::shared_ptr>> element(m, ("DFTElement" + vt_suffix).c_str(), "DFT element"); element.def_property_readonly("id", &DFTElement::id, "Id") .def_property_readonly("name", &DFTElement::name, "Name") .def_property_readonly("type", &DFTElement::type, "Type") - .def("__str__", &DFTElement::toString) - ; + .def("__str__", &DFTElement::toString); - py::class_, std::shared_ptr>>(m, ("DFTBE"+vt_suffix).c_str(), "Basic Event", element) - .def("__str__", &BE::toString) - ; + py::class_, std::shared_ptr>>(m, ("DFTBE" + vt_suffix).c_str(), "Basic Event", element) + .def("__str__", &BE::toString); - py::class_, std::shared_ptr>>(m, ("DFTDependency"+vt_suffix).c_str(), "Dependency", element) + py::class_, std::shared_ptr>>(m, ("DFTDependency" + vt_suffix).c_str(), "Dependency", element) .def_property_readonly("trigger", &Dependency::triggerEvent, "Trigger event") .def_property_readonly("dependent_events", &Dependency::dependentEvents, "Dependent events") - .def("__str__", &Dependency::toString) - ; - + .def("__str__", &Dependency::toString); } - template void define_dft_elements_typed(py::module& m, std::string const& vt_suffix); template void define_dft_elements_typed(py::module& m, std::string const& vt_suffix); diff --git a/src/dft/dft_state.cpp b/src/dft/dft_state.cpp index acec545da6..8eaf230868 100644 --- a/src/dft/dft_state.cpp +++ b/src/dft/dft_state.cpp @@ -1,46 +1,39 @@ #include "dft_state.h" #include "src/helpers.h" -#include "storm/adapters/RationalFunctionAdapter.h" #include "storm-dft/storage/DFTState.h" #include "storm-dft/storage/FailableElements.h" +#include "storm/adapters/RationalFunctionAdapter.h" - -template using DFTState = storm::dft::storage::DFTState; +template +using DFTState = storm::dft::storage::DFTState; typedef storm::dft::storage::FailableElements Failable; typedef storm::dft::storage::FailableElements::const_iterator FailableIter; template void define_dft_state(py::module& m, std::string const& vt_suffix) { - // DFT state - py::class_, std::shared_ptr>>(m, ("DFTState"+vt_suffix).c_str(), "DFT state") + py::class_, std::shared_ptr>>(m, ("DFTState" + vt_suffix).c_str(), "DFT state") .def("operational", &DFTState::isOperational, "Is element operational", py::arg("id")) - .def("failed", [](DFTState const& state, size_t id) { - return state.hasFailed(id); - }, "Is element failed", py::arg("id")) - .def("failsafe", [](DFTState const& state, size_t id) { - return state.isFailsafe(id); - }, "Is element fail-safe", py::arg("id")) + .def( + "failed", [](DFTState const& state, size_t id) { return state.hasFailed(id); }, "Is element failed", py::arg("id")) + .def( + "failsafe", [](DFTState const& state, size_t id) { return state.isFailsafe(id); }, "Is element fail-safe", py::arg("id")) .def("dontcare", &DFTState::dontCare, "Is element Don't Care", py::arg("id")) .def("invalid", &DFTState::isInvalid, "Is state invalid") .def("failable", &DFTState::getFailableElements, "Get failable elements") .def("spare_uses", &DFTState::uses, "Child currently used by a SPARE", py::arg("spare_id")) - .def("__str__", [](DFTState const& state) { - return streamToString(state.status()); - }) - .def("to_string", [](std::shared_ptr> const& state, storm::dft::storage::DFT const& dft) { - return dft.getStateString(state); - }, "Print status", py::arg("dft")) - ; + .def("__str__", [](DFTState const& state) { return streamToString(state.status()); }) + .def( + "to_string", + [](std::shared_ptr> const& state, storm::dft::storage::DFT const& dft) { return dft.getStateString(state); }, + "Print status", py::arg("dft")); } - void define_failable_elements(py::module& m) { - // Helper iterator for access from python // We need to manually create the bindings (and not use make_iterator) as we need access to the iterator (and not only the value). struct FailableIterator { - FailableIterator(Failable const &failable, py::object ref) : failable(failable), ref(ref), it(failable.begin()) { } + FailableIterator(Failable const& failable, py::object ref) : failable(failable), ref(ref), it(failable.begin()) {} FailableIter next() { if (it == failable.end()) { @@ -53,29 +46,25 @@ void define_failable_elements(py::module& m) { } Failable const& failable; - py::object ref; // keep a reference + py::object ref; // keep a reference FailableIter it; }; py::class_>(m, "FailableElements", "Failable elements in DFT state") - .def("__iter__", [](py::object s) { return FailableIterator(s.cast(), s); }, py::keep_alive<0, 1>()) - ; + .def("__iter__", [](py::object s) { return FailableIterator(s.cast(), s); }, py::keep_alive<0, 1>()); py::class_(m, "FailableIterator") - .def("__iter__", [](FailableIterator &it) -> FailableIterator& { return it; }, py::keep_alive<0, 1>()) - .def("__next__", &FailableIterator::next, py::keep_alive<0, 1>()) - ; + .def( + "__iter__", [](FailableIterator& it) -> FailableIterator& { return it; }, py::keep_alive<0, 1>()) + .def("__next__", &FailableIterator::next, py::keep_alive<0, 1>()); py::class_>(m, "FailableElement", "Failable element") .def("is_due_dependency", &FailableIter::isFailureDueToDependency, "Is failure due to dependency") .def("as_be_double", &FailableIter::asBE, py::arg("dft"), "Get BE which fails") .def("as_be_ratfunc", &FailableIter::asBE, py::arg("dft"), "Get BE which fails") .def("as_dependency_double", &FailableIter::asDependency, py::arg("dft"), "Get dependency which is triggered") - .def("as_dependency_ratfunc", &FailableIter::asDependency, py::arg("dft"), "Get dependency which is triggered") - ; - + .def("as_dependency_ratfunc", &FailableIter::asDependency, py::arg("dft"), "Get dependency which is triggered"); } - template void define_dft_state(py::module& m, std::string const& vt_suffix); template void define_dft_state(py::module& m, std::string const& vt_suffix); diff --git a/src/dft/io.cpp b/src/dft/io.cpp index ca0c64bbcb..3ecd55c492 100644 --- a/src/dft/io.cpp +++ b/src/dft/io.cpp @@ -1,25 +1,26 @@ #include "io.h" #include "src/helpers.h" - // Define python bindings void define_input(py::module& m) { - // Load DFT input m.def("load_dft_galileo_file", &storm::dft::api::loadDFTGalileoFile, "Load DFT from Galileo file", py::arg("path")); - m.def("load_parametric_dft_galileo_file", &storm::dft::api::loadDFTGalileoFile, "Load parametric DFT from Galileo file", py::arg("path")); + m.def("load_parametric_dft_galileo_file", &storm::dft::api::loadDFTGalileoFile, "Load parametric DFT from Galileo file", + py::arg("path")); // Parse Jani model m.def("load_dft_json_file", &storm::dft::api::loadDFTJsonFile, "Load DFT from JSON file", py::arg("path")); m.def("load_dft_json_string", &storm::dft::api::loadDFTJsonString, "Load DFT from JSON string", py::arg("json_string")); m.def("load_parametric_dft_json_file", &storm::dft::api::loadDFTJsonFile, "Load parametric DFT from JSON file", py::arg("path")); - m.def("load_parametric_dft_json_string", &storm::dft::api::loadDFTJsonString, "Load parametric DFT from JSON string", py::arg("json_string")); + m.def("load_parametric_dft_json_string", &storm::dft::api::loadDFTJsonString, "Load parametric DFT from JSON string", + py::arg("json_string")); } void define_output(py::module& m) { - // Export DFT m.def("export_dft_json_file", &storm::dft::api::exportDFTToJsonFile, "Export DFT to JSON file", py::arg("dft"), py::arg("path")); m.def("export_dft_json_string", &storm::dft::api::exportDFTToJsonString, "Export DFT to JSON string", py::arg("dft")); - m.def("export_parametric_dft_json_file", &storm::dft::api::exportDFTToJsonFile, "Export parametric DFT to JSON file", py::arg("dft"), py::arg("path")); - m.def("export_parametric_dft_json_string", &storm::dft::api::exportDFTToJsonString, "Export parametric DFT to JSON string", py::arg("dft")); + m.def("export_parametric_dft_json_file", &storm::dft::api::exportDFTToJsonFile, "Export parametric DFT to JSON file", + py::arg("dft"), py::arg("path")); + m.def("export_parametric_dft_json_string", &storm::dft::api::exportDFTToJsonString, "Export parametric DFT to JSON string", + py::arg("dft")); } diff --git a/src/dft/module.cpp b/src/dft/module.cpp index 7f7355fc71..f7b1940cc4 100644 --- a/src/dft/module.cpp +++ b/src/dft/module.cpp @@ -5,7 +5,6 @@ using DftIndependentModule = storm::dft::storage::DftIndependentModule; void define_module(py::module& m) { - py::class_>(m, "DftIndependentModule", "Independent module in DFT") .def("static", &DftIndependentModule::isStatic, "Whether the module contains only static elements (except in submodules)") .def("fully_static", &DftIndependentModule::isFullyStatic, "Whether the module contains only static elements (also in submodules)") @@ -14,6 +13,5 @@ void define_module(py::module& m) { .def("elements", &DftIndependentModule::getElements, "Get elements of module (excluding submodules)") .def("submodules", &DftIndependentModule::getSubModules, "Get submodules") .def("_subtree_double", &DftIndependentModule::getSubtree, "Get subtree formed by module", py::arg("dft")) - .def("_subtree_ratfunc", &DftIndependentModule::getSubtree, "Get subtree formed by module", py::arg("dft")) - ; + .def("_subtree_ratfunc", &DftIndependentModule::getSubtree, "Get subtree formed by module", py::arg("dft")); } diff --git a/src/dft/simulator.cpp b/src/dft/simulator.cpp index 9ddbcfa5ed..6f12b20f0e 100644 --- a/src/dft/simulator.cpp +++ b/src/dft/simulator.cpp @@ -1,57 +1,48 @@ #include "simulator.h" #include "src/helpers.h" -#include "storm-dft/simulator/DFTTraceSimulator.h" #include "storm-dft/api/storm-dft.h" #include "storm-dft/generator/DftNextStateGenerator.h" +#include "storm-dft/simulator/DFTTraceSimulator.h" - -template using Simulator = storm::dft::simulator::DFTTraceSimulator; +template +using Simulator = storm::dft::simulator::DFTTraceSimulator; typedef storm::dft::storage::DFTStateGenerationInfo DFTStateInfo; typedef boost::mt19937 RandomGenerator; - void define_simulator(py::module& m) { - // Simulation result py::enum_(m, "SimulationStepResult") .value("SUCCESSFUL", storm::dft::simulator::SimulationStepResult::SUCCESSFUL) .value("UNSUCCESSFUL", storm::dft::simulator::SimulationStepResult::UNSUCCESSFUL) - .value("INVALID", storm::dft::simulator::SimulationStepResult::INVALID) - ; + .value("INVALID", storm::dft::simulator::SimulationStepResult::INVALID); py::enum_(m, "SimulationTraceResult") .value("SUCCESSFUL", storm::dft::simulator::SimulationTraceResult::SUCCESSFUL) .value("UNSUCCESSFUL", storm::dft::simulator::SimulationTraceResult::UNSUCCESSFUL) .value("INVALID", storm::dft::simulator::SimulationTraceResult::INVALID) - .value("CONTINUE", storm::dft::simulator::SimulationTraceResult::CONTINUE) - ; - py::class_>(m, "DFTStateInfo", "State Generation Info for DFT") - ; + .value("CONTINUE", storm::dft::simulator::SimulationTraceResult::CONTINUE); + py::class_>(m, "DFTStateInfo", "State Generation Info for DFT"); py::class_>(m, "RandomGenerator", "Random number generator") - .def_static("create", [](unsigned int seed) -> RandomGenerator { - return RandomGenerator(seed); - }, py::arg("seed"), "Initialize random number generator") - ; + .def_static( + "create", [](unsigned int seed) -> RandomGenerator { return RandomGenerator(seed); }, py::arg("seed"), "Initialize random number generator"); } - template void define_simulator_typed(py::module& m, std::string const& vt_suffix) { - // Simulator for DFTs - py::class_, std::shared_ptr>>(m, ("DFTSimulator"+vt_suffix).c_str(), "Simulator for DFT traces") - .def(py::init const&, DFTStateInfo const&, RandomGenerator&>(), py::keep_alive<1,2>(), py::keep_alive<1, 3>(), py::keep_alive<1,4>(), py::arg("dft"), py::arg("state_generation_info"), py::arg("generator"), "Create Simulator") + py::class_, std::shared_ptr>>(m, ("DFTSimulator" + vt_suffix).c_str(), "Simulator for DFT traces") + .def(py::init const&, DFTStateInfo const&, RandomGenerator&>(), py::keep_alive<1, 2>(), py::keep_alive<1, 3>(), + py::keep_alive<1, 4>(), py::arg("dft"), py::arg("state_generation_info"), py::arg("generator"), "Create Simulator") .def("reset", &Simulator::resetToInitial, "Reset to initial state") .def("reset_state", &Simulator::resetToState, py::arg("state"), "Reset to state") .def("get_state", &Simulator::getCurrentState, "Get current state") .def("get_time", &Simulator::getCurrentTime, "Get total elapsed time so far") - .def("step", &Simulator::step, py::arg("next_failure"), py::arg("dependency_success") = true, "Perform simulation step according to next_failure. For PDEPs, dependency_success determines whether the PDEP was successful or not.") + .def("step", &Simulator::step, py::arg("next_failure"), py::arg("dependency_success") = true, + "Perform simulation step according to next_failure. For PDEPs, dependency_success determines whether the PDEP was successful or not.") .def("random_step", &Simulator::randomStep, "Perform random simulation step.") - .def("simulate_trace", &Simulator::simulateCompleteTrace, py::arg("timebound"), "Simulate complete trace for given timebound") - ; + .def("simulate_trace", &Simulator::simulateCompleteTrace, py::arg("timebound"), "Simulate complete trace for given timebound"); } - template void define_simulator_typed(py::module& m, std::string const& vt_suffix); template void define_simulator_typed(py::module& m, std::string const& vt_suffix); diff --git a/src/dft/transformations.cpp b/src/dft/transformations.cpp index bce242e05c..2182435099 100644 --- a/src/dft/transformations.cpp +++ b/src/dft/transformations.cpp @@ -1,16 +1,13 @@ #include "dft.h" #include "src/helpers.h" -#include "storm/adapters/RationalFunctionAdapter.h" #include "storm-dft/transformations/DftInstantiator.h" +#include "storm/adapters/RationalFunctionAdapter.h" using DFTInstantiator = storm::dft::transformations::DftInstantiator; void define_transformations(py::module& m) { - py::class_>(m, "DFTInstantiator", "Instantiator for parametric DFT") .def(py::init const&>(), "Initialize with parametric DFT", py::arg("dft")) - .def("instantiate", &DFTInstantiator::instantiate, "Instantiate parametric DFT and obtain concrete DFT", py::arg("valuation")) - ; + .def("instantiate", &DFTInstantiator::instantiate, "Instantiate parametric DFT and obtain concrete DFT", py::arg("valuation")); } - diff --git a/src/gspn/gspn.cpp b/src/gspn/gspn.cpp index c0663bbf85..1f82ffba6a 100644 --- a/src/gspn/gspn.cpp +++ b/src/gspn/gspn.cpp @@ -2,8 +2,8 @@ #include "src/helpers.h" #include "storm-gspn/storage/gspn/GSPN.h" #include "storm-gspn/storage/gspn/GspnBuilder.h" -#include "storm/settings/SettingsManager.h" #include "storm/io/file.h" +#include "storm/settings/SettingsManager.h" using GSPN = storm::gspn::GSPN; using GSPNBuilder = storm::gspn::GspnBuilder; @@ -14,23 +14,19 @@ using ImmediateTransition = storm::gspn::ImmediateTransition; using Transition = storm::gspn::Transition; using TransitionPartition = storm::gspn::TransitionPartition; - void gspnToFile(GSPN const& gspn, std::string const& filepath, bool toPnpro) { std::ofstream fs; storm::io::openFile(filepath, fs); - if(toPnpro) { + if (toPnpro) { gspn.toPnpro(fs); - } - else { + } else { gspn.toPnml(fs); } storm::io::closeFile(fs); } - void define_gspn(py::module& m) { - // GSPN_Builder class py::class_>(m, "GSPNBuilder", "Generalized Stochastic Petri Net Builder") .def(py::init(), "Constructor") @@ -44,9 +40,13 @@ void define_gspn(py::module& m) { :param stormpy.LayoutInfo layout_info: The layout information. )doc") - .def("add_immediate_transition", &GSPNBuilder::addImmediateTransition, "Add an immediate transition to the GSPN", "priority"_a = 0, "weight"_a = 0, "name"_a = "") - .def("add_timed_transition", py::overload_cast(&GSPNBuilder::addTimedTransition), "Add a timed transition to the GSPN", "priority"_a, "rate"_a, "name"_a = "") - .def("add_timed_transition", py::overload_cast const&, std::string const&>(&GSPNBuilder::addTimedTransition), "priority"_a, "rate"_a, "num_servers"_a, "name"_a = "") + .def("add_immediate_transition", &GSPNBuilder::addImmediateTransition, "Add an immediate transition to the GSPN", "priority"_a = 0, "weight"_a = 0, + "name"_a = "") + .def("add_timed_transition", py::overload_cast(&GSPNBuilder::addTimedTransition), + "Add a timed transition to the GSPN", "priority"_a, "rate"_a, "name"_a = "") + .def("add_timed_transition", + py::overload_cast const&, std::string const&>(&GSPNBuilder::addTimedTransition), + "priority"_a, "rate"_a, "num_servers"_a, "name"_a = "") .def("set_transition_layout_info", &GSPNBuilder::setTransitionLayoutInfo, "transition_id"_a, "layout_info"_a, R"doc( Set transition layout information. @@ -54,7 +54,8 @@ void define_gspn(py::module& m) { :param stormpy.LayoutInfo layout_info: The layout information. )doc") - .def("add_input_arc", py::overload_cast(&GSPNBuilder::addInputArc), "from"_a , "to"_a, "multiplicity"_a = 1, R"doc( + .def("add_input_arc", py::overload_cast(&GSPNBuilder::addInputArc), "from"_a, "to"_a, + "multiplicity"_a = 1, R"doc( Add a new input arc from a place to a transition :param from: The ID or name of the place from which the arc is originating. @@ -63,8 +64,10 @@ void define_gspn(py::module& m) { :type from: uint_64_t or str :param uint64_t multiplicity: The multiplicity of the arc, default = 1. )doc") - .def("add_input_arc", py::overload_cast(&GSPNBuilder::addInputArc), "from"_a, "to"_a, "multiplicity"_a = 1) - .def("add_inhibition_arc", py::overload_cast(&GSPNBuilder::addInhibitionArc), "from"_a, "to"_a, "multiplicity"_a = 1, R"doc( + .def("add_input_arc", py::overload_cast(&GSPNBuilder::addInputArc), "from"_a, "to"_a, + "multiplicity"_a = 1) + .def("add_inhibition_arc", py::overload_cast(&GSPNBuilder::addInhibitionArc), + "from"_a, "to"_a, "multiplicity"_a = 1, R"doc( Add an new inhibition arc from a place to a transition. :param from: The ID or name of the place from which the arc is originating. @@ -73,8 +76,10 @@ void define_gspn(py::module& m) { :type to: uint_64_t or str :param uint64_t multiplicity: The multiplicity of the arc, default = 1. )doc") - .def("add_inhibition_arc", py::overload_cast(&GSPNBuilder::addInhibitionArc), "from"_a, "to"_a, "multiplicity"_a = 1) - .def("add_output_arc", py::overload_cast(&GSPNBuilder::addOutputArc), "from"_a, "to"_a, "multiplicity"_a = 1, R"doc( + .def("add_inhibition_arc", py::overload_cast(&GSPNBuilder::addInhibitionArc), "from"_a, "to"_a, + "multiplicity"_a = 1) + .def("add_output_arc", py::overload_cast(&GSPNBuilder::addOutputArc), "from"_a, + "to"_a, "multiplicity"_a = 1, R"doc( Add an new output arc from a transition to a place. :param from: The ID or name of the transition from which the arc is originating. @@ -83,7 +88,8 @@ void define_gspn(py::module& m) { :type to: uint_64_t or str :param uint64_t multiplicity: The multiplicity of the arc, default = 1. )doc") - .def("add_output_arc", py::overload_cast(&GSPNBuilder::addOutputArc), "from"_a, "to"_a, "multiplicity"_a) + .def("add_output_arc", py::overload_cast(&GSPNBuilder::addOutputArc), "from"_a, "to"_a, + "multiplicity"_a) .def("add_normal_arc", &GSPNBuilder::addNormalArc, "from"_a, "to"_a, "multiplicity"_a = 1, R"doc( Add an arc from a named element to a named element. Can be both input or output arc, but not an inhibition arc. @@ -94,15 +100,17 @@ void define_gspn(py::module& m) { :param uint64_t multiplicity: Multiplicity of the arc, default = 1. )doc") - .def("build_gspn", &GSPNBuilder::buildGspn, "Construct GSPN", "expression_manager"_a = nullptr, "constants_substitution"_a = std::map()) - ; + .def("build_gspn", &GSPNBuilder::buildGspn, "Construct GSPN", "expression_manager"_a = nullptr, + "constants_substitution"_a = std::map()); // GSPN class py::class_>(m, "GSPN", "Generalized Stochastic Petri Net") // Constructor - .def(py::init const&, std::vector const&, - std::vector const&, std::vector const&, std::shared_ptr const&, std::map const&>(), "name"_a, "places"_a, "immediate_transitions"_a, "timed_transitions"_a, "partitions"_a, "expression_manager"_a, "constants_substitution"_a = std::map()) + .def(py::init const&, std::vector const&, std::vector const&, + std::vector const&, std::shared_ptr const&, + std::map const&>(), + "name"_a, "places"_a, "immediate_transitions"_a, "timed_transitions"_a, "partitions"_a, "expression_manager"_a, + "constants_substitution"_a = std::map()) .def("get_name", &GSPN::getName, "Get name of GSPN") .def("set_name", &GSPN::setName, "Set name of GSPN") @@ -111,16 +119,24 @@ void define_gspn(py::module& m) { .def("get_number_of_immediate_transitions", &GSPN::getNumberOfImmediateTransitions, "Get the number of immediate transitions in this GSPN") .def("get_number_of_timed_transitions", &GSPN::getNumberOfTimedTransitions, "Get the number of timed transitions in this GSPN") - .def("get_place", [](GSPN const& g, uint64_t id) -> const Place& {return *(g.getPlace(id)); }, "id"_a, R"doc( + .def( + "get_place", [](GSPN const& g, uint64_t id) -> const Place& { return *(g.getPlace(id)); }, "id"_a, R"doc( Returns the place with the corresponding id. :param uint64_t id: The ID of the place. :rtype: stormpy.Place )doc") - .def("get_place", [](GSPN const& g, std::string const& name) -> const Place& {return *(g.getPlace(name)); }, "name"_a) - .def("get_timed_transition", [](GSPN const& g, std::string const& name) -> const TimedTransition& {return *(g.getTimedTransition(name)); }, "name"_a, "Returns the timed transition with the corresponding name") - .def("get_immediate_transition", [](GSPN const& g, std::string const& name) -> const ImmediateTransition& {return *(g.getImmediateTransition(name)); }, "name"_a, "Returns the immediate transition with the corresponding name") - .def("get_transition",[](GSPN const& g, std::string const& name) -> const Transition& {return *(g.getTransition(name)); }, "name"_a, "Returns the transition with the corresponding name") + .def( + "get_place", [](GSPN const& g, std::string const& name) -> const Place& { return *(g.getPlace(name)); }, "name"_a) + .def( + "get_timed_transition", [](GSPN const& g, std::string const& name) -> const TimedTransition& { return *(g.getTimedTransition(name)); }, "name"_a, + "Returns the timed transition with the corresponding name") + .def( + "get_immediate_transition", [](GSPN const& g, std::string const& name) -> const ImmediateTransition& { return *(g.getImmediateTransition(name)); }, + "name"_a, "Returns the immediate transition with the corresponding name") + .def( + "get_transition", [](GSPN const& g, std::string const& name) -> const Transition& { return *(g.getTransition(name)); }, "name"_a, + "Returns the transition with the corresponding name") .def("get_partitions", &GSPN::getPartitions, "Get the partitions of this GSPN") .def("get_places", &GSPN::getPlaces, R"doc( @@ -143,15 +159,17 @@ void define_gspn(py::module& m) { .def("is_valid", &GSPN::isValid, "Perform some checks") // GSPN export - .def("export_gspn_pnpro_file", [](GSPN& g, std::string const& filepath) -> void { gspnToFile(g, filepath, true); }, "filepath"_a, "Export GSPN to PNPRO file") - .def("export_gspn_pnml_file", [](GSPN& g, std::string const& filepath) -> void { gspnToFile(g, filepath, false); }, "filepath"_a, "Export GSPN to PNML file") + .def( + "export_gspn_pnpro_file", [](GSPN& g, std::string const& filepath) -> void { gspnToFile(g, filepath, true); }, "filepath"_a, + "Export GSPN to PNPRO file") + .def( + "export_gspn_pnml_file", [](GSPN& g, std::string const& filepath) -> void { gspnToFile(g, filepath, false); }, "filepath"_a, + "Export GSPN to PNML file") .def_static("timed_transition_id_to_transition_id", &GSPN::timedTransitionIdToTransitionId) .def_static("immediate_transition_id_to_transition_id", &GSPN::immediateTransitionIdToTransitionId) .def_static("transition_id_to_timed_transition_id", &GSPN::transitionIdToTimedTransitionId) - .def_static("transition_id_to_immediate_transition_id", &GSPN::transitionIdToImmediateTransitionId) - ; - + .def_static("transition_id_to_immediate_transition_id", &GSPN::transitionIdToImmediateTransitionId); // LayoutInfo class py::class_(m, "LayoutInfo") @@ -159,8 +177,7 @@ void define_gspn(py::module& m) { .def(py::init(), "x"_a, "y"_a, "rotation"_a = 0.0) .def_readwrite("x", &LayoutInfo::x) .def_readwrite("y", &LayoutInfo::y) - .def_readwrite("rotation", &LayoutInfo::rotation) - ; + .def_readwrite("rotation", &LayoutInfo::rotation); // Place class py::class_>(m, "Place", "Place in a GSPN") @@ -172,8 +189,7 @@ void define_gspn(py::module& m) { .def("get_number_of_initial_tokens", &Place::getNumberOfInitialTokens, "Get the number of initial tokens of this place") .def("set_capacity", &Place::setCapacity, "cap"_a, "Set the capacity of tokens of this place") // problem: boost or lambda [](.. .def("get_capacity", &Place::getCapacity, "Get the capacity of tokens of this place") - .def("has_restricted_capacity", &Place::hasRestrictedCapacity, "Is capacity of this place restricted") - ; + .def("has_restricted_capacity", &Place::hasRestrictedCapacity, "Is capacity of this place restricted"); // Transition class py::class_>(m, "Transition", "Transition in a GSPN") @@ -184,17 +200,21 @@ void define_gspn(py::module& m) { .def("set_priority", &Transition::setPriority, "priority"_a, "Set priority of this transition") .def("get_priority", &Transition::getPriority, "Get priority of this transition") - .def("set_input_arc_multiplicity", &Transition::setInputArcMultiplicity, "place"_a, "multiplicity"_a, "Set the multiplicity of the input arc originating from the place.") + .def("set_input_arc_multiplicity", &Transition::setInputArcMultiplicity, "place"_a, "multiplicity"_a, + "Set the multiplicity of the input arc originating from the place.") .def("remove_input_arc", &Transition::removeInputArc, "place"_a, "Remove an input arc connected to a given place.") .def("exists_input_arc", &Transition::existsInputArc, "place"_a, "Check whether the given place is connected to this transition via an input arc.") - .def("set_output_arc_multiplicity", &Transition::setOutputArcMultiplicity, "place"_a, "multiplicity"_a, "Set the multiplicity of the output arc going to the place.") + .def("set_output_arc_multiplicity", &Transition::setOutputArcMultiplicity, "place"_a, "multiplicity"_a, + "Set the multiplicity of the output arc going to the place.") .def("remove_output_arc", &Transition::removeOutputArc, "place"_a, "Remove an output arc connected to a given place.") .def("exists_output_arc", &Transition::existsOutputArc, "place"_a, "Check whether the given place is connected to this transition via an output arc.") - .def("set_inhibition_arc_multiplicity", &Transition::setInhibitionArcMultiplicity, "place"_a, "multiplicity"_a, "Set the multiplicity of the inhibition arc originating from the place.") + .def("set_inhibition_arc_multiplicity", &Transition::setInhibitionArcMultiplicity, "place"_a, "multiplicity"_a, + "Set the multiplicity of the inhibition arc originating from the place.") .def("remove_inhibition_arc", &Transition::removeInhibitionArc, "place"_a, "Remove an inhibition arc connected to a given place.") - .def("exists_inhibition_arc", &Transition::existsInhibitionArc, "place"_a, "Check whether the given place is connected to this transition via an inhibition arc.") + .def("exists_inhibition_arc", &Transition::existsInhibitionArc, "place"_a, + "Check whether the given place is connected to this transition via an inhibition arc.") .def("get_input_places", &Transition::getInputPlaces) .def("get_output_places", &Transition::getOutputPlaces) @@ -207,7 +227,7 @@ void define_gspn(py::module& m) { .def("is_enabled", &Transition::isEnabled, "marking"_a, "Check if the given marking enables the transition.") .def("fire", &Transition::fire, "marking"_a, "Fire the transition if possible.") - ; + ; // TimedTransition class py::class_>(m, "TimedTransition", "TimedTransition in a GSPN") @@ -220,23 +240,19 @@ void define_gspn(py::module& m) { .def("has_k_server_semantics", &TimedTransition::hasKServerSemantics, "Get semantics of this transition") .def("has_single_server_semantics", &TimedTransition::hasSingleServerSemantics, "Get semantics of this transition") .def("has_infinite_server_semantics", &TimedTransition::hasInfiniteServerSemantics, "Get semantics of this transition") - .def("get_number_of_servers", &TimedTransition::getNumberOfServers, "Get number of servers") - ; + .def("get_number_of_servers", &TimedTransition::getNumberOfServers, "Get number of servers"); // ImmediateTransition class py::class_>(m, "ImmediateTransition", "ImmediateTransition in a GSPN") .def(py::init<>()) .def("get_weight", &ImmediateTransition::getWeight, "Get weight of this transition") .def("set_weight", &ImmediateTransition::setWeight, "weight"_a, "Set weight of this transition") - .def("no_weight_attached", &ImmediateTransition::noWeightAttached, "True iff no weight is attached") - ; + .def("no_weight_attached", &ImmediateTransition::noWeightAttached, "True iff no weight is attached"); // TransitionPartition class py::class_(m, "TransitionPartition") - .def(py::init<>()) - .def_readwrite("priority", &TransitionPartition::priority) - .def_readwrite("transitions", &TransitionPartition::transitions) - .def("nr_transitions", &TransitionPartition::nrTransitions, "Get number of transitions") - ; - + .def(py::init<>()) + .def_readwrite("priority", &TransitionPartition::priority) + .def_readwrite("transitions", &TransitionPartition::transitions) + .def("nr_transitions", &TransitionPartition::nrTransitions, "Get number of transitions"); } diff --git a/src/gspn/gspn.h b/src/gspn/gspn.h index cc43acd297..17d58eabc4 100644 --- a/src/gspn/gspn.h +++ b/src/gspn/gspn.h @@ -3,5 +3,3 @@ #include "common.h" void define_gspn(py::module& m); - - diff --git a/src/gspn/gspn_io.cpp b/src/gspn/gspn_io.cpp index 9ed9330623..900105b87d 100644 --- a/src/gspn/gspn_io.cpp +++ b/src/gspn/gspn_io.cpp @@ -1,26 +1,26 @@ #include "gspn_io.h" #include "src/helpers.h" -#include "storm-gspn/storage/gspn/GSPN.h" #include "storm-gspn/parser/GspnParser.h" +#include "storm-gspn/storage/gspn/GSPN.h" using GSPN = storm::gspn::GSPN; using GSPNParser = storm::parser::GspnParser; using GSPNJaniBuilder = storm::builder::JaniGSPNBuilder; - void define_gspn_io(py::module& m) { - // GspnParser class py::class_>(m, "GSPNParser") - .def(py::init<>()) - .def("parse", [](GSPNParser& p, std::string const& filename, std::string const& constantDefinitions) -> GSPN& {return *(p.parse(filename,constantDefinitions)); }, "filename"_a, "constant_definitions"_a = "") - ; + .def(py::init<>()) + .def( + "parse", + [](GSPNParser& p, std::string const& filename, std::string const& constantDefinitions) -> GSPN& { + return *(p.parse(filename, constantDefinitions)); + }, + "filename"_a, "constant_definitions"_a = ""); // GspnToJani builder py::class_>(m, "GSPNToJaniBuilder") - .def(py::init(), py::arg("gspn")) - .def("build", &GSPNJaniBuilder::build, py::arg("automaton_name") = "gspn_automaton", "Build Jani model from GSPN") - .def("create_deadlock_properties", &GSPNJaniBuilder::getDeadlockProperties, py::arg("jani_model"), "Create standard properties for deadlocks") - ; - + .def(py::init(), py::arg("gspn")) + .def("build", &GSPNJaniBuilder::build, py::arg("automaton_name") = "gspn_automaton", "Build Jani model from GSPN") + .def("create_deadlock_properties", &GSPNJaniBuilder::getDeadlockProperties, py::arg("jani_model"), "Create standard properties for deadlocks"); } diff --git a/src/gspn/gspn_io.h b/src/gspn/gspn_io.h index ef4c1e1dd7..654fd3b14e 100644 --- a/src/gspn/gspn_io.h +++ b/src/gspn/gspn_io.h @@ -3,4 +3,3 @@ #include "common.h" void define_gspn_io(py::module& m); - diff --git a/src/helpers.h b/src/helpers.h index 9aec2ad854..052737ca33 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -28,4 +28,3 @@ std::string containerToString(T& t) { // Be warned: Enabling something like this will break everything about Monomial, // as to Python the shared_ptr (Arg) IS the Monomial // //PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); - diff --git a/src/logic/formulae.cpp b/src/logic/formulae.cpp index 46ccaed610..10a169d0f3 100644 --- a/src/logic/formulae.cpp +++ b/src/logic/formulae.cpp @@ -1,120 +1,160 @@ #include "formulae.h" -#include "storm/logic/Formulas.h" +#include "storm/adapters/RationalNumberAdapter.h" #include "storm/logic/CloneVisitor.h" +#include "storm/logic/Formulas.h" #include "storm/logic/LabelSubstitutionVisitor.h" #include "storm/storage/expressions/Variable.h" -#include "storm/adapters/RationalNumberAdapter.h" - void define_formulae(py::module& m) { - py::enum_(m, "ComparisonType") .value("LESS", storm::logic::ComparisonType::Less) .value("LEQ", storm::logic::ComparisonType::LessEqual) .value("GREATER", storm::logic::ComparisonType::Greater) - .value("GEQ", storm::logic::ComparisonType::GreaterEqual) - ; - + .value("GEQ", storm::logic::ComparisonType::GreaterEqual); py::enum_(m, "BinaryBooleanOperatorType") - .value("AND", storm::logic::BinaryBooleanOperatorType::And) - .value("OR", storm::logic::BinaryBooleanOperatorType::Or); - + .value("AND", storm::logic::BinaryBooleanOperatorType::And) + .value("OR", storm::logic::BinaryBooleanOperatorType::Or); py::class_> formula(m, "Formula", "Generic Storm Formula"); formula.def("__str__", &storm::logic::Formula::toString) - .def("clone", [](storm::logic::Formula const& f) { storm::logic::CloneVisitor cv; return cv.clone(f);}) - .def("substitute", [](storm::logic::Formula const& f, std::map const& map) { return f.substitute(map); }, "Substitute variables", py::arg("constants_map")) - .def("substitute_labels_by_labels", [](storm::logic::Formula const& f, std::map const& labelSubs) {storm::logic::LabelSubstitutionVisitor lsv(labelSubs); return lsv.substitute(f);}, "substitute label occurences", py::arg("replacements")) + .def("clone", + [](storm::logic::Formula const& f) { + storm::logic::CloneVisitor cv; + return cv.clone(f); + }) + .def( + "substitute", + [](storm::logic::Formula const& f, std::map const& map) { return f.substitute(map); }, + "Substitute variables", py::arg("constants_map")) + .def( + "substitute_labels_by_labels", + [](storm::logic::Formula const& f, std::map const& labelSubs) { + storm::logic::LabelSubstitutionVisitor lsv(labelSubs); + return lsv.substitute(f); + }, + "substitute label occurences", py::arg("replacements")) .def_property_readonly("is_probability_operator", &storm::logic::Formula::isProbabilityOperatorFormula, "is it a probability operator") .def_property_readonly("is_reward_operator", &storm::logic::Formula::isRewardOperatorFormula, "is it a reward operator") .def_property_readonly("is_eventually_formula", &storm::logic::Formula::isEventuallyFormula) .def_property_readonly("is_bounded_until_formula", &storm::logic::Formula::isBoundedUntilFormula) .def_property_readonly("is_until_formula", &storm::logic::Formula::isUntilFormula) - .def_property_readonly("is_multi_objective_formula", &storm::logic::Formula::isMultiObjectiveFormula) - ; + .def_property_readonly("is_multi_objective_formula", &storm::logic::Formula::isMultiObjectiveFormula); // Path Formulae - py::class_> pathFormula(m, "PathFormula", "Formula about the probability of a set of paths in an automaton", formula); - py::class_> unaryPathFormula(m, "UnaryPathFormula", "Path formula with one operand", pathFormula); + py::class_> pathFormula( + m, "PathFormula", "Formula about the probability of a set of paths in an automaton", formula); + py::class_> unaryPathFormula(m, "UnaryPathFormula", + "Path formula with one operand", pathFormula); unaryPathFormula.def_property_readonly("subformula", &storm::logic::UnaryPathFormula::getSubformula, "the subformula"); - py::class_>(m, "EventuallyFormula", "Formula for eventually", unaryPathFormula); + py::class_>(m, "EventuallyFormula", "Formula for eventually", + unaryPathFormula); py::class_>(m, "GloballyFormula", "Formula for globally", unaryPathFormula); - py::class_> binaryPathFormula(m, "BinaryPathFormula", "Path formula with two operands", pathFormula); + py::class_> binaryPathFormula( + m, "BinaryPathFormula", "Path formula with two operands", pathFormula); binaryPathFormula.def_property_readonly("left_subformula", &storm::logic::BinaryPathFormula::getLeftSubformula); binaryPathFormula.def_property_readonly("right_subformula", &storm::logic::BinaryPathFormula::getRightSubformula); - py::class_>(m, "BoundedUntilFormula", "Until Formula with either a step or a time bound.", binaryPathFormula) - .def_property_readonly("is_multidimensional", &storm::logic::BoundedUntilFormula::isMultiDimensional, "Is the bound multi-dimensional") - .def_property_readonly("has_lower_bound", [](storm::logic::BoundedUntilFormula const& form) { return form.hasLowerBound(); }) - .def_property_readonly("upper_bound_expression", [](storm::logic::BoundedUntilFormula const& form) { return form.getUpperBound(); } ) - .def_property_readonly("left_subformula", [](storm::logic::BoundedUntilFormula const& form) -> storm::logic::Formula const& { return form.getLeftSubformula(); }, py::return_value_policy::reference_internal) - .def_property_readonly("right_subformula", [](storm::logic::BoundedUntilFormula const& form)-> storm::logic::Formula const& { return form.getRightSubformula(); }, py::return_value_policy::reference_internal); - py::class_>(m, "ConditionalFormula", "Formula with the right hand side being a condition.", formula); - py::class_>(m, "UntilFormula", "Path Formula for unbounded until", binaryPathFormula); + py::class_>( + m, "BoundedUntilFormula", "Until Formula with either a step or a time bound.", binaryPathFormula) + .def_property_readonly("is_multidimensional", &storm::logic::BoundedUntilFormula::isMultiDimensional, "Is the bound multi-dimensional") + .def_property_readonly("has_lower_bound", [](storm::logic::BoundedUntilFormula const& form) { return form.hasLowerBound(); }) + .def_property_readonly("upper_bound_expression", [](storm::logic::BoundedUntilFormula const& form) { return form.getUpperBound(); }) + .def_property_readonly( + "left_subformula", [](storm::logic::BoundedUntilFormula const& form) -> storm::logic::Formula const& { return form.getLeftSubformula(); }, + py::return_value_policy::reference_internal) + .def_property_readonly( + "right_subformula", [](storm::logic::BoundedUntilFormula const& form) -> storm::logic::Formula const& { return form.getRightSubformula(); }, + py::return_value_policy::reference_internal); + py::class_>( + m, "ConditionalFormula", "Formula with the right hand side being a condition.", formula); + py::class_>(m, "UntilFormula", "Path Formula for unbounded until", + binaryPathFormula); // Reward Path Formulae - //py::class_(m, "RewardPathFormula", "Formula about the rewards of a set of paths in an automaton", py::base()); - py::class_>(m, "CumulativeRewardFormula", "Summed rewards over a the paths", pathFormula); - py::class_>(m ,"InstantaneousRewardFormula", "Instantaneous reward", pathFormula); - py::class_>(m, "LongRunAverageRewardFormula", "Long run average reward", pathFormula); - //py::class_>(m, "ReachabilityRewardFormula", "Reachability reward", py::base()); - + // py::class_(m, "RewardPathFormula", "Formula about the rewards of a set + // of paths in an automaton", py::base()); + py::class_>(m, "CumulativeRewardFormula", + "Summed rewards over a the paths", pathFormula); + py::class_>(m, "InstantaneousRewardFormula", + "Instantaneous reward", pathFormula); + py::class_>(m, "LongRunAverageRewardFormula", + "Long run average reward", pathFormula); + // py::class_>(m, "ReachabilityRewardFormula", + // "Reachability reward", py::base()); // State Formulae - py::class_> stateFormula(m, "StateFormula", "Formula about a state of an automaton", formula); - py::class_>(m, "AtomicExpressionFormula", "Formula with an atomic expression", stateFormula) + py::class_> stateFormula(m, "StateFormula", "Formula about a state of an automaton", + formula); + py::class_>(m, "AtomicExpressionFormula", + "Formula with an atomic expression", stateFormula) .def("get_expression", &storm::logic::AtomicExpressionFormula::getExpression); - py::class_>(m, "AtomicLabelFormula", "Formula with an atomic label", stateFormula) + py::class_>(m, "AtomicLabelFormula", "Formula with an atomic label", + stateFormula) .def_property_readonly("label", &storm::logic::AtomicLabelFormula::getLabel, "label in the formula"); - py::class_>(m, "BooleanLiteralFormula", "Formula with a boolean literal", stateFormula) - .def(py::init(),"truth value"_a); - py::class_> unaryStateFormula(m, "UnaryStateFormula", "State formula with one operand", stateFormula); + py::class_>(m, "BooleanLiteralFormula", + "Formula with a boolean literal", stateFormula) + .def(py::init(), "truth value"_a); + py::class_> unaryStateFormula( + m, "UnaryStateFormula", "State formula with one operand", stateFormula); unaryStateFormula.def_property_readonly("subformula", &storm::logic::UnaryStateFormula::getSubformula, "the subformula"); - py::class_>(m, "UnaryBooleanStateFormula", "Unary boolean state formula", unaryStateFormula); - py::class_> operatorFormula(m, "OperatorFormula", "Operator formula", unaryStateFormula); + py::class_>( + m, "UnaryBooleanStateFormula", "Unary boolean state formula", unaryStateFormula); + py::class_> operatorFormula(m, "OperatorFormula", "Operator formula", + unaryStateFormula); operatorFormula.def_property_readonly("has_bound", &storm::logic::OperatorFormula::hasBound, "Flag if formula is bounded") - .def_property("comparison_type", &storm::logic::OperatorFormula::getComparisonType, &storm::logic::OperatorFormula::setComparisonType, "Comparison type of bound") - .def_property_readonly("threshold", [](storm::logic::OperatorFormula const& f) { - if (f.getThreshold().containsVariables()) { - throw std::runtime_error("To obtain the threshold as an expression, use threshold_expr"); - } - if (f.getThreshold().hasRationalType()) { - return f.getThresholdAs(); - } else if (f.getThreshold().hasIntegerType()) { - return storm::utility::convertNumber(f.getThreshold().evaluateAsInt()); - } else { - throw std::runtime_error("Can't get non-rational threshold (not implemented)"); - } - }, "Threshold of bound (currently only applicable to rational expressions)") - .def_property_readonly("threshold_expr", [](storm::logic::OperatorFormula const& f) { - return f.getThreshold(); - }) - .def("set_bound", [](storm::logic::OperatorFormula& f, storm::logic::ComparisonType comparisonType, storm::expressions::Expression const& bound) { - f.setBound(storm::logic::Bound(comparisonType, bound)); - }, "Set bound", py::arg("comparison_type"), py::arg("bound")) + .def_property("comparison_type", &storm::logic::OperatorFormula::getComparisonType, &storm::logic::OperatorFormula::setComparisonType, + "Comparison type of bound") + .def_property_readonly( + "threshold", + [](storm::logic::OperatorFormula const& f) { + if (f.getThreshold().containsVariables()) { + throw std::runtime_error("To obtain the threshold as an expression, use threshold_expr"); + } + if (f.getThreshold().hasRationalType()) { + return f.getThresholdAs(); + } else if (f.getThreshold().hasIntegerType()) { + return storm::utility::convertNumber(f.getThreshold().evaluateAsInt()); + } else { + throw std::runtime_error("Can't get non-rational threshold (not implemented)"); + } + }, + "Threshold of bound (currently only applicable to rational expressions)") + .def_property_readonly("threshold_expr", [](storm::logic::OperatorFormula const& f) { return f.getThreshold(); }) + .def( + "set_bound", + [](storm::logic::OperatorFormula& f, storm::logic::ComparisonType comparisonType, storm::expressions::Expression const& bound) { + f.setBound(storm::logic::Bound(comparisonType, bound)); + }, + "Set bound", py::arg("comparison_type"), py::arg("bound")) .def("remove_bound", &storm::logic::OperatorFormula::removeBound) - .def_property_readonly("has_optimality_type", &storm::logic::OperatorFormula::hasOptimalityType, "Flag if an optimality type is present") + .def_property_readonly("has_optimality_type", &storm::logic::OperatorFormula::hasOptimalityType, "Flag if an optimality type is present") .def_property_readonly("optimality_type", &storm::logic::OperatorFormula::getOptimalityType, "Flag for the optimality type") - .def("set_optimality_type", &storm::logic::OperatorFormula::setOptimalityType, "set the optimality type (use remove optimiality type for clearing)", "new_optimality_type"_a) + .def("set_optimality_type", &storm::logic::OperatorFormula::setOptimalityType, "set the optimality type (use remove optimiality type for clearing)", + "new_optimality_type"_a) .def("remove_optimality_type", &storm::logic::OperatorFormula::removeOptimalityType, "remove the optimality type") - ; + ; py::class_>(m, "TimeOperator", "The time operator", operatorFormula); - py::class_>(m, "LongRunAvarageOperator", "Long run average operator", operatorFormula); - py::class_>(m, "ProbabilityOperator", "Probability operator", operatorFormula) - .def(py::init>(), "construct probability operator formula", py::arg("subformula")) - ; + py::class_>( + m, "LongRunAvarageOperator", "Long run average operator", operatorFormula); + py::class_>(m, "ProbabilityOperator", + "Probability operator", operatorFormula) + .def(py::init>(), "construct probability operator formula", py::arg("subformula")); - py::class_>(m, "RewardOperator", "Reward operator", operatorFormula) - .def("has_reward_name", &storm::logic::RewardOperatorFormula::hasRewardModelName) - .def_property_readonly("reward_name", &storm::logic::RewardOperatorFormula::getRewardModelName); - py::class_> binaryStateFormula(m, "BinaryStateFormula", "State formula with two operands", stateFormula); - py::class_>(m, "BooleanBinaryStateFormula", "Boolean binary state formula", binaryStateFormula); + py::class_>(m, "RewardOperator", "Reward operator", + operatorFormula) + .def("has_reward_name", &storm::logic::RewardOperatorFormula::hasRewardModelName) + .def_property_readonly("reward_name", &storm::logic::RewardOperatorFormula::getRewardModelName); + py::class_> binaryStateFormula( + m, "BinaryStateFormula", "State formula with two operands", stateFormula); + py::class_>( + m, "BooleanBinaryStateFormula", "Boolean binary state formula", binaryStateFormula); - py::class_>(m, "MultiObjectiveFormula", "Multi objective formula", formula) - .def_property_readonly("subformulas", &storm::logic::MultiObjectiveFormula::getSubformulas, "Get vector of subformulas") - .def_property_readonly("nr_subformulas", &storm::logic::MultiObjectiveFormula::getNumberOfSubformulas, "Get number of subformulas"); + py::class_>(m, "MultiObjectiveFormula", "Multi objective formula", + formula) + .def_property_readonly("subformulas", &storm::logic::MultiObjectiveFormula::getSubformulas, "Get vector of subformulas") + .def_property_readonly("nr_subformulas", &storm::logic::MultiObjectiveFormula::getNumberOfSubformulas, "Get number of subformulas"); py::class_>(m, "GameFormula", "Game formula", unaryStateFormula) - .def_property_readonly("is_game_formula", &storm::logic::GameFormula::isGameFormula, "is it a game formula"); + .def_property_readonly("is_game_formula", &storm::logic::GameFormula::isGameFormula, "is it a game formula"); } diff --git a/src/mod_core.cpp b/src/mod_core.cpp index 4363adb935..44dca2e2a0 100644 --- a/src/mod_core.cpp +++ b/src/mod_core.cpp @@ -1,15 +1,15 @@ #include "common.h" -#include "core/core.h" -#include "core/result.h" -#include "core/modelchecking.h" -#include "core/bisimulation.h" -#include "core/input.h" #include "core/analysis.h" +#include "core/bisimulation.h" +#include "core/core.h" #include "core/counterexample.h" #include "core/environment.h" -#include "core/transformation.h" +#include "core/input.h" +#include "core/modelchecking.h" +#include "core/result.h" #include "core/simulator.h" +#include "core/transformation.h" PYBIND11_MODULE(_core, m) { m.doc() = "core"; @@ -43,5 +43,4 @@ PYBIND11_MODULE(_core, m) { define_sparse_model_simulator(m, "Double"); define_sparse_model_simulator(m, "Exact"); define_prism_program_simulator(m, "Double"); - } diff --git a/src/mod_dft.cpp b/src/mod_dft.cpp index b051df979f..b9b4326cf8 100644 --- a/src/mod_dft.cpp +++ b/src/mod_dft.cpp @@ -17,7 +17,7 @@ PYBIND11_MODULE(_dft, m) { options.disable_function_signatures(); #endif - define_symmetries(m); // Must be before define_analysis_typed + define_symmetries(m); // Must be before define_analysis_typed define_analysis(m); define_analysis_typed(m, "_double"); define_analysis_typed(m, "_ratfunc"); diff --git a/src/mod_info.cpp b/src/mod_info.cpp index b3fd07ec7f..8e8f477f41 100644 --- a/src/mod_info.cpp +++ b/src/mod_info.cpp @@ -12,12 +12,17 @@ PYBIND11_MODULE(_info, m) { py::class_(m, "Version", "Version information for Storm") // static properties are still called with self as argument (which we ignore), see // https://pybind11.readthedocs.io/en/stable/advanced/classes.html#static-properties - .def_property_readonly_static("major", [](py::object /* self */){ return storm::StormVersion::versionMajor; }, "Storm major version.") - .def_property_readonly_static("minor", [](py::object /* self */){ return storm::StormVersion::versionMinor; }, "Storm minor version.") - .def_property_readonly_static("patch", [](py::object /* self */){ return storm::StormVersion::versionPatch; }, "Storm patch version.") - .def_property_readonly_static("development", [](py::object /* self */){ return storm::StormVersion::versionDev; }, "Flag if Storm is development version.") - .def_property_readonly_static("short", [](py::object /* self */){ return storm::StormVersion::shortVersionString(); }, "Storm version in short representation.") - .def_property_readonly_static("long", [](py::object /* self */){ return storm::StormVersion::longVersionString(); }, "Storm version in long representation.") - .def_property_readonly_static("build_info", [](py::object /* self */){ return storm::StormVersion::buildInfo(); }, "Build info for Storm.") - ; + .def_property_readonly_static( + "major", [](py::object /* self */) { return storm::StormVersion::versionMajor; }, "Storm major version.") + .def_property_readonly_static( + "minor", [](py::object /* self */) { return storm::StormVersion::versionMinor; }, "Storm minor version.") + .def_property_readonly_static( + "patch", [](py::object /* self */) { return storm::StormVersion::versionPatch; }, "Storm patch version.") + .def_property_readonly_static( + "development", [](py::object /* self */) { return storm::StormVersion::versionDev; }, "Flag if Storm is development version.") + .def_property_readonly_static( + "short", [](py::object /* self */) { return storm::StormVersion::shortVersionString(); }, "Storm version in short representation.") + .def_property_readonly_static( + "long", [](py::object /* self */) { return storm::StormVersion::longVersionString(); }, "Storm version in long representation.") + .def_property_readonly_static("build_info", [](py::object /* self */) { return storm::StormVersion::buildInfo(); }, "Build info for Storm."); } diff --git a/src/mod_pars.cpp b/src/mod_pars.cpp index bc9b441748..bfb5e28598 100644 --- a/src/mod_pars.cpp +++ b/src/mod_pars.cpp @@ -1,8 +1,8 @@ #include "common.h" +#include "pars/model_instantiator.h" #include "pars/pars.h" #include "pars/pla.h" -#include "pars/model_instantiator.h" PYBIND11_MODULE(_pars, m) { m.doc() = "Functionality for parametric analysis"; diff --git a/src/mod_pomdp.cpp b/src/mod_pomdp.cpp index a26a9e50f0..d7a2d19b3f 100644 --- a/src/mod_pomdp.cpp +++ b/src/mod_pomdp.cpp @@ -1,12 +1,12 @@ #include "common.h" -#include "pomdp/tracker.h" -#include "pomdp/qualitative_analysis.h" -#include "pomdp/transformations.h" +#include #include "pomdp/memory.h" +#include "pomdp/qualitative_analysis.h" #include "pomdp/quantitative_analysis.h" -#include +#include "pomdp/tracker.h" +#include "pomdp/transformations.h" PYBIND11_MODULE(_pomdp, m) { m.doc() = "Functionality for POMDP analysis"; diff --git a/src/mod_storage.cpp b/src/mod_storage.cpp index f88d6bf9ed..82256bd29d 100644 --- a/src/mod_storage.cpp +++ b/src/mod_storage.cpp @@ -1,22 +1,22 @@ #include "common.h" #include "storage/bitvector.h" +#include "storage/choiceorigins.h" #include "storage/dd.h" -#include "storage/model.h" #include "storage/decomposition.h" +#include "storage/distribution.h" +#include "storage/expressions.h" +#include "storage/geometry.h" +#include "storage/jani.h" +#include "storage/labeling.h" #include "storage/matrix.h" #include "storage/memorystructure.h" +#include "storage/model.h" #include "storage/model_components.h" -#include "storage/distribution.h" -#include "storage/scheduler.h" #include "storage/prism.h" -#include "storage/jani.h" +#include "storage/scheduler.h" #include "storage/state.h" #include "storage/valuation.h" -#include "storage/choiceorigins.h" -#include "storage/labeling.h" -#include "storage/expressions.h" -#include "storage/geometry.h" #include "storm/adapters/IntervalAdapter.h" #include "storm/storage/dd/DdType.h" @@ -82,5 +82,4 @@ PYBIND11_MODULE(_storage, m) { define_maximal_end_component_decomposition(m, "_exact"); define_maximal_end_component_decomposition(m, "_interval"); define_maximal_end_component_decomposition(m, "_ratfunc"); - } diff --git a/src/mod_utility.cpp b/src/mod_utility.cpp index dd53606bed..91342af7a9 100644 --- a/src/mod_utility.cpp +++ b/src/mod_utility.cpp @@ -1,10 +1,10 @@ #include "common.h" -#include "utility/shortestPaths.h" -#include "utility/smtsolver.h" +#include "storm/adapters/RationalNumberAdapter.h" #include "utility/chrono.h" #include "utility/json.h" -#include "storm/adapters/RationalNumberAdapter.h" +#include "utility/shortestPaths.h" +#include "utility/smtsolver.h" PYBIND11_MODULE(_utility, m) { m.doc() = "Utilities for Storm"; diff --git a/src/pars/common.h b/src/pars/common.h index 4894fadd50..59c22b196d 100644 --- a/src/pars/common.h +++ b/src/pars/common.h @@ -4,5 +4,5 @@ #include "storm-pars/api/storm-pars.h" -#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" -#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" \ No newline at end of file +#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" +#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" \ No newline at end of file diff --git a/src/pars/model_instantiator.cpp b/src/pars/model_instantiator.cpp index 6e6d368ebf..5f411f23c0 100644 --- a/src/pars/model_instantiator.cpp +++ b/src/pars/model_instantiator.cpp @@ -1,30 +1,34 @@ #include "model_instantiator.h" -#include "storm/models/sparse/Model.h" -#include "storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.h" #include "storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h" +#include "storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.h" +#include "storm/models/sparse/Model.h" #include "storm/models/sparse/StandardRewardModel.h" - #include "storm-pars/transformer/SparseParametricDtmcSimplifier.h" #include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/modelchecker/prctl/helper/BaierUpperRewardBoundsComputer.h" +#include "storm/modelchecker/prctl/helper/DsMpiUpperRewardBoundsComputer.h" #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" -#include "storm/modelchecker/prctl/helper/DsMpiUpperRewardBoundsComputer.h" -#include "storm/modelchecker/prctl/helper/BaierUpperRewardBoundsComputer.h" #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/solver/MinMaxLinearEquationSolver.h" -#include "storm/utility/vector.h" -#include "storm/utility/graph.h" #include "storm/utility/NumberTraits.h" +#include "storm/utility/graph.h" +#include "storm/utility/vector.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; +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; using namespace storm::modelchecker; @@ -32,100 +36,152 @@ using namespace storm::modelchecker; 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") - ; + .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"); + + py::class_, Dtmc>>(m, "PartialPDtmcInstantiator", + "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") + py::class_, Mdp>>(m, "PartialPMdpInstantiator", + "Instantiate PMDPs to MDPs") .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, Mdp>::instantiate, "Instantiate model with given parameter values") - ; + .def("instantiate", &storm::utility::ModelInstantiator, Mdp>::instantiate, + "Instantiate model with given parameter values"); - py::class_,Ctmc>>(m, "PCtmcInstantiator", "Instantiate PCTMCs to CTMCs") + py::class_, Ctmc>>(m, "PartialPCtmcInstantiator", + "Instantiate PCTMCs to CTMCs") .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, Ctmc>::instantiate, "Instantiate model with given parameter values") - ; + .def("instantiate", &storm::utility::ModelInstantiator, Ctmc>::instantiate, + "Instantiate model with given parameter values"); - py::class_,MarkovAutomaton>>(m, "PMaInstantiator", "Instantiate PMAs to MAs") + py::class_, MarkovAutomaton>>( + m, "PartialPMaInstantiator", "Instantiate PMAs to MAs") .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, MarkovAutomaton>::instantiate, "Instantiate model with given parameter values") - ; - - py::class_, Dtmc>>(m, "PartialPDtmcInstantiator", "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, "PartialPMdpInstantiator", "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, "PartialPCtmcInstantiator", "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, "PartialPMaInstantiator", "Instantiate PMAs to MAs") - .def(py::init>(), "parametric model"_a) - .def("instantiate", &storm::utility::ModelInstantiator, MarkovAutomaton>::instantiate, "Instantiate model with given parameter values") - ; + .def("instantiate", &storm::utility::ModelInstantiator, MarkovAutomaton>::instantiate, + "Instantiate model with given parameter values"); } void define_model_instantiation_checker(py::module& m) { - - py::class_, double>, std::shared_ptr, double>>> bpdtmcinstchecker(m, "_PDtmcInstantiationCheckerBase", "Instantiate pDTMCs to DTMCs and immediately check (base)"); + py::class_, double>, + std::shared_ptr, double>>> + bpdtmcinstchecker(m, "_PDtmcInstantiationCheckerBase", "Instantiate pDTMCs to DTMCs and immediately check (base)"); bpdtmcinstchecker.def("specify_formula", &SparseInstantiationModelChecker, double>::specifyFormula, "check_task"_a); - py::class_, double>, std::shared_ptr, double>>> (m, "PDtmcInstantiationChecker", "Instantiate pDTMCs to DTMCs and immediately check", bpdtmcinstchecker) + py::class_, double>, + std::shared_ptr, double>>>( + m, "PDtmcInstantiationChecker", "Instantiate pDTMCs to DTMCs and immediately check", bpdtmcinstchecker) .def(py::init>(), "parametric model"_a) - .def("check", [](SparseDtmcInstantiationModelChecker, double> &sdimc, storm::Environment const& env, storm::utility::parametric::Valuation const& val) -> std::shared_ptr {return sdimc.check(env,val);}, "env"_a, "instantiation"_a) - .def("set_graph_preserving", &SparseDtmcInstantiationModelChecker, double>::setInstantiationsAreGraphPreserving, "value"_a) - ; - - py::class_, storm::RationalNumber>, std::shared_ptr, storm::RationalNumber>>> bpdtmcexactinstchecker(m, "_PDtmcExactInstantiationCheckerBase", "Instantiate pDTMCs to exact DTMCs and immediately check (base)"); - bpdtmcexactinstchecker.def("specify_formula", &SparseInstantiationModelChecker, storm::RationalNumber>::specifyFormula, "check_task"_a); - - py::class_, storm::RationalNumber>, std::shared_ptr, storm::RationalNumber>>> (m, "PDtmcExactInstantiationChecker", "Instantiate pDTMCs to exact DTMCs and immediately check", bpdtmcexactinstchecker) + .def( + "check", + [](SparseDtmcInstantiationModelChecker, double>& sdimc, storm::Environment const& env, + storm::utility::parametric::Valuation const& val) -> std::shared_ptr { return sdimc.check(env, val); }, + "env"_a, "instantiation"_a) + .def("set_graph_preserving", &SparseDtmcInstantiationModelChecker, double>::setInstantiationsAreGraphPreserving, + "value"_a); + + py::class_, storm::RationalNumber>, + std::shared_ptr, storm::RationalNumber>>> + bpdtmcexactinstchecker(m, "_PDtmcExactInstantiationCheckerBase", "Instantiate pDTMCs to exact DTMCs and immediately check (base)"); + bpdtmcexactinstchecker.def("specify_formula", &SparseInstantiationModelChecker, storm::RationalNumber>::specifyFormula, + "check_task"_a); + + py::class_, storm::RationalNumber>, + std::shared_ptr, storm::RationalNumber>>>( + m, "PDtmcExactInstantiationChecker", "Instantiate pDTMCs to exact DTMCs and immediately check", bpdtmcexactinstchecker) .def(py::init>(), "parametric model"_a) - .def("check", [](SparseDtmcInstantiationModelChecker, storm::RationalNumber> &sdimc, storm::Environment const& env, storm::utility::parametric::Valuation const& val) -> std::shared_ptr {return sdimc.check(env,val);}, "env"_a, "instantiation"_a) - .def("set_graph_preserving", &SparseDtmcInstantiationModelChecker, storm::RationalNumber>::setInstantiationsAreGraphPreserving, "value"_a) - ; - - - py::class_, double>, std::shared_ptr, double>>> bpmdpinstchecker(m, "_PMdpInstantiationCheckerBase", "Instantiate pMDPs to MDPs and immediately check (base)"); + .def( + "check", + [](SparseDtmcInstantiationModelChecker, storm::RationalNumber>& sdimc, storm::Environment const& env, + storm::utility::parametric::Valuation const& val) -> std::shared_ptr { return sdimc.check(env, val); }, + "env"_a, "instantiation"_a) + .def("set_graph_preserving", + &SparseDtmcInstantiationModelChecker, storm::RationalNumber>::setInstantiationsAreGraphPreserving, "value"_a); + + py::class_, double>, + std::shared_ptr, double>>> + bpmdpinstchecker(m, "_PMdpInstantiationCheckerBase", "Instantiate pMDPs to MDPs and immediately check (base)"); bpmdpinstchecker.def("specify_formula", &SparseInstantiationModelChecker, double>::specifyFormula, "check_task"_a); - py::class_, double>, std::shared_ptr, double>>> (m, "PMdpInstantiationChecker", "Instantiate PMDP to MDPs and immediately check", bpmdpinstchecker) + py::class_, double>, + std::shared_ptr, double>>>( + m, "PMdpInstantiationChecker", "Instantiate PMDP to MDPs and immediately check", bpmdpinstchecker) .def(py::init>(), "parametric model"_a) - .def("check", [](SparseMdpInstantiationModelChecker, double> &sdimc, storm::Environment const& env, storm::utility::parametric::Valuation const& val) -> std::shared_ptr {return sdimc.check(env,val);}, "env"_a, "instantiation"_a) - .def("set_graph_preserving", &SparseMdpInstantiationModelChecker, double>::setInstantiationsAreGraphPreserving, "value"_a) - ; - - py::class_, storm::RationalNumber>, std::shared_ptr, storm::RationalNumber>>> bpmdpexactinstchecker(m, "_PMdpExactInstantiationCheckerBase", "Instantiate pMDPs to exact MDPs and immediately check (base)"); - bpmdpexactinstchecker.def("specify_formula", &SparseInstantiationModelChecker, storm::RationalNumber>::specifyFormula, "check_task"_a); - - py::class_, storm::RationalNumber>, std::shared_ptr, storm::RationalNumber>>> (m, "PMdpExactInstantiationChecker", "Instantiate PMDP to exact MDPs and immediately check", bpmdpexactinstchecker) + .def( + "check", + [](SparseMdpInstantiationModelChecker, double>& sdimc, storm::Environment const& env, + storm::utility::parametric::Valuation const& val) -> std::shared_ptr { return sdimc.check(env, val); }, + "env"_a, "instantiation"_a) + .def("set_graph_preserving", &SparseMdpInstantiationModelChecker, double>::setInstantiationsAreGraphPreserving, "value"_a); + + py::class_, storm::RationalNumber>, + std::shared_ptr, storm::RationalNumber>>> + bpmdpexactinstchecker(m, "_PMdpExactInstantiationCheckerBase", "Instantiate pMDPs to exact MDPs and immediately check (base)"); + bpmdpexactinstchecker.def("specify_formula", &SparseInstantiationModelChecker, storm::RationalNumber>::specifyFormula, + "check_task"_a); + + py::class_, storm::RationalNumber>, + std::shared_ptr, storm::RationalNumber>>>( + m, "PMdpExactInstantiationChecker", "Instantiate PMDP to exact MDPs and immediately check", bpmdpexactinstchecker) .def(py::init>(), "parametric model"_a) - .def("check", [](SparseMdpInstantiationModelChecker, storm::RationalNumber> &sdimc, storm::Environment const& env, storm::utility::parametric::Valuation const& val) -> std::shared_ptr {return sdimc.check(env,val);}, "env"_a, "instantiation"_a) - .def("set_graph_preserving", &SparseMdpInstantiationModelChecker, storm::RationalNumber>::setInstantiationsAreGraphPreserving, "value"_a) - ; - - py::class_, double>, std::shared_ptr, double>>> bpctmcinstchecker(m, "_PCtmcInstantiationCheckerBase", "Instantiate pCTMCs to CTMCs and immediately check (base)"); + .def( + "check", + [](SparseMdpInstantiationModelChecker, storm::RationalNumber>& sdimc, storm::Environment const& env, + storm::utility::parametric::Valuation const& val) -> std::shared_ptr { return sdimc.check(env, val); }, + "env"_a, "instantiation"_a) + .def("set_graph_preserving", + &SparseMdpInstantiationModelChecker, storm::RationalNumber>::setInstantiationsAreGraphPreserving, "value"_a); + + py::class_, double>, + std::shared_ptr, double>>> + bpctmcinstchecker(m, "_PCtmcInstantiationCheckerBase", "Instantiate pCTMCs to CTMCs and immediately check (base)"); bpctmcinstchecker.def("specify_formula", &SparseInstantiationModelChecker, double>::specifyFormula, "check_task"_a); - py::class_, double>, std::shared_ptr, double>>> (m, "PCtmcInstantiationChecker", "Instantiate pCTMCs to CTMCs and immediately check", bpctmcinstchecker) + py::class_, double>, + std::shared_ptr, double>>>( + m, "PCtmcInstantiationChecker", "Instantiate pCTMCs to CTMCs and immediately check", bpctmcinstchecker) .def(py::init>(), "parametric model"_a) - .def("check", [](SparseCtmcInstantiationModelChecker, double> &scimc, storm::Environment const& env, storm::utility::parametric::Valuation const& val) -> std::shared_ptr {return scimc.check(env,val);}, "env"_a, "instantiation"_a) - .def("set_graph_preserving", &SparseCtmcInstantiationModelChecker, double>::setInstantiationsAreGraphPreserving, "value"_a) - ; - - py::class_, storm::RationalNumber>, std::shared_ptr, storm::RationalNumber>>> bpctmcexactinstchecker(m, "_PCtmcExactInstantiationCheckerBase", "Instantiate pCTMCs to exact CTMCs and immediately check (base)"); - bpctmcexactinstchecker.def("specify_formula", &SparseInstantiationModelChecker, storm::RationalNumber>::specifyFormula, "check_task"_a); - - py::class_, storm::RationalNumber>, std::shared_ptr, storm::RationalNumber>>> (m, "PCtmcExactInstantiationChecker", "Instantiate pCTMCs to exact CTMCs and immediately check", bpctmcexactinstchecker) + .def( + "check", + [](SparseCtmcInstantiationModelChecker, double>& scimc, storm::Environment const& env, + storm::utility::parametric::Valuation const& val) -> std::shared_ptr { return scimc.check(env, val); }, + "env"_a, "instantiation"_a) + .def("set_graph_preserving", &SparseCtmcInstantiationModelChecker, double>::setInstantiationsAreGraphPreserving, + "value"_a); + + py::class_, storm::RationalNumber>, + std::shared_ptr, storm::RationalNumber>>> + bpctmcexactinstchecker(m, "_PCtmcExactInstantiationCheckerBase", "Instantiate pCTMCs to exact CTMCs and immediately check (base)"); + bpctmcexactinstchecker.def("specify_formula", &SparseInstantiationModelChecker, storm::RationalNumber>::specifyFormula, + "check_task"_a); + + py::class_, storm::RationalNumber>, + std::shared_ptr, storm::RationalNumber>>>( + m, "PCtmcExactInstantiationChecker", "Instantiate pCTMCs to exact CTMCs and immediately check", bpctmcexactinstchecker) .def(py::init>(), "parametric model"_a) - .def("check", [](SparseCtmcInstantiationModelChecker, storm::RationalNumber> &scimc, storm::Environment const& env, storm::utility::parametric::Valuation const& val) -> std::shared_ptr {return scimc.check(env,val);}, "env"_a, "instantiation"_a) - .def("set_graph_preserving", &SparseCtmcInstantiationModelChecker, storm::RationalNumber>::setInstantiationsAreGraphPreserving, "value"_a) - ; - + .def( + "check", + [](SparseCtmcInstantiationModelChecker, storm::RationalNumber>& scimc, storm::Environment const& env, + storm::utility::parametric::Valuation const& val) -> std::shared_ptr { return scimc.check(env, val); }, + "env"_a, "instantiation"_a) + .def("set_graph_preserving", + &SparseCtmcInstantiationModelChecker, storm::RationalNumber>::setInstantiationsAreGraphPreserving, "value"_a); } diff --git a/src/pars/pars.cpp b/src/pars/pars.cpp index b8d42b716f..3ebbd26088 100644 --- a/src/pars/pars.cpp +++ b/src/pars/pars.cpp @@ -1,9 +1,9 @@ #include "pars.h" -#include "storm/settings/SettingsManager.h" #include "storm-pars/settings/modules/ParametricSettings.h" #include "storm-pars/settings/modules/RegionSettings.h" #include "storm-pars/transformer/SparseParametricDtmcSimplifier.h" #include "storm-pars/transformer/SparseParametricMdpSimplifier.h" +#include "storm/settings/SettingsManager.h" typedef storm::models::sparse::Dtmc Dtmc; typedef storm::models::sparse::Mdp Mdp; @@ -11,35 +11,35 @@ typedef storm::transformer::SparseParametricDtmcSimplifier SparseParametri typedef storm::transformer::SparseParametricMdpSimplifier SparseParametricMdpSimplifier; void define_pars(py::module& m) { - m.def("_set_up", []() { + m.def( + "_set_up", + []() { storm::settings::addModule(); storm::settings::addModule(); - }, "Initialize Storm-pars"); - - py::class_>(m, "_SparseParametricDtmcSimplifier", "Model simplifier for parametric DTMCs") - .def(py::init(), py::arg("dtmc")) - .def("simplify", [](SparseParametricDtmcSimplifier &simplifier, storm::logic::Formula const& formula) -> bool { - return simplifier.simplify(formula); - }, "Simplify model", py::arg("formula")) - .def_property_readonly("simplified_model", [](SparseParametricDtmcSimplifier const& simplifier) { - return simplifier.getSimplifiedModel(); - }, "Return simplified model") - .def_property_readonly("simplified_formula", [](SparseParametricDtmcSimplifier const& simplifier) { - return simplifier.getSimplifiedFormula(); - }, "Return simplified formula") - ; + }, + "Initialize Storm-pars"); - py::class_>(m, "_SparseParametricMdpSimplifier", "Model simplifier for parametric MDPs") - .def(py::init(), py::arg("mdp")) - .def("simplify", [](SparseParametricMdpSimplifier &simplifier, storm::logic::Formula const& formula) -> bool { - return simplifier.simplify(formula); - }, "Simplify model", py::arg("formula")) - .def_property_readonly("simplified_model", [](SparseParametricMdpSimplifier const& simplifier) { - return simplifier.getSimplifiedModel(); - }, "Return simplified model") - .def_property_readonly("simplified_formula", [](SparseParametricMdpSimplifier const& simplifier) { - return simplifier.getSimplifiedFormula(); - }, "Return simplified formula") - ; + py::class_>(m, "_SparseParametricDtmcSimplifier", + "Model simplifier for parametric DTMCs") + .def(py::init(), py::arg("dtmc")) + .def( + "simplify", [](SparseParametricDtmcSimplifier& simplifier, storm::logic::Formula const& formula) -> bool { return simplifier.simplify(formula); }, + "Simplify model", py::arg("formula")) + .def_property_readonly( + "simplified_model", [](SparseParametricDtmcSimplifier const& simplifier) { return simplifier.getSimplifiedModel(); }, "Return simplified model") + .def_property_readonly( + "simplified_formula", [](SparseParametricDtmcSimplifier const& simplifier) { return simplifier.getSimplifiedFormula(); }, + "Return simplified formula"); + py::class_>(m, "_SparseParametricMdpSimplifier", + "Model simplifier for parametric MDPs") + .def(py::init(), py::arg("mdp")) + .def( + "simplify", [](SparseParametricMdpSimplifier& simplifier, storm::logic::Formula const& formula) -> bool { return simplifier.simplify(formula); }, + "Simplify model", py::arg("formula")) + .def_property_readonly( + "simplified_model", [](SparseParametricMdpSimplifier const& simplifier) { return simplifier.getSimplifiedModel(); }, "Return simplified model") + .def_property_readonly( + "simplified_formula", [](SparseParametricMdpSimplifier const& simplifier) { return simplifier.getSimplifiedFormula(); }, + "Return simplified formula"); } diff --git a/src/pars/pla.cpp b/src/pars/pla.cpp index 5d883f6c8e..6539077d53 100644 --- a/src/pars/pla.cpp +++ b/src/pars/pla.cpp @@ -1,10 +1,10 @@ #include "pla.h" #include "src/helpers.h" -#include "storm/api/storm.h" #include "storm-pars/api/region.h" +#include "storm/api/storm.h" - -typedef storm::modelchecker::SparseDtmcParameterLiftingModelChecker, double> DtmcParameterLiftingModelChecker; +typedef storm::modelchecker::SparseDtmcParameterLiftingModelChecker, double> + DtmcParameterLiftingModelChecker; typedef storm::modelchecker::SparseMdpParameterLiftingModelChecker, double> MdpParameterLiftingModelChecker; typedef storm::modelchecker::RegionModelChecker RegionModelChecker; @@ -13,50 +13,69 @@ typedef storm::storage::ParameterRegion Region; typedef storm::modelchecker::AnnotatedRegion AnnotatedRegion; // Thin wrappers -std::shared_ptr createRegionChecker(storm::Environment const& env, std::shared_ptr> const& model, std::shared_ptr const& formula, bool allowModelSimplifications, bool graphPreserving, bool preconditionsValidatedManually) { +std::shared_ptr createRegionChecker(storm::Environment const& env, + std::shared_ptr> const& model, + std::shared_ptr const& formula, bool allowModelSimplifications, + bool graphPreserving, bool preconditionsValidatedManually) { auto task = storm::api::createTask(formula, true); - auto regionChecker = storm::api::initializeRegionModelChecker(env, model, task, storm::modelchecker::RegionCheckEngine::ParameterLifting, allowModelSimplifications, graphPreserving, preconditionsValidatedManually); + auto regionChecker = storm::api::initializeRegionModelChecker( + env, model, task, storm::modelchecker::RegionCheckEngine::ParameterLifting, allowModelSimplifications, graphPreserving, preconditionsValidatedManually); return regionChecker; } -std::shared_ptr createRegionRefinementChecker(storm::Environment const& env, std::shared_ptr> const& model, std::shared_ptr const& formula, bool allowModelSimplifications, bool graphPreserving, bool preconditionsValidatedManually) { +std::shared_ptr createRegionRefinementChecker(storm::Environment const& env, + std::shared_ptr> const& model, + std::shared_ptr const& formula, bool allowModelSimplifications, + bool graphPreserving, bool preconditionsValidatedManually) { auto task = storm::api::createTask(formula, true); storm::modelchecker::RegionSplittingStrategy strategy; storm::pars::modelchecker::MonotonicityOptions monotonicityOptions; std::set::VariableType> discreteVars; - storm::pars::modelchecker::RegionRefinementOptions settings( - model, task, storm::modelchecker::RegionCheckEngine::ParameterLifting, strategy, - monotonicityOptions, discreteVars, allowModelSimplifications, graphPreserving, preconditionsValidatedManually - ); + storm::pars::modelchecker::RegionRefinementOptions settings(model, task, storm::modelchecker::RegionCheckEngine::ParameterLifting, + strategy, monotonicityOptions, discreteVars, allowModelSimplifications, + graphPreserving, preconditionsValidatedManually); return storm::api::initializeRegionRefinementChecker(env, settings); } -void specifyRegionChecker(std::shared_ptr& checker, storm::Environment const& env, std::shared_ptr> const& model, std::shared_ptr const& formula, std::optional splittingEstimate, bool allowModelSimplifications, bool graphPreserving) { - return checker->specify(env, model, storm::api::createTask(formula, true), splittingEstimate, nullptr, allowModelSimplifications, graphPreserving); +void specifyRegionChecker(std::shared_ptr& checker, storm::Environment const& env, + std::shared_ptr> const& model, + std::shared_ptr const& formula, std::optional splittingEstimate, + bool allowModelSimplifications, bool graphPreserving) { + return checker->specify(env, model, storm::api::createTask(formula, true), splittingEstimate, nullptr, allowModelSimplifications, + graphPreserving); } -void specifyRefinementChecker(std::shared_ptr& checker, storm::Environment const& env, std::shared_ptr> const& model, std::shared_ptr const& formula, bool allowModelSimplifications, bool graphPreserving) { +void specifyRefinementChecker(std::shared_ptr& checker, storm::Environment const& env, + std::shared_ptr> const& model, + std::shared_ptr const& formula, bool allowModelSimplifications, bool graphPreserving) { storm::modelchecker::RegionSplittingStrategy strategy; std::set::VariableType> discreteVars; - return checker->specify(env, model, storm::api::createTask(formula, true), strategy, discreteVars, nullptr, allowModelSimplifications, graphPreserving); + return checker->specify(env, model, storm::api::createTask(formula, true), strategy, discreteVars, nullptr, + allowModelSimplifications, graphPreserving); } -storm::modelchecker::RegionResult checkRegion(std::shared_ptr& checker, storm::Environment const& env, Region const& region, storm::modelchecker::RegionResultHypothesis const& hypothesis, bool sampleVertices) { +storm::modelchecker::RegionResult checkRegion(std::shared_ptr& checker, storm::Environment const& env, Region const& region, + storm::modelchecker::RegionResultHypothesis const& hypothesis, bool sampleVertices) { return checker->analyzeRegion(env, region, hypothesis, sampleVertices); } Region::CoefficientType getBoundAtInit(std::shared_ptr& checker, storm::Environment const& env, Region const& region, bool maximise) { - return checker->getBoundAtInitState(env, region, maximise ? storm::solver::OptimizationDirection::Maximize : storm::solver::OptimizationDirection::Minimize); + return checker->getBoundAtInitState(env, region, + maximise ? storm::solver::OptimizationDirection::Maximize : storm::solver::OptimizationDirection::Minimize); } -storm::modelchecker::ExplicitQuantitativeCheckResult getBound_dtmc(std::shared_ptr& checker, storm::Environment const& env, Region const& region, bool maximise) { +storm::modelchecker::ExplicitQuantitativeCheckResult getBound_dtmc(std::shared_ptr& checker, + storm::Environment const& env, Region const& region, bool maximise) { AnnotatedRegion annotatedRegion(region); - return checker->getBound(env, annotatedRegion, maximise ? storm::solver::OptimizationDirection::Maximize : storm::solver::OptimizationDirection::Minimize)->asExplicitQuantitativeCheckResult(); + return checker->getBound(env, annotatedRegion, maximise ? storm::solver::OptimizationDirection::Maximize : storm::solver::OptimizationDirection::Minimize) + ->asExplicitQuantitativeCheckResult(); } -storm::modelchecker::ExplicitQuantitativeCheckResult getBound_mdp(std::shared_ptr& checker, storm::Environment const& env, Region const& region, bool maximise) { +storm::modelchecker::ExplicitQuantitativeCheckResult getBound_mdp(std::shared_ptr& checker, + storm::Environment const& env, Region const& region, bool maximise) { AnnotatedRegion annotatedRegion(region); - return checker->getBound(env, annotatedRegion, maximise ? storm::solver::OptimizationDirection::Maximize : storm::solver::OptimizationDirection::Minimize)->asExplicitQuantitativeCheckResult(); + return checker->getBound(env, annotatedRegion, maximise ? storm::solver::OptimizationDirection::Maximize : storm::solver::OptimizationDirection::Minimize) + ->asExplicitQuantitativeCheckResult(); } std::set gatherDerivatives(storm::models::sparse::Model const& model, carl::Variable const& var) { @@ -70,11 +89,8 @@ std::set gatherDerivatives(storm::models::sparse::Model(m, "RegionResult", "Types of region check results") .value("EXISTSSAT", storm::modelchecker::RegionResult::ExistsSat) @@ -85,59 +101,74 @@ void define_pla(py::module& m) { .value("ALLSAT", storm::modelchecker::RegionResult::AllSat) .value("ALLVIOLATED", storm::modelchecker::RegionResult::AllViolated) .value("UNKNOWN", storm::modelchecker::RegionResult::Unknown) - .def("__str__", &streamToString, py::prepend() /* use custom method instead of default enum overload */) - ; + .def("__str__", &streamToString, py::prepend() /* use custom method instead of default enum overload */); // RegionResultHypothesis py::enum_(m, "RegionResultHypothesis", "Hypothesis for the result of a parameter region") .value("UNKNOWN", storm::modelchecker::RegionResultHypothesis::Unknown) .value("ALLSAT", storm::modelchecker::RegionResultHypothesis::AllSat) .value("ALLVIOLATED", storm::modelchecker::RegionResultHypothesis::AllViolated) - .def("__str__", &streamToString, py::prepend() /* use custom method instead of default enum overload */) - ; + .def("__str__", &streamToString, py::prepend() /* use custom method instead of default enum overload */); // Region py::class_>(m, "ParameterRegion", "Parameter region") .def(py::init([](std::map> valuation) { - Region::Valuation lowerValuation; - Region::Valuation upperValuation; - for (auto const& val : valuation) { - lowerValuation[val.first] = val.second.first; - upperValuation[val.first] = val.second.second; - } - return Region(lowerValuation, upperValuation); - }), "Create region from valuation of var -> (lower_bound, upper_bound)", py::arg("valuation")) - .def_static("create_from_string", [](std::string const& regionString, std::set const& variables) -> Region { + Region::Valuation lowerValuation; + Region::Valuation upperValuation; + for (auto const& val : valuation) { + lowerValuation[val.first] = val.second.first; + upperValuation[val.first] = val.second.second; + } + return Region(lowerValuation, upperValuation); + }), + "Create region from valuation of var -> (lower_bound, upper_bound)", py::arg("valuation")) + .def_static( + "create_from_string", + [](std::string const& regionString, std::set const& variables) -> Region { return storm::api::parseRegion(regionString, variables); - }, "Create region from string", py::arg("region_string"), py::arg("variables")) + }, + "Create region from string", py::arg("region_string"), py::arg("variables")) .def_property_readonly("area", &Region::area, "Get area") - .def("__str__", &streamToString) - ; + .def("__str__", &streamToString); // RegionModelChecker - py::class_> regionModelChecker(m, "RegionModelChecker", "Region model checker via paramater lifting"); - regionModelChecker.def("check_region", &checkRegion, "Check region", py::arg("environment"), py::arg("region"), py::arg("hypothesis") = storm::modelchecker::RegionResultHypothesis::Unknown, py::arg("sampleVertices") = false) - .def("get_bound", &getBoundAtInit, "Get bound", py::arg("environment"), py::arg("region"), py::arg("maximise")= true) + py::class_> regionModelChecker(m, "RegionModelChecker", + "Region model checker via paramater lifting"); + regionModelChecker + .def("check_region", &checkRegion, "Check region", py::arg("environment"), py::arg("region"), + py::arg("hypothesis") = storm::modelchecker::RegionResultHypothesis::Unknown, py::arg("sampleVertices") = false) + .def("get_bound", &getBoundAtInit, "Get bound", py::arg("environment"), py::arg("region"), py::arg("maximise") = true) .def("get_split_suggestion", &RegionModelChecker::obtainRegionSplitEstimates, "Get region split estimates", py::arg("relevant_parameters")) - .def("specify", &specifyRegionChecker, "specify arguments",py::arg("environment"), py::arg("model"), py::arg("formula"), py::arg("splitting_estimate") = std::nullopt, py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true) - ; + .def("specify", &specifyRegionChecker, "specify arguments", py::arg("environment"), py::arg("model"), py::arg("formula"), + py::arg("splitting_estimate") = std::nullopt, py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true); // RegionRefinementChecker py::class_>(m, "RegionRefinementChecker", "Region refinement checker") - .def("specify", &specifyRefinementChecker, "specify arguments", py::arg("environment"), py::arg("model"), py::arg("formula"), py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true) - .def("compute_extremum", [](RegionRefinementChecker& r, storm::Environment const& env, Region const& region, storm::solver::OptimizationDirection const& dirForParameters, storm::RationalFunctionCoefficient const& precision, bool absolutePrecision) { - return r.computeExtremalValue(env, region, dirForParameters, storm::utility::one() * precision, absolutePrecision, std::nullopt); - }, "Compute extremum value and point with precision", py::arg("environment"), py::arg("region"), py::arg("extremum_direction"), py::arg("precision"), py::arg("precision_absolute") = false) - ; - - py::class_>(m, "DtmcParameterLiftingModelChecker", "Region model checker for DTMCs", regionModelChecker) - .def(py::init<>()) - .def("get_bound_all_states", &getBound_dtmc, "Get bound", py::arg("environment"), py::arg("region"), py::arg("maximise")= true); - py::class_>(m, "MdpParameterLiftingModelChecker", "Region model checker for MPDs", regionModelChecker) - .def(py::init<>()) - .def("get_bound_all_states", &getBound_mdp, "Get bound", py::arg("environment"), py::arg("region"), py::arg("maximise")= true); - - m.def("create_region_checker", &createRegionChecker, "Create region checker", py::arg("environment"), py::arg("model"), py::arg("formula"), py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true, py::arg("preconditions_validated_manually") = false ); - m.def("create_region_refinement_checker", &createRegionRefinementChecker, "Create region refinement checker", py::arg("environment"), py::arg("model"), py::arg("formula"), py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true, py::arg("preconditions_validated_manually") = false ); + .def("specify", &specifyRefinementChecker, "specify arguments", py::arg("environment"), py::arg("model"), py::arg("formula"), + py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true) + .def( + "compute_extremum", + [](RegionRefinementChecker& r, storm::Environment const& env, Region const& region, storm::solver::OptimizationDirection const& dirForParameters, + storm::RationalFunctionCoefficient const& precision, bool absolutePrecision) { + return r.computeExtremalValue(env, region, dirForParameters, storm::utility::one() * precision, absolutePrecision, + std::nullopt); + }, + "Compute extremum value and point with precision", py::arg("environment"), py::arg("region"), py::arg("extremum_direction"), py::arg("precision"), + py::arg("precision_absolute") = false); + + py::class_>(m, "DtmcParameterLiftingModelChecker", + "Region model checker for DTMCs", regionModelChecker) + .def(py::init<>()) + .def("get_bound_all_states", &getBound_dtmc, "Get bound", py::arg("environment"), py::arg("region"), py::arg("maximise") = true); + py::class_>(m, "MdpParameterLiftingModelChecker", + "Region model checker for MPDs", regionModelChecker) + .def(py::init<>()) + .def("get_bound_all_states", &getBound_mdp, "Get bound", py::arg("environment"), py::arg("region"), py::arg("maximise") = true); + + m.def("create_region_checker", &createRegionChecker, "Create region checker", py::arg("environment"), py::arg("model"), py::arg("formula"), + py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true, py::arg("preconditions_validated_manually") = false); + m.def("create_region_refinement_checker", &createRegionRefinementChecker, "Create region refinement checker", py::arg("environment"), py::arg("model"), + py::arg("formula"), py::arg("allow_model_simplification") = true, py::arg("graph_preserving") = true, + py::arg("preconditions_validated_manually") = false); m.def("gather_derivatives", &gatherDerivatives, "Gather all derivatives of transition probabilities", py::arg("model"), py::arg("var")); } diff --git a/src/pomdp/memory.cpp b/src/pomdp/memory.cpp index 3941f43f67..f1d43fd491 100644 --- a/src/pomdp/memory.cpp +++ b/src/pomdp/memory.cpp @@ -1,27 +1,22 @@ #include "memory.h" -#include "src/helpers.h" #include - +#include "src/helpers.h" void define_memory(py::module& m) { py::class_ memory(m, "PomdpMemory", "Memory for POMDP policies"); - memory.def_property_readonly("nr_states",&storm::storage::PomdpMemory::getNumberOfStates, "How many states does the memory structure have"); + memory.def_property_readonly("nr_states", &storm::storage::PomdpMemory::getNumberOfStates, "How many states does the memory structure have"); // Trivial, FixedCounter, SelectiveCounter, FixedRing, SelectiveRing, SettableBits, Full py::enum_(m, "PomdpMemoryPattern", "Memory pattern for POMDP memory") - .value("trivial", storm::storage::PomdpMemoryPattern::Trivial) - .value("fixed_counter", storm::storage::PomdpMemoryPattern::FixedCounter) - .value("selective_counter", storm::storage::PomdpMemoryPattern::SelectiveCounter) - .value("fixed_ring", storm::storage::PomdpMemoryPattern::FixedRing) - .value("selective_ring", storm::storage::PomdpMemoryPattern::SelectiveRing) - .value("settable_bits", storm::storage::PomdpMemoryPattern::SettableBits) - .value("full", storm::storage::PomdpMemoryPattern::Full) - ; - + .value("trivial", storm::storage::PomdpMemoryPattern::Trivial) + .value("fixed_counter", storm::storage::PomdpMemoryPattern::FixedCounter) + .value("selective_counter", storm::storage::PomdpMemoryPattern::SelectiveCounter) + .value("fixed_ring", storm::storage::PomdpMemoryPattern::FixedRing) + .value("selective_ring", storm::storage::PomdpMemoryPattern::SelectiveRing) + .value("settable_bits", storm::storage::PomdpMemoryPattern::SettableBits) + .value("full", storm::storage::PomdpMemoryPattern::Full); py::class_ memorybuilder(m, "PomdpMemoryBuilder", "MemoryBuilder for POMDP policies"); memorybuilder.def(py::init<>()); memorybuilder.def("build", &storm::storage::PomdpMemoryBuilder::build, py::arg("pattern"), py::arg("nr_states")); - - } \ No newline at end of file diff --git a/src/pomdp/qualitative_analysis.cpp b/src/pomdp/qualitative_analysis.cpp index 1cb86b2396..e774684411 100644 --- a/src/pomdp/qualitative_analysis.cpp +++ b/src/pomdp/qualitative_analysis.cpp @@ -1,15 +1,17 @@ -#include "tracker.h" -#include "src/helpers.h" #include #include #include #include - -template using SparsePomdp = storm::models::sparse::Pomdp; +#include "src/helpers.h" +#include "tracker.h" template -std::shared_ptr> createWinningRegionSolver(SparsePomdp const& pomdp, storm::logic::Formula const& formula, storm::pomdp::MemlessSearchOptions const& options) { +using SparsePomdp = storm::models::sparse::Pomdp; +template +std::shared_ptr> createWinningRegionSolver(SparsePomdp const& pomdp, + storm::logic::Formula const& formula, + storm::pomdp::MemlessSearchOptions const& options) { STORM_LOG_TRACE("Run qualitative preprocessing..."); storm::analysis::QualitativeAnalysisOnGraphs qualitativeAnalysis(pomdp); // After preprocessing, this might be done cheaper. @@ -32,17 +34,21 @@ SparsePomdp preparePOMDPForQualitativeSearch(SparsePomdp c template void define_qualitative_policy_search(py::module& m, std::string const& vtSuffix) { - m.def(("create_iterative_qualitative_search_solver_" + vtSuffix).c_str(), &createWinningRegionSolver, "Create solver " ,py::arg("pomdp"), py::arg("formula"), py::arg("options")); - m.def(("prepare_pomdp_for_qualitative_search_" +vtSuffix).c_str(), &preparePOMDPForQualitativeSearch, "Preprocess POMDP", py::arg("pomdp"), py::arg("formula")); - py::class_, std::shared_ptr>> mssq(m, ("IterativeQualitativeSearchSolver" + vtSuffix).c_str(), "Solver for POMDPs that solves qualitative queries"); + m.def(("create_iterative_qualitative_search_solver_" + vtSuffix).c_str(), &createWinningRegionSolver, "Create solver ", py::arg("pomdp"), + py::arg("formula"), py::arg("options")); + m.def(("prepare_pomdp_for_qualitative_search_" + vtSuffix).c_str(), &preparePOMDPForQualitativeSearch, "Preprocess POMDP", py::arg("pomdp"), + py::arg("formula")); + py::class_, std::shared_ptr>> mssq( + m, ("IterativeQualitativeSearchSolver" + vtSuffix).c_str(), "Solver for POMDPs that solves qualitative queries"); mssq.def("compute_winning_region", &storm::pomdp::IterativePolicySearch::computeWinningRegion, py::arg("lookahead")); mssq.def("compute_winning_policy_for_initial_states", &storm::pomdp::IterativePolicySearch::analyzeForInitialStates, py::arg("lookahead")); - mssq.def_property_readonly("last_winning_region", &storm::pomdp::IterativePolicySearch::getLastWinningRegion, "get the last computed winning region"); + mssq.def_property_readonly("last_winning_region", &storm::pomdp::IterativePolicySearch::getLastWinningRegion, + "get the last computed winning region"); py::class_> wrqi(m, ("BeliefSupportWinningRegionQueryInterface" + vtSuffix).c_str()); - wrqi.def(py::init const&, storm::pomdp::WinningRegion const&>(), py::arg("pomdp"), py::arg("BeliefSupportWinningRegion")); + wrqi.def(py::init const&, storm::pomdp::WinningRegion const&>(), py::arg("pomdp"), py::arg("BeliefSupportWinningRegion")); wrqi.def("query_current_belief", &storm::pomdp::WinningRegionQueryInterface::isInWinningRegion, py::arg("current_belief")); - wrqi.def("query_action", &storm::pomdp::WinningRegionQueryInterface::staysInWinningRegion, py::arg("current_belief"), py::arg("action")); + wrqi.def("query_action", &storm::pomdp::WinningRegionQueryInterface::staysInWinningRegion, py::arg("current_belief"), py::arg("action")); } template void define_qualitative_policy_search(py::module& m, std::string const& vtSuffix); @@ -53,5 +59,5 @@ void define_qualitative_policy_search_nt(py::module& m) { py::class_ winningRegion(m, "BeliefSupportWinningRegion"); winningRegion.def_static("load_from_file", &storm::pomdp::WinningRegion::loadFromFile, py::arg("filepath")); - winningRegion.def("store_to_file", &storm::pomdp::WinningRegion::storeToFile, py::arg("filepath"), py::arg("preamble"), py::arg("append")=false); + winningRegion.def("store_to_file", &storm::pomdp::WinningRegion::storeToFile, py::arg("filepath"), py::arg("preamble"), py::arg("append") = false); } diff --git a/src/pomdp/quantitative_analysis.cpp b/src/pomdp/quantitative_analysis.cpp index d7a9ac751d..7b32bd9fb7 100644 --- a/src/pomdp/quantitative_analysis.cpp +++ b/src/pomdp/quantitative_analysis.cpp @@ -1,25 +1,42 @@ #include "quantitative_analysis.h" +#include "storm-pomdp/api/verification.h" #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/models/sparse/Pomdp.h" -#include "storm-pomdp/api/verification.h" - -template using Pomdp = storm::models::sparse::Pomdp>; -template using BeliefExplorationPomdpModelChecker = typename storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker, ValueType, ValueType>; -template using BeliefExplorationPomdpModelCheckerResult = typename storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker::Result; -template using Options = storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions; -template using additionalCutoffValueType = std::vector>>; +template +using Pomdp = storm::models::sparse::Pomdp>; +template +using BeliefExplorationPomdpModelChecker = typename storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker, ValueType, ValueType>; +template +using BeliefExplorationPomdpModelCheckerResult = typename storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker::Result; +template +using Options = storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions; +template +using additionalCutoffValueType = std::vector>>; template void define_belief_exploration(py::module& m, std::string const& vtSuffix) { py::class_> belmc(m, ("BeliefExplorationModelChecker" + vtSuffix).c_str()); belmc.def(py::init>, Options>(), py::arg("model"), py::arg("options")); - belmc.def("check", py::overload_cast const&>(&BeliefExplorationPomdpModelChecker::check), py::arg("formula"), py::arg("cutoff_values")); - belmc.def("check_with_preprocessing_environment", py::overload_cast const&>(&BeliefExplorationPomdpModelChecker::check), py::arg("formula"), py::arg("pre_processing_environment"), py::arg("cutoff_values")); - belmc.def("check_with_environment", py::overload_cast const&>(&BeliefExplorationPomdpModelChecker::check), py::arg("environment"), py::arg("formula"), py::arg("cutoff_values")); - belmc.def("check_with_environment_and_pre_processing_environment", py::overload_cast const&>(&BeliefExplorationPomdpModelChecker::check), py::arg("environment"), py::arg("formula"), py::arg("pre_processing_environment"), py::arg("cutoff_values")); + belmc.def( + "check", + py::overload_cast const&>(&BeliefExplorationPomdpModelChecker::check), + py::arg("formula"), py::arg("cutoff_values")); + belmc.def("check_with_preprocessing_environment", + py::overload_cast const&>( + &BeliefExplorationPomdpModelChecker::check), + py::arg("formula"), py::arg("pre_processing_environment"), py::arg("cutoff_values")); + belmc.def("check_with_environment", + py::overload_cast const&>( + &BeliefExplorationPomdpModelChecker::check), + py::arg("environment"), py::arg("formula"), py::arg("cutoff_values")); + belmc.def( + "check_with_environment_and_pre_processing_environment", + py::overload_cast const&>( + &BeliefExplorationPomdpModelChecker::check), + py::arg("environment"), py::arg("formula"), py::arg("pre_processing_environment"), py::arg("cutoff_values")); belmc.def("pause_unfolding", &BeliefExplorationPomdpModelChecker::pauseUnfolding); belmc.def("continue_unfolding", &BeliefExplorationPomdpModelChecker::continueUnfolding); @@ -58,7 +75,8 @@ void define_belief_exploration(py::module& m, std::string const& vtSuffix) { belexplres.def_readonly("lower_bound", &BeliefExplorationPomdpModelChecker::Result::lowerBound); belexplres.def_readonly("upper_bound", &BeliefExplorationPomdpModelChecker::Result::upperBound); - m.def("create_interactive_mc", &storm::pomdp::api::createInteractiveUnfoldingModelChecker, py::arg("env"), py::arg("pomdp"), py::arg("use_clipping")); + m.def("create_interactive_mc", &storm::pomdp::api::createInteractiveUnfoldingModelChecker, py::arg("env"), py::arg("pomdp"), + py::arg("use_clipping")); } template void define_belief_exploration(py::module& m, std::string const& vtSuffix); \ No newline at end of file diff --git a/src/pomdp/tracker.cpp b/src/pomdp/tracker.cpp index 11740e2b98..ba577923dd 100644 --- a/src/pomdp/tracker.cpp +++ b/src/pomdp/tracker.cpp @@ -1,17 +1,19 @@ #include "tracker.h" #include "src/helpers.h" -#include #include #include +#include +template +using SparsePomdp = storm::models::sparse::Pomdp; +template +using SparsePomdpTracker = storm::generator::BeliefSupportTracker; -template using SparsePomdp = storm::models::sparse::Pomdp; -template using SparsePomdpTracker = storm::generator::BeliefSupportTracker; - -template using NDPomdpTrackerSparse = storm::generator::NondeterministicBeliefTracker>; -template using NDPomdpTrackerDense = storm::generator::NondeterministicBeliefTracker>; - +template +using NDPomdpTrackerSparse = storm::generator::NondeterministicBeliefTracker>; +template +using NDPomdpTrackerDense = storm::generator::NondeterministicBeliefTracker>; template void define_tracker(py::module& m, std::string const& vtSuffix) { @@ -25,41 +27,41 @@ void define_tracker(py::module& m, std::string const& vtSuffix) { sbel.def_property_readonly("risk", &storm::generator::SparseBeliefState::getRisk); sbel.def("__str__", &storm::generator::SparseBeliefState::toString); sbel.def_property_readonly("is_valid", &storm::generator::SparseBeliefState::isValid); -// -// py::class_> dbel(m, "DenseBeliefStateDouble", "Belief state in dense format"); -// dbel.def("get", &storm::generator::ObservationDenseBeliefState::get, py::arg("state")); -// dbel.def_property_readonly("risk", &storm::generator::ObservationDenseBeliefState::getRisk); -// dbel.def("__str__", &storm::generator::ObservationDenseBeliefState::toString); + // + // py::class_> dbel(m, "DenseBeliefStateDouble", "Belief state in dense format"); + // dbel.def("get", &storm::generator::ObservationDenseBeliefState::get, py::arg("state")); + // dbel.def_property_readonly("risk", &storm::generator::ObservationDenseBeliefState::getRisk); + // dbel.def("__str__", &storm::generator::ObservationDenseBeliefState::toString); - py::class_::Options> opts(m, ("NondeterministicBeliefTracker" + vtSuffix + "SparseOptions").c_str(), "Options for the corresponding tracker"); + py::class_::Options> opts(m, ("NondeterministicBeliefTracker" + vtSuffix + "SparseOptions").c_str(), + "Options for the corresponding tracker"); opts.def(py::init<>()); opts.def_readwrite("track_timeout", &NDPomdpTrackerSparse::Options::trackTimeOut); opts.def_readwrite("reduction_timeout", &NDPomdpTrackerSparse::Options::timeOut); opts.def_readwrite("reduction_wiggle", &NDPomdpTrackerSparse::Options::wiggle); - py::class_> ndetbelieftracker(m, ("NondeterministicBeliefTracker" + vtSuffix + "Sparse").c_str(), "Tracker for belief states and uncontrollable actions"); + py::class_> ndetbelieftracker(m, ("NondeterministicBeliefTracker" + vtSuffix + "Sparse").c_str(), + "Tracker for belief states and uncontrollable actions"); ndetbelieftracker.def(py::init const&, typename NDPomdpTrackerSparse::Options>(), py::arg("pomdp"), py::arg("options")); ndetbelieftracker.def("reset", &NDPomdpTrackerSparse::reset); ndetbelieftracker.def("set_risk", &NDPomdpTrackerSparse::setRisk, py::arg("risk")); - ndetbelieftracker.def("obtain_current_risk",&NDPomdpTrackerSparse::getCurrentRisk, py::arg("max")=true); + ndetbelieftracker.def("obtain_current_risk", &NDPomdpTrackerSparse::getCurrentRisk, py::arg("max") = true); ndetbelieftracker.def("track", &NDPomdpTrackerSparse::track, py::arg("observation")); ndetbelieftracker.def("obtain_beliefs", &NDPomdpTrackerSparse::getCurrentBeliefs); ndetbelieftracker.def("size", &NDPomdpTrackerSparse::getNumberOfBeliefs); ndetbelieftracker.def("dimension", &NDPomdpTrackerSparse::getCurrentDimension); ndetbelieftracker.def("obtain_last_observation", &NDPomdpTrackerSparse::getCurrentObservation); - ndetbelieftracker.def("reduce",&NDPomdpTrackerSparse::reduce); + ndetbelieftracker.def("reduce", &NDPomdpTrackerSparse::reduce); ndetbelieftracker.def("reduction_timed_out", &NDPomdpTrackerSparse::hasTimedOut); -// py::class_> ndetbelieftrackerd(m, "NondeterministicBeliefTrackerDoubleDense", "Tracker for belief states and uncontrollable actions"); -// ndetbelieftrackerd.def(py::init const&>(), py::arg("pomdp")); -// ndetbelieftrackerd.def("reset", &NDPomdpTrackerDense::reset); -// ndetbelieftrackerd.def("set_risk", &NDPomdpTrackerDense::setRisk, py::arg("risk")); -// ndetbelieftrackerd.def("obtain_current_risk",&NDPomdpTrackerDense::getCurrentRisk, py::arg("max")=true); -// ndetbelieftrackerd.def("track", &NDPomdpTrackerDense::track, py::arg("observation")); -// ndetbelieftrackerd.def("obtain_beliefs", &NDPomdpTrackerDense::getCurrentBeliefs); -// ndetbelieftrackerd.def("obtain_last_observation", &NDPomdpTrackerDense::getCurrentObservation); -// ndetbelieftrackerd.def("reduce",&NDPomdpTrackerDense::reduce); - + // py::class_> ndetbelieftrackerd(m, "NondeterministicBeliefTrackerDoubleDense", "Tracker for belief states and + // uncontrollable actions"); ndetbelieftrackerd.def(py::init const&>(), py::arg("pomdp")); ndetbelieftrackerd.def("reset", + // &NDPomdpTrackerDense::reset); ndetbelieftrackerd.def("set_risk", &NDPomdpTrackerDense::setRisk, py::arg("risk")); + // ndetbelieftrackerd.def("obtain_current_risk",&NDPomdpTrackerDense::getCurrentRisk, py::arg("max")=true); + // ndetbelieftrackerd.def("track", &NDPomdpTrackerDense::track, py::arg("observation")); + // ndetbelieftrackerd.def("obtain_beliefs", &NDPomdpTrackerDense::getCurrentBeliefs); + // ndetbelieftrackerd.def("obtain_last_observation", &NDPomdpTrackerDense::getCurrentObservation); + // ndetbelieftrackerd.def("reduce",&NDPomdpTrackerDense::reduce); } template void define_tracker(py::module& m, std::string const& vtSuffix); diff --git a/src/pomdp/transformations.cpp b/src/pomdp/transformations.cpp index bfd88d72d4..c4a01270a5 100644 --- a/src/pomdp/transformations.cpp +++ b/src/pomdp/transformations.cpp @@ -1,9 +1,9 @@ #include "transformations.h" -#include "storm-pomdp/transformer/MakePOMDPCanonic.h" -#include "storm-pomdp/transformer/PomdpMemoryUnfolder.h" -#include "storm-pomdp/transformer/BinaryPomdpTransformer.h" #include "storm-pomdp/transformer/ApplyFiniteSchedulerToPomdp.h" +#include "storm-pomdp/transformer/BinaryPomdpTransformer.h" +#include "storm-pomdp/transformer/MakePOMDPCanonic.h" #include "storm-pomdp/transformer/ObservationTraceUnfolder.h" +#include "storm-pomdp/transformer/PomdpMemoryUnfolder.h" #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/storage/expressions/ExpressionManager.h" @@ -14,7 +14,9 @@ std::shared_ptr> make_canonic(storm::mod } template -std::shared_ptr> unfold_memory(storm::models::sparse::Pomdp const& pomdp, storm::storage::PomdpMemory const& memory, bool addMemoryLabels, bool keepStateValuations) { +std::shared_ptr> unfold_memory(storm::models::sparse::Pomdp const& pomdp, + storm::storage::PomdpMemory const& memory, bool addMemoryLabels, + bool keepStateValuations) { storm::transformer::PomdpMemoryUnfolder unfolder(pomdp, memory, addMemoryLabels, keepStateValuations); return unfolder.transform(); } @@ -22,43 +24,50 @@ std::shared_ptr> unfold_memory(storm::mo template std::shared_ptr> make_simple(storm::models::sparse::Pomdp const& pomdp, bool keepStateValuations) { storm::transformer::BinaryPomdpTransformer transformer; - return transformer.transform(pomdp,true, keepStateValuations).transformedPomdp; + return transformer.transform(pomdp, true, keepStateValuations).transformedPomdp; } template -std::shared_ptr> apply_unknown_fsc(storm::models::sparse::Pomdp const& pomdp, storm::transformer::PomdpFscApplicationMode const& applicationMode) { +std::shared_ptr> apply_unknown_fsc(storm::models::sparse::Pomdp const& pomdp, + storm::transformer::PomdpFscApplicationMode const& applicationMode) { storm::transformer::ApplyFiniteSchedulerToPomdp transformer(pomdp); return transformer.transform(applicationMode); } template -std::shared_ptr> unfold_trace(storm::models::sparse::Pomdp const& pomdp, std::shared_ptr& exprManager, std::vector const& observationTrace, std::vector const& riskDef ) { +std::shared_ptr> unfold_trace(storm::models::sparse::Pomdp const& pomdp, + std::shared_ptr& exprManager, + std::vector const& observationTrace, std::vector const& riskDef) { storm::pomdp::ObservationTraceUnfolder transformer(pomdp, exprManager); return transformer.transform(observationTrace, riskDef); } // STANDARD, SIMPLE_LINEAR, SIMPLE_LINEAR_INVERSE, SIMPLE_LOG, FULL -void define_transformations_nt(py::module &m) { +void define_transformations_nt(py::module& m) { py::enum_(m, "PomdpFscApplicationMode") - .value("standard", storm::transformer::PomdpFscApplicationMode::STANDARD) - .value("simple_linear", storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR) - .value("simple_linear_inverse", storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR_INVERSE) - .value("simple_log", storm::transformer::PomdpFscApplicationMode::SIMPLE_LOG) - .value("full", storm::transformer::PomdpFscApplicationMode::FULL) - ; - + .value("standard", storm::transformer::PomdpFscApplicationMode::STANDARD) + .value("simple_linear", storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR) + .value("simple_linear_inverse", storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR_INVERSE) + .value("simple_log", storm::transformer::PomdpFscApplicationMode::SIMPLE_LOG) + .value("full", storm::transformer::PomdpFscApplicationMode::FULL); } template void define_transformations(py::module& m, std::string const& vtSuffix) { m.def(("_make_canonic_" + vtSuffix).c_str(), &make_canonic, "Return a canonicly-ordered POMDP", py::arg("pomdp")); - m.def(("_unfold_memory_" + vtSuffix).c_str(), &unfold_memory, "Unfold memory into a POMDP", py::arg("pomdp"), py::arg("memorystructure"), py::arg("memorylabels") = false, py::arg("keep_state_valuations")=false); - m.def(("_make_simple_"+ vtSuffix).c_str(), &make_simple, "Make POMDP simple", py::arg("pomdp"), py::arg("keep_state_valuations")=false); - m.def(("_apply_unknown_fsc_" + vtSuffix).c_str(), &apply_unknown_fsc, "Apply unknown FSC",py::arg("pomdp"), py::arg("application_mode")=storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR); - //m.def(("_unfold_trace_" + vtSuffix).c_str(), &unfold_trace, "Unfold observed trace", py::arg("pomdp"), py::arg("expression_manager"),py::arg("observation_trace"), py::arg("risk_definition")); + m.def(("_unfold_memory_" + vtSuffix).c_str(), &unfold_memory, "Unfold memory into a POMDP", py::arg("pomdp"), py::arg("memorystructure"), + py::arg("memorylabels") = false, py::arg("keep_state_valuations") = false); + m.def(("_make_simple_" + vtSuffix).c_str(), &make_simple, "Make POMDP simple", py::arg("pomdp"), py::arg("keep_state_valuations") = false); + m.def(("_apply_unknown_fsc_" + vtSuffix).c_str(), &apply_unknown_fsc, "Apply unknown FSC", py::arg("pomdp"), + py::arg("application_mode") = storm::transformer::PomdpFscApplicationMode::SIMPLE_LINEAR); + // m.def(("_unfold_trace_" + vtSuffix).c_str(), &unfold_trace, "Unfold observed trace", py::arg("pomdp"), + // py::arg("expression_manager"),py::arg("observation_trace"), py::arg("risk_definition")); - py::class_> unfolder(m, ("ObservationTraceUnfolder" + vtSuffix).c_str(), "Unfolds observation traces in models"); - unfolder.def(py::init const&, std::vector const&, std::shared_ptr&>(), py::arg("model"), py::arg("risk"), py::arg("expression_manager")); + py::class_> unfolder(m, ("ObservationTraceUnfolder" + vtSuffix).c_str(), + "Unfolds observation traces in models"); + unfolder.def( + py::init const&, std::vector const&, std::shared_ptr&>(), + py::arg("model"), py::arg("risk"), py::arg("expression_manager")); unfolder.def("transform", &storm::pomdp::ObservationTraceUnfolder::transform, py::arg("trace")); unfolder.def("extend", &storm::pomdp::ObservationTraceUnfolder::extend, py::arg("new_observation")); unfolder.def("reset", &storm::pomdp::ObservationTraceUnfolder::reset, py::arg("new_observation")); diff --git a/src/pycarl/common.h b/src/pycarl/common.h index ab00ae398a..854a8c6f91 100644 --- a/src/pycarl/common.h +++ b/src/pycarl/common.h @@ -1,11 +1,10 @@ #pragma once -#include #include +#include #include -#include #include - +#include #include @@ -19,28 +18,25 @@ namespace py = pybind11; #define PY_RDIV "__rdiv__" #endif -struct NoPickling: public std::exception { +struct NoPickling : public std::exception { virtual const char* what() const throw() { return "Pickling support not implemented!"; } }; - - // `boost::variant` as an example -- can be any `std::variant`-like container namespace pybind11 { - namespace detail { - template - struct type_caster> : variant_caster> {}; - - // Specifies the function used to visit the variant -- `apply_visitor` instead of `visit` - template <> - struct visit_helper { - template - static auto call(Args &&...args) - -> decltype(boost::apply_visitor(std::forward(args)...)) { - return boost::apply_visitor(std::forward(args)...); - } - }; +namespace detail { +template +struct type_caster> : variant_caster> {}; + +// Specifies the function used to visit the variant -- `apply_visitor` instead of `visit` +template<> +struct visit_helper { + template + static auto call(Args&&... args) -> decltype(boost::apply_visitor(std::forward(args)...)) { + return boost::apply_visitor(std::forward(args)...); } -} // namespace pybind11::detail \ No newline at end of file +}; +} // namespace detail +} // namespace pybind11 \ No newline at end of file diff --git a/src/pycarl/core/bound_type.cpp b/src/pycarl/core/bound_type.cpp index e2671e4113..6e9fd1a86f 100644 --- a/src/pycarl/core/bound_type.cpp +++ b/src/pycarl/core/bound_type.cpp @@ -1,13 +1,11 @@ #include "bound_type.h" -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" - +#include "src/pycarl/types.h" void define_boundtype(py::module& m) { py::enum_(m, "BoundType") .value("STRICT", carl::BoundType::STRICT) .value("WEAK", carl::BoundType::WEAK) - .value("INFTY", carl::BoundType::INFTY) - ; + .value("INFTY", carl::BoundType::INFTY); } diff --git a/src/pycarl/core/monomial.cpp b/src/pycarl/core/monomial.cpp index 69c41abdc7..27aefbb455 100644 --- a/src/pycarl/core/monomial.cpp +++ b/src/pycarl/core/monomial.cpp @@ -1,43 +1,36 @@ #include "monomial.h" -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" +#include "src/pycarl/types.h" void define_monomial(py::module& m) { py::class_>(m, "Monomial") - .def("__pow__", [](const Monomial::Arg& var, carl::uint exp) {return var->pow(exp);}) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) + .def("__pow__", [](const Monomial::Arg& var, carl::uint exp) { return var->pow(exp); }) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) - .def("__pos__", [](const Monomial::Arg& var) {return Monomial::Arg(var);}) + .def("__pos__", [](const Monomial::Arg& var) { return Monomial::Arg(var); }) - .def_property_readonly("tdeg", [](const Monomial::Arg& arg) { return arg->tdeg();} ) - .def_property_readonly("exponents", [](const Monomial::Arg& arg) { return arg->exponents();} ) + .def_property_readonly("tdeg", [](const Monomial::Arg& arg) { return arg->tdeg(); }) + .def_property_readonly("exponents", [](const Monomial::Arg& arg) { return arg->exponents(); }) .def("__str__", &streamToString) .def("__len__", [](const Monomial::Arg& m) { return m->nrVariables(); }) - .def("__getitem__", [](const Monomial::Arg& m, std::size_t index) { return *(m->begin()+index); }) - .def("__iter__", [](const Monomial::Arg& m) { return py::make_iterator(m->begin(), m->end()); }, - py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def(py::pickle( - [](const Monomial& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> std::shared_ptr { - throw NoPickling(); - } - )) - .def("__hash__", [](const Monomial& v) { std::hash h; return h(v);}) - ; - - - m.def("create_monomial", [] (const carl::Variable& v, carl::exponent e){ - return carl::createMonomial(v, e); - }, "Create monomial", py::arg("variable"), py::arg("exponent")); - m.def("clear_monomial_pool", [](){ - carl::MonomialPool::getInstance().clear(); - }, "Clear monomial pool and remove all monomials"); - + .def("__getitem__", [](const Monomial::Arg& m, std::size_t index) { return *(m->begin() + index); }) + .def( + "__iter__", [](const Monomial::Arg& m) { return py::make_iterator(m->begin(), m->end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def(py::pickle([](const Monomial& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> std::shared_ptr { throw NoPickling(); })) + .def("__hash__", [](const Monomial& v) { + std::hash h; + return h(v); + }); + + m.def( + "create_monomial", [](const carl::Variable& v, carl::exponent e) { return carl::createMonomial(v, e); }, "Create monomial", py::arg("variable"), + py::arg("exponent")); + m.def("clear_monomial_pool", []() { carl::MonomialPool::getInstance().clear(); }, "Clear monomial pool and remove all monomials"); } diff --git a/src/pycarl/core/variable.cpp b/src/pycarl/core/variable.cpp index 1c19a7b426..439a232aab 100644 --- a/src/pycarl/core/variable.cpp +++ b/src/pycarl/core/variable.cpp @@ -1,13 +1,12 @@ -#include #include #include +#include -#include "variable.h" #include "src/pycarl/helpers.h" #include "src/pycarl/types.h" +#include "variable.h" - -carl::Variable getOrCreateVariable(std::string const & name, carl::VariableType type) { +carl::Variable getOrCreateVariable(std::string const& name, carl::VariableType type) { // Variables are constructed by the Pool. Note that for a given name, // two Variable instances may differ, but refer to the same id (data) auto& pool = carl::VariablePool::getInstance(); @@ -26,18 +25,16 @@ void define_variabletype(py::module& m) { } void define_variable(py::module& m) { - py::class_(m, "Variable") .def(py::init(), py::arg("other")) - .def(py::init([] (std::string name, carl::VariableType type) { - return freshVariable(name, type); - }), py::arg("name"), py::arg("type") = carl::VariableType::VT_REAL) - .def(py::init([] (carl::VariableType type) { - return freshVariable(type); - //return std::unique_ptr(new carl::Variable(tmp)); - }), py::arg("type") = carl::VariableType::VT_REAL) - .def("__mul__", static_cast(&carl::operator*)) - + .def(py::init([](std::string name, carl::VariableType type) { return freshVariable(name, type); }), py::arg("name"), + py::arg("type") = carl::VariableType::VT_REAL) + .def(py::init([](carl::VariableType type) { + return freshVariable(type); + // return std::unique_ptr(new carl::Variable(tmp)); + }), + py::arg("type") = carl::VariableType::VT_REAL) + .def("__mul__", static_cast(&carl::operator*)) .def(py::self == py::self) .def(py::self != py::self) @@ -46,38 +43,43 @@ void define_variable(py::module& m) { .def(py::self > py::self) .def(py::self >= py::self) - .def_property_readonly("name", [](const carl::Variable& r) -> std::string { - if (r != carl::Variable::NO_VARIABLE) { - return r.name(); - } else { - return std::string("__NOVAR__"); - } - }) + .def_property_readonly("name", + [](const carl::Variable& r) -> std::string { + if (r != carl::Variable::NO_VARIABLE) { + return r.name(); + } else { + return std::string("__NOVAR__"); + } + }) .def_property_readonly("type", &carl::Variable::type) .def_property_readonly("id", &carl::Variable::id) .def_property_readonly("rank", &carl::Variable::rank) - .def("__repr__", [](const carl::Variable& r) { if (r != carl::Variable::NO_VARIABLE) { return ""; } else { return std::string("");} }) + .def("__repr__", + [](const carl::Variable& r) { + if (r != carl::Variable::NO_VARIABLE) { + return ""; + } else { + return std::string(""); + } + }) .def("__str__", &streamToString) - .def_property_readonly("is_no_variable", [](const carl::Variable& v) {return v == carl::Variable::NO_VARIABLE;}) - // TODO get state has an issue if there are several variables with the same name; they cannot be distinguished afterwards - .def(py::pickle( - [](const carl::Variable& v) { - return std::make_tuple(v.name(), carl::to_string(v.type())); - }, - [](const std::tuple& data ) { - return getOrCreateVariable(std::get<0>(data), carl::variableTypeFromString(std::get<1>(data))); - } - )) - .def("__hash__", [](const carl::Variable& v) { std::hash h; return h(v);}) - - ; + .def_property_readonly("is_no_variable", [](const carl::Variable& v) { return v == carl::Variable::NO_VARIABLE; }) + // TODO get state has an issue if there are several variables with the same name; they cannot be distinguished afterwards + .def(py::pickle([](const carl::Variable& v) { return std::make_tuple(v.name(), carl::to_string(v.type())); }, + [](const std::tuple& data) { + return getOrCreateVariable(std::get<0>(data), carl::variableTypeFromString(std::get<1>(data))); + })) + .def("__hash__", + [](const carl::Variable& v) { + std::hash h; + return h(v); + }) - m.def("variable_with_name", [](std::string const& name){ - return carl::VariablePool::getInstance().findVariableWithName(name); - }, "Get a variable from the pool with the given name."); + ; + m.def( + "variable_with_name", [](std::string const& name) { return carl::VariablePool::getInstance().findVariableWithName(name); }, + "Get a variable from the pool with the given name."); - m.def("clear_variable_pool", [](){ - carl::VariablePool::getInstance().clear(); - }, "Clear variable pool and remove all variables"); + m.def("clear_variable_pool", []() { carl::VariablePool::getInstance().clear(); }, "Clear variable pool and remove all variables"); } diff --git a/src/pycarl/formula/formula_type.cpp b/src/pycarl/formula/formula_type.cpp index 4c75e5d08e..c6f6b8c7ba 100644 --- a/src/pycarl/formula/formula_type.cpp +++ b/src/pycarl/formula/formula_type.cpp @@ -19,6 +19,5 @@ void define_formula_type(py::module& m) { .value("IFF", carl::FormulaType::IFF) .value("CONSTRAINT", carl::FormulaType::CONSTRAINT) .value("BITVECTOR", carl::FormulaType::BITVECTOR) - .value("UEQ", carl::FormulaType::UEQ) - ; + .value("UEQ", carl::FormulaType::UEQ); } \ No newline at end of file diff --git a/src/pycarl/formula/relation.cpp b/src/pycarl/formula/relation.cpp index ac76723f76..0922b8649a 100644 --- a/src/pycarl/formula/relation.cpp +++ b/src/pycarl/formula/relation.cpp @@ -11,6 +11,5 @@ void define_relation(py::module& m) { .value("LEQ", carl::Relation::LEQ) .value("GREATER", carl::Relation::GREATER) .value("GEQ", carl::Relation::GEQ) - .def("__str__", &streamToString, py::prepend() /* use custom method instead of default enum overload */) - ; + .def("__str__", &streamToString, py::prepend() /* use custom method instead of default enum overload */); } diff --git a/src/pycarl/helpers.h b/src/pycarl/helpers.h index 83de49c3fc..eb23fd73a4 100644 --- a/src/pycarl/helpers.h +++ b/src/pycarl/helpers.h @@ -8,7 +8,7 @@ * Used for __str__ functions. */ template -std::string streamToString(T const & t) { +std::string streamToString(T const& t) { std::stringstream ss; ss << t; return ss.str(); diff --git a/src/pycarl/mod_cln.cpp b/src/pycarl/mod_cln.cpp index 38ddcc30b6..6b97d21090 100644 --- a/src/pycarl/mod_cln.cpp +++ b/src/pycarl/mod_cln.cpp @@ -1,15 +1,15 @@ #include "common.h" #include "types.h" -#include "typed_core/integer.h" -#include "typed_core/rational.h" -#include "typed_core/term.h" -#include "typed_core/polynomial.h" -#include "typed_core/rationalfunction.h" #include "typed_core/factorization.h" #include "typed_core/factorizedpolynomial.h" #include "typed_core/factorizedrationalfunction.h" +#include "typed_core/integer.h" #include "typed_core/interval.h" +#include "typed_core/polynomial.h" +#include "typed_core/rational.h" +#include "typed_core/rationalfunction.h" +#include "typed_core/term.h" PYBIND11_MODULE(_cln, m) { m.attr("__name__") = "stormpy.pycarl.cln"; diff --git a/src/pycarl/mod_core.cpp b/src/pycarl/mod_core.cpp index 2feaa42c14..5823f6b09e 100644 --- a/src/pycarl/mod_core.cpp +++ b/src/pycarl/mod_core.cpp @@ -1,8 +1,8 @@ #include "common.h" -#include "core/variable.h" -#include "core/monomial.h" #include "core/bound_type.h" +#include "core/monomial.h" +#include "core/variable.h" #include "typed_core/interval.h" PYBIND11_MODULE(_pycarl_core, m) { diff --git a/src/pycarl/mod_formula.cpp b/src/pycarl/mod_formula.cpp index 2799fae40a..ac8e1560b7 100644 --- a/src/pycarl/mod_formula.cpp +++ b/src/pycarl/mod_formula.cpp @@ -6,13 +6,11 @@ PYBIND11_MODULE(_formula, m) { m.attr("__name__") = "stormpy.pycarl.formula"; - m.doc() = "pycarl formula untyped functions"; + m.doc() = "pycarl formula untyped functions"; + // Constraint relies on Rational + m.import("stormpy.pycarl"); - // Constraint relies on Rational - m.import("stormpy.pycarl"); - - define_relation(m); - define_formula_type(m); - + define_relation(m); + define_formula_type(m); } diff --git a/src/pycarl/mod_gmp.cpp b/src/pycarl/mod_gmp.cpp index a3d2167fa8..3df4187a63 100644 --- a/src/pycarl/mod_gmp.cpp +++ b/src/pycarl/mod_gmp.cpp @@ -1,15 +1,15 @@ #include "common.h" #include "types.h" -#include "typed_core/integer.h" -#include "typed_core/rational.h" -#include "typed_core/term.h" -#include "typed_core/polynomial.h" -#include "typed_core/rationalfunction.h" #include "typed_core/factorization.h" #include "typed_core/factorizedpolynomial.h" #include "typed_core/factorizedrationalfunction.h" +#include "typed_core/integer.h" #include "typed_core/interval.h" +#include "typed_core/polynomial.h" +#include "typed_core/rational.h" +#include "typed_core/rationalfunction.h" +#include "typed_core/term.h" PYBIND11_MODULE(_gmp, m) { m.attr("__name__") = "stormpy.pycarl.gmp"; diff --git a/src/pycarl/mod_parse.cpp b/src/pycarl/mod_parse.cpp index 5b942799c0..8b4f639caa 100644 --- a/src/pycarl/mod_parse.cpp +++ b/src/pycarl/mod_parse.cpp @@ -1,7 +1,6 @@ #include "common.h" - #include #include @@ -15,7 +14,6 @@ PYBIND11_MODULE(_parse, m) { // Constraint relies on Rational m.import("stormpy.pycarl"); - py::enum_(m, "_ParserReturnType") .value("Rational", carlparser::ParserReturnType::Rational) .value("Variable", carlparser::ParserReturnType::Variable) @@ -24,7 +22,5 @@ PYBIND11_MODULE(_parse, m) { .value("Polynomial", carlparser::ParserReturnType::Polynomial) .value("RationalFunction", carlparser::ParserReturnType::RationalFunction) .value("Constraint", carlparser::ParserReturnType::Constraint) - .value("Formula", carlparser::ParserReturnType::Formula) - ; - + .value("Formula", carlparser::ParserReturnType::Formula); } diff --git a/src/pycarl/mod_typed_formula.cpp b/src/pycarl/mod_typed_formula.cpp index 1ea42f52e9..15fbc4a032 100644 --- a/src/pycarl/mod_typed_formula.cpp +++ b/src/pycarl/mod_typed_formula.cpp @@ -6,15 +6,13 @@ PYBIND11_MODULE(_formula, m) { m.attr("__name__") = "stormpy.pycarl.formula"; - m.doc() = "pycarl formula typed functions"; + m.doc() = "pycarl formula typed functions"; - - // Constraint relies on Rational - m.import("stormpy.pycarl"); + // Constraint relies on Rational + m.import("stormpy.pycarl"); m.import("stormpy.pycarl.formula"); - define_constraint(m); - define_simple_constraint(m); - define_formula(m); - + define_constraint(m); + define_simple_constraint(m); + define_formula(m); } diff --git a/src/pycarl/mod_typed_parse.cpp b/src/pycarl/mod_typed_parse.cpp index 27d459a029..3d7d0d4005 100644 --- a/src/pycarl/mod_typed_parse.cpp +++ b/src/pycarl/mod_typed_parse.cpp @@ -22,10 +22,8 @@ PYBIND11_MODULE(_parse, m) { .def("as_polynomial", &ParserResultWrapper::asPolynomial) .def("as_rational_function", &ParserResultWrapper::asRationalFunction) .def("as_constraint", &ParserResultWrapper::asConstraint) - .def("as_formula", &ParserResultWrapper::asFormula) - ; + .def("as_formula", &ParserResultWrapper::asFormula); m.def("_deserialize", &from_string); m.def("_check_parsed_type", &carlparser::check_type); - } diff --git a/src/pycarl/typed_core/factorization.cpp b/src/pycarl/typed_core/factorization.cpp index 62827ee8ef..47d0370808 100644 --- a/src/pycarl/typed_core/factorization.cpp +++ b/src/pycarl/typed_core/factorization.cpp @@ -1,21 +1,14 @@ #include "factorization.h" -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" - +#include "src/pycarl/types.h" void define_factorizationcache(py::module& m) { - py::class_, std::shared_ptr>>(m, "_FactorizationCache", "Cache storing all factorized polynomials") + py::class_, std::shared_ptr>>(m, "_FactorizationCache", + "Cache storing all factorized polynomials") .def(py::init(), "Constructor") - .def(py::pickle( - [](const carl::Cache& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> std::shared_ptr> { - throw NoPickling(); - } - )) - ; + .def(py::pickle([](const carl::Cache& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> std::shared_ptr> { throw NoPickling(); })); } void define_factorization(py::module& m) { @@ -23,20 +16,11 @@ void define_factorization(py::module& m) { .def("__str__", &streamToString) .def(py::self == py::self) - .def("__len__", [](const Factorization& f) { - return f.size(); - }) - .def("__iter__", [](const Factorization& f) { - return py::make_iterator(f.begin(), f.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def("__len__", [](const Factorization& f) { return f.size(); }) + .def( + "__iter__", [](const Factorization& f) { return py::make_iterator(f.begin(), f.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def(py::pickle( - [](const Factorization& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> Factorization { - throw NoPickling(); - } - )) - ; + .def(py::pickle([](const Factorization& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> Factorization { throw NoPickling(); })); } diff --git a/src/pycarl/typed_core/factorizedpolynomial.cpp b/src/pycarl/typed_core/factorizedpolynomial.cpp index d1ec5917e7..9c33b6b469 100644 --- a/src/pycarl/typed_core/factorizedpolynomial.cpp +++ b/src/pycarl/typed_core/factorizedpolynomial.cpp @@ -1,7 +1,7 @@ #include "factorizedpolynomial.h" -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" +#include "src/pycarl/types.h" void define_factorizedpolynomial(py::module& m) { py::class_(m, "FactorizedPolynomial", "Represent a polynomial with its factorization") @@ -13,49 +13,48 @@ void define_factorizedpolynomial(py::module& m) { .def("constant_part", &FactorizedPolynomial::constantPart) .def_property("coefficient", &FactorizedPolynomial::coefficient, &FactorizedPolynomial::setCoefficient) - .def("factorization", [](const FactorizedPolynomial& pol) { + .def( + "factorization", + [](const FactorizedPolynomial& pol) { if (pol.isConstant()) return Factorization(); else return pol.factorization(); - }, "Get factorization") - .def("polynomial", [](const FactorizedPolynomial& pol) { + }, + "Get factorization") + .def( + "polynomial", + [](const FactorizedPolynomial& pol) { if (pol.isConstant()) throw std::invalid_argument("Function not applicable for constants"); else return pol.polynomialWithCoefficient(); - },"Get underlying polynomial") + }, + "Get underlying polynomial") .def("cache", &FactorizedPolynomial::pCache) .def("evaluate", &FactorizedPolynomial::evaluate) .def("gather_variables", static_cast (FactorizedPolynomial::*)() const>(&FactorizedPolynomial::gatherVariables)) - .def("derive", [](FactorizedPolynomial const& pol, carl::Variable const& var) { - return pol.derivative(var, 1); - }, "Compute the derivative", py::arg("variable")) + .def( + "derive", [](FactorizedPolynomial const& pol, carl::Variable const& var) { return pol.derivative(var, 1); }, "Compute the derivative", + py::arg("variable")) .def("__str__", &streamToString) - .def("to_smt2", [](FactorizedPolynomial const& pol) { - return pol.toString(false, true); - }) + .def("to_smt2", [](FactorizedPolynomial const& pol) { return pol.toString(false, true); }) .def(py::self - py::self) .def(py::self + py::self) .def(py::self * py::self) - .def("__pow__", [](const FactorizedPolynomial& pol, carl::uint exp) { - return pol.pow(exp); - }, py::arg("exponent"), "Raise polynomial to the power") + .def( + "__pow__", [](const FactorizedPolynomial& pol, carl::uint exp) { return pol.pow(exp); }, py::arg("exponent"), "Raise polynomial to the power") .def(py::self == py::self) .def(py::self != py::self) .def(py::self == Rational()) .def(py::self != Rational()) - .def(py::pickle( - [](const FactorizedPolynomial& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> FactorizedPolynomial { - throw NoPickling(); - } - )) - .def("__hash__", [](const FactorizedPolynomial& v) { std::hash h; return h(v);}) - ; + .def(py::pickle([](const FactorizedPolynomial& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> FactorizedPolynomial { throw NoPickling(); })) + .def("__hash__", [](const FactorizedPolynomial& v) { + std::hash h; + return h(v); + }); } diff --git a/src/pycarl/typed_core/factorizedpolynomial.h b/src/pycarl/typed_core/factorizedpolynomial.h index 95fa01fc84..4e49d0cd63 100644 --- a/src/pycarl/typed_core/factorizedpolynomial.h +++ b/src/pycarl/typed_core/factorizedpolynomial.h @@ -3,4 +3,3 @@ #include "src/pycarl/common.h" void define_factorizedpolynomial(py::module& m); - diff --git a/src/pycarl/typed_core/factorizedrationalfunction.cpp b/src/pycarl/typed_core/factorizedrationalfunction.cpp index b2d7dd792f..07ad11fc40 100644 --- a/src/pycarl/typed_core/factorizedrationalfunction.cpp +++ b/src/pycarl/typed_core/factorizedrationalfunction.cpp @@ -1,12 +1,11 @@ #include "factorizedrationalfunction.h" - -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" - +#include "src/pycarl/types.h" void define_factorizedrationalfunction(py::module& m) { - py::class_(m, "FactorizedRationalFunction", "Represent a rational function, that is the fraction of two factorized polynomials ") + py::class_(m, "FactorizedRationalFunction", + "Represent a rational function, that is the fraction of two factorized polynomials ") .def(py::init()) .def(py::init()) .def("evaluate", &FactorizedRationalFunction::evaluate) @@ -15,20 +14,19 @@ void define_factorizedrationalfunction(py::module& m) { .def_property_readonly("denominator", &FactorizedRationalFunction::denominator) .def("is_constant", &FactorizedRationalFunction::isConstant) .def("constant_part", &FactorizedRationalFunction::constantPart) - .def("rational_function", [](FactorizedRationalFunction const& rf) -> RationalFunction { - if(rf.isConstant()) { - return RationalFunction(rf.constantPart()); - } else { - return RationalFunction(rf.nominator().polynomialWithCoefficient(), rf.denominator().polynomialWithCoefficient()); - }; - }) - .def("derive", [](FactorizedRationalFunction const& ratFunc, carl::Variable const& var) { - return ratFunc.derivative(var, 1); - }, "Compute the derivative", py::arg("variable")) + .def("rational_function", + [](FactorizedRationalFunction const& rf) -> RationalFunction { + if (rf.isConstant()) { + return RationalFunction(rf.constantPart()); + } else { + return RationalFunction(rf.nominator().polynomialWithCoefficient(), rf.denominator().polynomialWithCoefficient()); + }; + }) + .def( + "derive", [](FactorizedRationalFunction const& ratFunc, carl::Variable const& var) { return ratFunc.derivative(var, 1); }, "Compute the derivative", + py::arg("variable")) .def("__str__", &streamToString) - .def("to_smt2", [](FactorizedRationalFunction const& rf) { - return rf.toString(false, true); - }) + .def("to_smt2", [](FactorizedRationalFunction const& rf) { return rf.toString(false, true); }) .def(py::self - py::self) .def(py::self + py::self) @@ -37,14 +35,10 @@ void define_factorizedrationalfunction(py::module& m) { .def(py::self == py::self) .def(py::self != py::self) .def(py::self + Rational()) - .def(py::pickle( - [](const FactorizedRationalFunction& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> FactorizedRationalFunction { - throw NoPickling(); - } - )) - .def("__hash__", [](const FactorizedRationalFunction& v) { std::hash h; return h(v);}) - ; + .def(py::pickle([](const FactorizedRationalFunction& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> FactorizedRationalFunction { throw NoPickling(); })) + .def("__hash__", [](const FactorizedRationalFunction& v) { + std::hash h; + return h(v); + }); } diff --git a/src/pycarl/typed_core/integer.cpp b/src/pycarl/typed_core/integer.cpp index 7559b7bb68..96f82f457d 100644 --- a/src/pycarl/typed_core/integer.cpp +++ b/src/pycarl/typed_core/integer.cpp @@ -2,23 +2,22 @@ #include "src/pycarl/helpers.h" -#include "src/pycarl/types.h" -#include "carl/numbers/numbers.h" #include "carl/numbers/conversion/cln_gmp.h" - +#include "carl/numbers/numbers.h" +#include "src/pycarl/types.h" void define_cln_integer(py::module& m) { #ifdef PYCARL_USE_CLN py::class_(m, "Integer", "Class wrapping cln-integers") .def(py::init()) .def(py::init([](std::string const& val) { - cln::cl_I tmp; - bool suc = carl::try_parse(val, tmp); - if(!suc) { - throw std::invalid_argument("Cannot translate " + val + " into an integer."); - } - return tmp; - })) + cln::cl_I tmp; + bool suc = carl::try_parse(val, tmp); + if (!suc) { + throw std::invalid_argument("Cannot translate " + val + " into an integer."); + } + return tmp; + })) .def(py::init(&carl::convert)) .def(py::self + py::self) @@ -43,12 +42,17 @@ void define_cln_integer(py::module& m) { .def("__rmul__", [](const cln::cl_I& rhs, carl::Variable::Arg lhs) -> Term { return cln::cl_RA(rhs) * lhs; }) .def("__rmul__", [](const cln::cl_I& rhs, const Monomial::Arg& lhs) -> Term { return cln::cl_RA(rhs) * lhs; }) - .def(PY_DIV, [](const cln::cl_I& lhs, const cln::cl_I& rhs) -> cln::cl_RA { if (carl::isZero(rhs)) throw std::runtime_error("Div by zero"); return lhs / rhs; }) + .def(PY_DIV, + [](const cln::cl_I& lhs, const cln::cl_I& rhs) -> cln::cl_RA { + if (carl::isZero(rhs)) + throw std::runtime_error("Div by zero"); + return lhs / rhs; + }) .def("__pow__", static_cast(&carl::pow)) - .def("__pos__", [](const cln::cl_I& var) {return var;}) - .def("__neg__", [](const cln::cl_I& var) -> cln::cl_I {return -var;}) - .def("__abs__", [](const cln::cl_I& var) {return carl::abs(var);}) + .def("__pos__", [](const cln::cl_I& var) { return var; }) + .def("__neg__", [](const cln::cl_I& var) -> cln::cl_I { return -var; }) + .def("__abs__", [](const cln::cl_I& var) { return carl::abs(var); }) .def(py::self > py::self) .def(py::self < py::self) @@ -64,20 +68,15 @@ void define_cln_integer(py::module& m) { .def(py::self >= int()) .def(py::self <= int()) - .def("__float__", static_cast(&carl::toDouble)) .def("__str__", &streamToString) .def("__repr__", [](const cln::cl_I& r) { return "(r) + ">"; }) - .def(py::pickle( - [](const cln::cl_I& val) { - return std::tuple(carl::toString(val)); - }, - [](std::tuple data) { - return carl::parse(std::get<0>(data)); - } - )) - .def("__hash__", [](const cln::cl_I& v) { std::hash h; return h(v);}) - ; + .def(py::pickle([](const cln::cl_I& val) { return std::tuple(carl::toString(val)); }, + [](std::tuple data) { return carl::parse(std::get<0>(data)); })) + .def("__hash__", [](const cln::cl_I& v) { + std::hash h; + return h(v); + }); #endif } @@ -86,13 +85,13 @@ void define_gmp_integer(py::module& m) { py::class_(m, "Integer", "Class wrapping gmp-integers") .def(py::init()) .def(py::init([](std::string const& val) { - mpz_class tmp; - bool suc = carl::try_parse(val, tmp); - if(!suc) { - throw std::invalid_argument("Cannot translate " + val + " into an integer."); - } - return tmp; - })) + mpz_class tmp; + bool suc = carl::try_parse(val, tmp); + if (!suc) { + throw std::invalid_argument("Cannot translate " + val + " into an integer."); + } + return tmp; + })) #ifdef PYCARL_HAS_CLN .def(py::init(&carl::convert)) #endif @@ -122,12 +121,17 @@ void define_gmp_integer(py::module& m) { .def("__rmul__", [](const mpz_class& rhs, carl::Variable::Arg lhs) -> Term { return mpq_class(rhs) * lhs; }) .def("__rmul__", [](const mpz_class& rhs, const Monomial::Arg& lhs) -> Term { return mpq_class(rhs) * lhs; }) - .def(PY_DIV, [](const mpz_class& lhs, const mpz_class& rhs) -> mpq_class { if (carl::isZero(rhs)) throw std::runtime_error("Div by zero"); return lhs / rhs; }) + .def(PY_DIV, + [](const mpz_class& lhs, const mpz_class& rhs) -> mpq_class { + if (carl::isZero(rhs)) + throw std::runtime_error("Div by zero"); + return lhs / rhs; + }) .def("__pow__", static_cast(&carl::pow)) - .def("__pos__", [](const mpz_class& var) {return var;}) - .def("__neg__", [](const mpz_class& var) -> mpz_class {return -var;}) - .def("__abs__", [](const mpz_class& var) {return carl::abs(var);}) + .def("__pos__", [](const mpz_class& var) { return var; }) + .def("__neg__", [](const mpz_class& var) -> mpz_class { return -var; }) + .def("__abs__", [](const mpz_class& var) { return carl::abs(var); }) .def(py::self > py::self) .def(py::self < py::self) @@ -143,22 +147,14 @@ void define_gmp_integer(py::module& m) { .def(py::self >= int()) .def(py::self <= int()) - .def("__float__", static_cast(&carl::toDouble)) .def("__str__", &streamToString) .def("__repr__", [](const mpz_class& r) { return "(r) + ">"; }) - .def(py::pickle( - [](const mpz_class& val) -> std::tuple { - return std::tuple(carl::toString(val)); - }, - [](const std::tuple& data) -> mpz_class { - return carl::parse(std::get<0>(data)); - } - )) - .def("__hash__", [](const mpz_class& v) { std::hash h; return h(v);}) - ; + .def(py::pickle([](const mpz_class& val) -> std::tuple { return std::tuple(carl::toString(val)); }, + [](const std::tuple& data) -> mpz_class { return carl::parse(std::get<0>(data)); })) + .def("__hash__", [](const mpz_class& v) { + std::hash h; + return h(v); + }); #endif - } - - diff --git a/src/pycarl/typed_core/interval.h b/src/pycarl/typed_core/interval.h index ef1794e660..c156990b7b 100644 --- a/src/pycarl/typed_core/interval.h +++ b/src/pycarl/typed_core/interval.h @@ -1,120 +1,113 @@ #pragma once #include "src/pycarl/common.h" -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" +#include "src/pycarl/types.h" template void define_interval(py::module& m) { using Interval = carl::Interval; - py::class_(m, "Interval") - .def(py::init()) - .def(py::init()) - .def(py::init()) - - .def_static("unboundedInterval", &Interval::unboundedInterval) - .def_static("emptyInterval", &Interval::emptyInterval) - .def_static("zeroInterval", &Interval::zeroInterval) - - // TODO: does not work :-( - //.def_property("lower", &Interval::lower, &Interval::setLower) - .def("lower", &Interval::lower, py::return_value_policy::reference_internal) - .def("setLower", &Interval::setLower) - .def("upper", &Interval::upper, py::return_value_policy::reference_internal) - .def("setUpper", &Interval::setUpper) - - .def("isInfinite", &Interval::isInfinite) - .def("isUnbounded", &Interval::isUnbounded) - .def("isHalfBounded", &Interval::isHalfBounded) - .def("isEmpty", &Interval::isEmpty) - .def("isPointInterval", &Interval::isPointInterval) - .def("isOpenInterval", &Interval::isOpenInterval) - .def("isClosedInterval", &Interval::isClosedInterval) - .def("isZero", &Interval::isZero) - .def("isOne", &Interval::isOne) - .def("isPositive", &Interval::isPositive) - .def("isNegative", &Interval::isNegative) - .def("isSemiPositive", &Interval::isSemiPositive) - .def("isSemiNegative", &Interval::isSemiNegative) - - .def("integralPart", &Interval::integralPart) - .def("diameter", &Interval::diameter) - .def("center", [](const Interval& i){ return i.center(); }) - .def("sample", &Interval::sample) - .def("contains", [](const Interval& i, const Number& r){ return i.contains(r); }) - .def("contains", [](const Interval& i, const Interval& i2){ return i.contains(i2); }) - .def("meets", &Interval::meets) - .def("isSubset", &Interval::isSubset) - .def("isProperSubset", &Interval::isProperSubset) - - .def("div", &Interval::div) - - .def("inverse", &Interval::inverse) - .def("abs", &Interval::abs) - .def("__pow__", [](const Interval& i, carl::uint exp) { return i.pow(exp); }) - .def("intersectsWith", &Interval::intersectsWith) - .def("intersect", &Interval::intersect) - .def("unite", &Interval::unite) - .def("difference", &Interval::difference) - .def("complement", &Interval::complement) - .def("symmetricDifference", &Interval::symmetricDifference) - - .def(py::self + py::self) - .def(Number() + py::self) - .def(py::self + Number()) - .def(py::self += py::self) - .def(py::self += Number()) - - .def(-py::self) - - .def(py::self - py::self) - .def(Number() - py::self) - .def(py::self - Number()) - .def(py::self -= py::self) - .def(py::self -= Number()) - - .def(py::self * py::self) - .def(Number() * py::self) - .def(py::self * Number()) - .def(py::self *= py::self) - .def(py::self *= Number()) - - .def(py::self / Number()) - .def(py::self /= Number()) - - .def(py::self == py::self) - .def(py::self != py::self) - .def(py::self <= py::self) - .def(py::self <= Number()) - .def(Number() <= py::self) - .def(py::self >= py::self) - .def(py::self >= Number()) - .def(Number() >= py::self) - .def(py::self < py::self) - .def(py::self < Number()) - .def(Number() < py::self) - .def(py::self > py::self) - .def(py::self > Number()) - .def(Number() > py::self) - - .def("__str__", &streamToString) - .def("__repr__", [](const Interval& i) { return "(i) + ">"; }) - .def(py::pickle( - [](const Interval& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> Interval { - throw NoPickling(); - } - )) - ; - - m.def("isInteger", [](const Interval& i){ return carl::isInteger(i); }); - m.def("div", [](const Interval& l, const Interval& r){ return carl::div(l, r); }); - m.def("quotient", [](const Interval& l, const Interval& r){ return carl::quotient(l, r); }); - m.def("abs", [](const Interval& i){ return carl::abs(i); }); - m.def("pow", [](const Interval& i, carl::uint exp){ return carl::pow(i, exp); }); - m.def("floor", [](const Interval& i){ return carl::floor(i); }); - m.def("ceil", [](const Interval& i){ return carl::ceil(i); }); + py::class_(m, "Interval") + .def(py::init()) + .def(py::init()) + .def(py::init()) + + .def_static("unboundedInterval", &Interval::unboundedInterval) + .def_static("emptyInterval", &Interval::emptyInterval) + .def_static("zeroInterval", &Interval::zeroInterval) + + // TODO: does not work :-( + //.def_property("lower", &Interval::lower, &Interval::setLower) + .def("lower", &Interval::lower, py::return_value_policy::reference_internal) + .def("setLower", &Interval::setLower) + .def("upper", &Interval::upper, py::return_value_policy::reference_internal) + .def("setUpper", &Interval::setUpper) + + .def("isInfinite", &Interval::isInfinite) + .def("isUnbounded", &Interval::isUnbounded) + .def("isHalfBounded", &Interval::isHalfBounded) + .def("isEmpty", &Interval::isEmpty) + .def("isPointInterval", &Interval::isPointInterval) + .def("isOpenInterval", &Interval::isOpenInterval) + .def("isClosedInterval", &Interval::isClosedInterval) + .def("isZero", &Interval::isZero) + .def("isOne", &Interval::isOne) + .def("isPositive", &Interval::isPositive) + .def("isNegative", &Interval::isNegative) + .def("isSemiPositive", &Interval::isSemiPositive) + .def("isSemiNegative", &Interval::isSemiNegative) + + .def("integralPart", &Interval::integralPart) + .def("diameter", &Interval::diameter) + .def("center", [](const Interval& i) { return i.center(); }) + .def("sample", &Interval::sample) + .def("contains", [](const Interval& i, const Number& r) { return i.contains(r); }) + .def("contains", [](const Interval& i, const Interval& i2) { return i.contains(i2); }) + .def("meets", &Interval::meets) + .def("isSubset", &Interval::isSubset) + .def("isProperSubset", &Interval::isProperSubset) + + .def("div", &Interval::div) + + .def("inverse", &Interval::inverse) + .def("abs", &Interval::abs) + .def("__pow__", [](const Interval& i, carl::uint exp) { return i.pow(exp); }) + .def("intersectsWith", &Interval::intersectsWith) + .def("intersect", &Interval::intersect) + .def("unite", &Interval::unite) + .def("difference", &Interval::difference) + .def("complement", &Interval::complement) + .def("symmetricDifference", &Interval::symmetricDifference) + + .def(py::self + py::self) + .def(Number() + py::self) + .def(py::self + Number()) + .def(py::self += py::self) + .def(py::self += Number()) + + .def(-py::self) + + .def(py::self - py::self) + .def(Number() - py::self) + .def(py::self - Number()) + .def(py::self -= py::self) + .def(py::self -= Number()) + + .def(py::self * py::self) + .def(Number() * py::self) + .def(py::self * Number()) + .def(py::self *= py::self) + .def(py::self *= Number()) + + .def(py::self / Number()) + .def(py::self /= Number()) + + .def(py::self == py::self) + .def(py::self != py::self) + .def(py::self <= py::self) + .def(py::self <= Number()) + .def(Number() <= py::self) + .def(py::self >= py::self) + .def(py::self >= Number()) + .def(Number() >= py::self) + .def(py::self < py::self) + .def(py::self < Number()) + .def(Number() < py::self) + .def(py::self > py::self) + .def(py::self > Number()) + .def(Number() > py::self) + + .def("__str__", &streamToString) + .def("__repr__", [](const Interval& i) { return "(i) + ">"; }) + .def(py::pickle([](const Interval& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> Interval { throw NoPickling(); })); + + m.def("isInteger", [](const Interval& i) { return carl::isInteger(i); }); + m.def("div", [](const Interval& l, const Interval& r) { return carl::div(l, r); }); + m.def("quotient", [](const Interval& l, const Interval& r) { return carl::quotient(l, r); }); + m.def("abs", [](const Interval& i) { return carl::abs(i); }); + m.def("pow", [](const Interval& i, carl::uint exp) { return carl::pow(i, exp); }); + m.def("floor", [](const Interval& i) { return carl::floor(i); }); + m.def("ceil", [](const Interval& i) { return carl::ceil(i); }); } diff --git a/src/pycarl/typed_core/polynomial.cpp b/src/pycarl/typed_core/polynomial.cpp index e6d26a2ed3..068c58485d 100644 --- a/src/pycarl/typed_core/polynomial.cpp +++ b/src/pycarl/typed_core/polynomial.cpp @@ -1,13 +1,10 @@ #include "polynomial.h" -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" - +#include "src/pycarl/types.h" void define_polynomial(py::module& m) { - - - py::class_(m, "Polynomial","Represent a multivariate polynomial") + py::class_(m, "Polynomial", "Represent a multivariate polynomial") .def(py::init()) .def(py::init()) .def(py::init()) @@ -51,47 +48,40 @@ void define_polynomial(py::module& m) { .def(py::self / Rational()) .def(PY_DIV, [](const Polynomial& lhs, const Integer& rhs) -> Polynomial { return lhs / Rational(rhs); }) - .def("__pow__", [](const Polynomial& var, carl::uint exp) {return var.pow(exp);}) + .def("__pow__", [](const Polynomial& var, carl::uint exp) { return var.pow(exp); }) - .def("__pos__", [](const Polynomial& var) {return Polynomial(var);}) - .def("__neg__", [](const Polynomial& var) {return var * Polynomial(-1);}) + .def("__pos__", [](const Polynomial& var) { return Polynomial(var); }) + .def("__neg__", [](const Polynomial& var) { return var * Polynomial(-1); }) .def("constant_part", [](const Polynomial& pol) -> Rational { return pol.constantPart(); }) .def("evaluate", &Polynomial::evaluate) - .def("substitute", [](const Polynomial& orig, std::map& substitutions) {return orig.substitute(substitutions);}) + .def("substitute", [](const Polynomial& orig, std::map& substitutions) { return orig.substitute(substitutions); }) .def("gather_variables", static_cast (Polynomial::*)() const>(&Polynomial::gatherVariables)) - .def_property_readonly("total_degree", &Polynomial::totalDegree)//, py::doc("The maximum degree of the terms in the polynomial")) - .def("degree", &Polynomial::degree)//, py::doc("Computes the degree with respect to the given variable")) + .def_property_readonly("total_degree", &Polynomial::totalDegree) //, py::doc("The maximum degree of the terms in the polynomial")) + .def("degree", &Polynomial::degree) //, py::doc("Computes the degree with respect to the given variable")) .def_property_readonly("nr_terms", &Polynomial::nrTerms) - .def("derive", [](Polynomial const& pol, carl::Variable const& var) { - return pol.derivative(var, 1); - }, "Compute the derivative", py::arg("variable")) + .def( + "derive", [](Polynomial const& pol, carl::Variable const& var) { return pol.derivative(var, 1); }, "Compute the derivative", py::arg("variable")) .def("__str__", [](const Polynomial& pol) { return pol.toString(); }) .def("__repr__", [](const Polynomial& pol) { return pol.toString(); }) - .def("to_smt2", [](Polynomial const& pol) { - return pol.toString(false, true); - }) + .def("to_smt2", [](Polynomial const& pol) { return pol.toString(false, true); }) .def(py::self != py::self) .def(py::self == py::self) .def(py::self != Rational()) .def(py::self == Rational()) - .def("__eq__", [](const Polynomial& lhs, const Integer& rhs) -> bool {return lhs == Rational(rhs);}) - .def("__ne__", [](const Polynomial& lhs, const Integer& rhs) -> bool {return lhs != Rational(rhs);}) + .def("__eq__", [](const Polynomial& lhs, const Integer& rhs) -> bool { return lhs == Rational(rhs); }) + .def("__ne__", [](const Polynomial& lhs, const Integer& rhs) -> bool { return lhs != Rational(rhs); }) .def("__len__", &Polynomial::size) - .def("__getitem__", [](const Polynomial& p, std::size_t index) { return *(p.begin()+index); }) - .def("__iter__", [](const Polynomial& p) { - return py::make_iterator(p.begin(), p.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def(py::pickle( - [](const Polynomial& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> Polynomial { - throw NoPickling(); - } - )) - .def("__hash__", [](const Polynomial& v) { std::hash h; return h(v);}) - ; + .def("__getitem__", [](const Polynomial& p, std::size_t index) { return *(p.begin() + index); }) + .def( + "__iter__", [](const Polynomial& p) { return py::make_iterator(p.begin(), p.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def(py::pickle([](const Polynomial& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> Polynomial { throw NoPickling(); })) + .def("__hash__", [](const Polynomial& v) { + std::hash h; + return h(v); + }); } diff --git a/src/pycarl/typed_core/rational.cpp b/src/pycarl/typed_core/rational.cpp index 6242f5985a..f592fc1416 100644 --- a/src/pycarl/typed_core/rational.cpp +++ b/src/pycarl/typed_core/rational.cpp @@ -5,23 +5,23 @@ #include "src/pycarl/helpers.h" #include "src/pycarl/types.h" -#include "carl/numbers/numbers.h" #include "carl/numbers/conversion/cln_gmp.h" +#include "carl/numbers/numbers.h" void define_cln_rational(py::module& m) { #ifdef PYCARL_USE_CLN py::class_(m, "Rational", "Class wrapping cln-rational numbers") .def(py::init([](double val) { return carl::rationalize(val); })) .def(py::init([](carl::sint val) { return carl::rationalize(val); })) - .def(py::init([](const cln::cl_I& numerator, const cln::cl_I& denominator) { return cln::cl_RA(numerator)/cln::cl_RA(denominator); })) + .def(py::init([](const cln::cl_I& numerator, const cln::cl_I& denominator) { return cln::cl_RA(numerator) / cln::cl_RA(denominator); })) .def(py::init([](const std::string& val) { - cln::cl_RA tmp; - bool suc = carl::try_parse(val, tmp); - if(!suc) { - throw std::invalid_argument("Cannot translate " + val + " into a rational."); - } - return tmp; - })) + cln::cl_RA tmp; + bool suc = carl::try_parse(val, tmp); + if (!suc) { + throw std::invalid_argument("Cannot translate " + val + " into a rational."); + } + return tmp; + })) .def(py::init(&carl::convert)) .def("__add__", [](const cln::cl_RA& lhs, const cln::cl_RA& rhs) -> cln::cl_RA { return lhs + rhs; }) @@ -31,35 +31,36 @@ void define_cln_rational(py::module& m) { .def("__radd__", [](const cln::cl_RA& rhs, carl::sint lhs) -> cln::cl_RA { return carl::rationalize(lhs) + rhs; }) .def("__radd__", [](const cln::cl_RA& rhs, carl::Variable::Arg lhs) -> Polynomial { return lhs + rhs; }) - .def("__sub__", [](const cln::cl_RA& lhs, const cln::cl_RA& rhs) -> cln::cl_RA { return lhs - rhs; }) .def("__sub__", [](const cln::cl_RA& lhs, carl::sint rhs) -> cln::cl_RA { return lhs - carl::rationalize(rhs); }) .def("__sub__", [](const cln::cl_RA& lhs, carl::Variable::Arg rhs) -> Polynomial { return lhs - rhs; }) .def("__rsub__", [](const cln::cl_RA& rhs, carl::sint lhs) -> cln::cl_RA { return carl::rationalize(lhs) - rhs; }) .def("__rsub__", [](const cln::cl_RA& rhs, carl::Variable::Arg lhs) -> Polynomial { return lhs - rhs; }) - .def("__mul__", [](const cln::cl_RA& lhs, const cln::cl_RA& rhs) -> cln::cl_RA { return lhs * rhs; }) .def("__mul__", [](const cln::cl_RA& lhs, carl::sint rhs) -> cln::cl_RA { return lhs * carl::rationalize(rhs); }) .def("__mul__", [](const cln::cl_RA& lhs, carl::Variable::Arg rhs) -> Term { return lhs * rhs; }) .def("__rmul__", [](const cln::cl_RA& rhs, carl::sint lhs) -> cln::cl_RA { return carl::rationalize(lhs) * rhs; }) .def("__rmul__", [](const cln::cl_RA& rhs, carl::Variable::Arg lhs) -> Term { return rhs * lhs; }) - .def(PY_DIV, [](const cln::cl_RA& lhs, const cln::cl_RA& rhs) -> cln::cl_RA { - if (carl::isZero(rhs)) - throw std::runtime_error("Div by zero"); - return lhs / rhs; - }) - .def(PY_DIV, [](const cln::cl_RA& lhs, carl::sint rhs) -> cln::cl_RA { - if (rhs == 0.0) - throw std::runtime_error("Div by zero"); - return lhs / carl::rationalize(rhs); - }) - .def(PY_RDIV, [](const cln::cl_RA& rhs, carl::sint lhs) -> cln::cl_RA { - if (carl::isZero(rhs)) - throw std::runtime_error("Div by zero"); - return carl::rationalize(lhs) / rhs; - }) + .def(PY_DIV, + [](const cln::cl_RA& lhs, const cln::cl_RA& rhs) -> cln::cl_RA { + if (carl::isZero(rhs)) + throw std::runtime_error("Div by zero"); + return lhs / rhs; + }) + .def(PY_DIV, + [](const cln::cl_RA& lhs, carl::sint rhs) -> cln::cl_RA { + if (rhs == 0.0) + throw std::runtime_error("Div by zero"); + return lhs / carl::rationalize(rhs); + }) + .def(PY_RDIV, + [](const cln::cl_RA& rhs, carl::sint lhs) -> cln::cl_RA { + if (carl::isZero(rhs)) + throw std::runtime_error("Div by zero"); + return carl::rationalize(lhs) / rhs; + }) .def(PY_DIV, [](const Rational& lhs, const RationalFunction& rhs) { return RationalFunction(lhs) / rhs; }) .def(PY_DIV, [](const Rational& lhs, const Polynomial& rhs) { return RationalFunction(lhs) / rhs; }) @@ -68,11 +69,10 @@ void define_cln_rational(py::module& m) { .def(PY_DIV, [](const Rational& lhs, carl::Variable::Arg rhs) { return RationalFunction(lhs) / rhs; }) .def(PY_RDIV, [](const Rational& rhs, carl::Variable::Arg lhs) { return RationalFunction(lhs) / rhs; }) - .def("__pow__", static_cast(&carl::pow)) - .def("__pos__", [](const cln::cl_RA& var) {return cln::cl_RA(var);}) - .def("__neg__", [](const cln::cl_RA& var) -> cln::cl_RA {return -var;}) - .def("__abs__", [](const cln::cl_RA& var) {return carl::abs(var);}) + .def("__pos__", [](const cln::cl_RA& var) { return cln::cl_RA(var); }) + .def("__neg__", [](const cln::cl_RA& var) -> cln::cl_RA { return -var; }) + .def("__abs__", [](const cln::cl_RA& var) { return carl::abs(var); }) .def(py::self > py::self) .def(py::self < py::self) @@ -98,40 +98,28 @@ void define_cln_rational(py::module& m) { .def(py::self >= int()) .def(py::self <= int()) - .def("is_one", [](const cln::cl_RA& r) { return carl::isOne(r); }) - .def("is_minus_one", [](const cln::cl_RA& r) {return carl::isOne(-r); }) + .def("is_minus_one", [](const cln::cl_RA& r) { return carl::isOne(-r); }) .def("__float__", static_cast(&carl::toDouble)) .def("__str__", &streamToString) - .def("__repr__", [](const cln::cl_RA& r) { return "(r) + ">"; }) - - .def_property_readonly("nominator", [](const cln::cl_RA& val) -> cln::cl_I { - return carl::getNum(val); - }) - .def_property_readonly("numerator", [](const cln::cl_RA& val) -> cln::cl_I { - return carl::getNum(val); - }) - .def_property_readonly("denominator", [](const cln::cl_RA& val) -> cln::cl_I { - return carl::getDenom(val); - }) + .def("__repr__", [](const cln::cl_RA& r) { return "(r) + ">"; }) + + .def_property_readonly("nominator", [](const cln::cl_RA& val) -> cln::cl_I { return carl::getNum(val); }) + .def_property_readonly("numerator", [](const cln::cl_RA& val) -> cln::cl_I { return carl::getNum(val); }) + .def_property_readonly("denominator", [](const cln::cl_RA& val) -> cln::cl_I { return carl::getDenom(val); }) .def(py::pickle( - [](const cln::cl_RA& val) { - return std::pair(carl::toString(carl::getNum(val)), carl::toString(carl::getDenom(val))); - }, - [](std::pair data) { - return carl::parse(data.first) / carl::parse(data.second); - } - )) - .def("__hash__", [](const cln::cl_RA& v) { std::hash h; return h(v);}) - ; - - py::implicitly_convertible(); + [](const cln::cl_RA& val) { return std::pair(carl::toString(carl::getNum(val)), carl::toString(carl::getDenom(val))); }, + [](std::pair data) { return carl::parse(data.first) / carl::parse(data.second); })) + .def("__hash__", [](const cln::cl_RA& v) { + std::hash h; + return h(v); + }); + + py::implicitly_convertible(); #endif } - - void define_gmp_rational(py::module& m) { #ifndef PYCARL_USE_CLN py::class_(m, "Rational", "Class wrapping gmp-rational numbers") @@ -139,13 +127,13 @@ void define_gmp_rational(py::module& m) { .def(py::init([](carl::sint val) { return carl::rationalize(val); })) .def(py::init()) .def(py::init([](const std::string& val) { - mpq_class tmp; - bool suc = carl::try_parse(val, tmp); - if(!suc) { - throw std::invalid_argument("Cannot translate " + val + " into a rational."); - } - return tmp; - })) + mpq_class tmp; + bool suc = carl::try_parse(val, tmp); + if (!suc) { + throw std::invalid_argument("Cannot translate " + val + " into a rational."); + } + return tmp; + })) #ifdef PYCARL_HAS_CLN .def(py::init(&carl::convert)) #endif @@ -155,7 +143,6 @@ void define_gmp_rational(py::module& m) { .def("__radd__", [](const mpq_class& rhs, carl::sint lhs) -> mpq_class { return carl::rationalize(lhs) + rhs; }) .def("__radd__", [](const mpq_class& rhs, carl::Variable::Arg lhs) -> Polynomial { return lhs + rhs; }) - .def("__sub__", [](const mpq_class& lhs, const mpq_class& rhs) -> mpq_class { return lhs - rhs; }) .def("__sub__", [](const mpq_class& lhs, carl::sint rhs) -> mpq_class { return lhs - carl::rationalize(rhs); }) .def("__sub__", [](const mpq_class& lhs, carl::Variable::Arg rhs) -> Polynomial { return lhs - rhs; }) @@ -168,21 +155,24 @@ void define_gmp_rational(py::module& m) { .def("__rmul__", [](const mpq_class& rhs, carl::sint lhs) -> mpq_class { return carl::rationalize(lhs) * rhs; }) .def("__rmul__", [](const mpq_class& rhs, carl::Variable::Arg lhs) -> Term { return rhs * lhs; }) - .def(PY_DIV, [](const mpq_class& lhs, const mpq_class& rhs) -> mpq_class { - if (carl::isZero(rhs)) - throw std::runtime_error("Div by zero"); - return lhs / rhs; - }) - .def(PY_DIV, [](const mpq_class& lhs, carl::sint rhs) -> mpq_class { - if (rhs == 0.0) - throw std::runtime_error("Div by zero"); - return lhs / carl::rationalize(rhs); - }) - .def(PY_RDIV, [](const mpq_class& rhs, carl::sint lhs) -> mpq_class { - if (carl::isZero(rhs)) - throw std::runtime_error("Div by zero"); - return carl::rationalize(lhs) / rhs; - }) + .def(PY_DIV, + [](const mpq_class& lhs, const mpq_class& rhs) -> mpq_class { + if (carl::isZero(rhs)) + throw std::runtime_error("Div by zero"); + return lhs / rhs; + }) + .def(PY_DIV, + [](const mpq_class& lhs, carl::sint rhs) -> mpq_class { + if (rhs == 0.0) + throw std::runtime_error("Div by zero"); + return lhs / carl::rationalize(rhs); + }) + .def(PY_RDIV, + [](const mpq_class& rhs, carl::sint lhs) -> mpq_class { + if (carl::isZero(rhs)) + throw std::runtime_error("Div by zero"); + return carl::rationalize(lhs) / rhs; + }) .def(PY_DIV, [](const Rational& lhs, const RationalFunction& rhs) { return RationalFunction(lhs) / rhs; }) .def(PY_DIV, [](const Rational& lhs, const Polynomial& rhs) { return RationalFunction(lhs) / rhs; }) @@ -192,9 +182,9 @@ void define_gmp_rational(py::module& m) { .def(PY_RDIV, [](const Rational& rhs, carl::Variable::Arg lhs) { return RationalFunction(lhs) / rhs; }) .def("__pow__", static_cast(&carl::pow)) - .def("__pos__", [](const mpq_class& var) {return mpq_class(var);}) - .def("__neg__", [](const mpq_class& var) -> mpq_class {return -var;}) - .def("__abs__", [](const mpq_class& var) {return carl::abs(var);}) + .def("__pos__", [](const mpq_class& var) { return mpq_class(var); }) + .def("__neg__", [](const mpq_class& var) -> mpq_class { return -var; }) + .def("__abs__", [](const mpq_class& var) { return carl::abs(var); }) .def(py::self > py::self) .def(py::self < py::self) @@ -220,32 +210,21 @@ void define_gmp_rational(py::module& m) { .def(py::self >= int()) .def(py::self <= int()) - .def("__float__", static_cast(&carl::toDouble)) .def("__str__", &streamToString) .def("__repr__", [](const mpq_class& r) { return "(r) + ">"; }) - - .def_property_readonly("nominator", [](const mpq_class& val) -> mpz_class { - return carl::getNum(val); - }) - .def_property_readonly("numerator", [](const mpq_class& val) -> mpz_class { - return carl::getNum(val); - }) - .def_property_readonly("denominator", [](const mpq_class& val) -> mpz_class { - return carl::getDenom(val); - }) + .def_property_readonly("nominator", [](const mpq_class& val) -> mpz_class { return carl::getNum(val); }) + .def_property_readonly("numerator", [](const mpq_class& val) -> mpz_class { return carl::getNum(val); }) + .def_property_readonly("denominator", [](const mpq_class& val) -> mpz_class { return carl::getDenom(val); }) .def(py::pickle( - [](const mpq_class& val) { - return std::pair(carl::toString(carl::getNum(val)), carl::toString(carl::getDenom(val))); - }, - [](std::pair data) { - return carl::parse(data.first) / carl::parse(data.second); - } - )) - .def("__hash__", [](const mpq_class& v) { std::hash h; return h(v);}) - ; + [](const mpq_class& val) { return std::pair(carl::toString(carl::getNum(val)), carl::toString(carl::getDenom(val))); }, + [](std::pair data) { return carl::parse(data.first) / carl::parse(data.second); })) + .def("__hash__", [](const mpq_class& v) { + std::hash h; + return h(v); + }); py::implicitly_convertible(); #endif diff --git a/src/pycarl/typed_core/rationalfunction.cpp b/src/pycarl/typed_core/rationalfunction.cpp index e0bcb49d8d..80587dc263 100644 --- a/src/pycarl/typed_core/rationalfunction.cpp +++ b/src/pycarl/typed_core/rationalfunction.cpp @@ -1,10 +1,7 @@ #include "rationalfunction.h" - -#include "src/pycarl/types.h" #include "src/pycarl/helpers.h" - - +#include "src/pycarl/types.h" void define_rationalfunction(py::module& m) { py::class_(m, "RationalFunction", "Represent a rational function, that is the fraction of two multivariate polynomials ") @@ -12,31 +9,31 @@ void define_rationalfunction(py::module& m) { .def(py::init()) .def(py::init()) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) .def(py::self + py::self) - .def("__radd__", [](const RationalFunction& rhs, const Polynomial& lhs) -> RationalFunction {return rhs + lhs;}) - .def("__radd__", [](const RationalFunction& rhs, const Term& lhs) -> RationalFunction {return rhs + lhs;}) - .def("__radd__", [](const RationalFunction& rhs, const Monomial::Arg& lhs) -> RationalFunction {return rhs + lhs;}) - .def("__radd__", [](const RationalFunction& rhs, carl::Variable::Arg lhs) -> RationalFunction {return rhs + lhs;}) - .def("__radd__", [](const RationalFunction& rhs, const Rational& lhs) -> RationalFunction {return rhs + lhs;}) + .def("__radd__", [](const RationalFunction& rhs, const Polynomial& lhs) -> RationalFunction { return rhs + lhs; }) + .def("__radd__", [](const RationalFunction& rhs, const Term& lhs) -> RationalFunction { return rhs + lhs; }) + .def("__radd__", [](const RationalFunction& rhs, const Monomial::Arg& lhs) -> RationalFunction { return rhs + lhs; }) + .def("__radd__", [](const RationalFunction& rhs, carl::Variable::Arg lhs) -> RationalFunction { return rhs + lhs; }) + .def("__radd__", [](const RationalFunction& rhs, const Rational& lhs) -> RationalFunction { return rhs + lhs; }) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) .def(py::self - py::self) - .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) .def("__rmul__", [](const RationalFunction& rhs, const Polynomial& lhs) -> RationalFunction { return rhs * lhs; }) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) .def(py::self * py::self) .def(PY_DIV, static_cast(&carl::operator/)) @@ -46,40 +43,34 @@ void define_rationalfunction(py::module& m) { .def(PY_DIV, static_cast(&carl::operator/)) .def(py::self / py::self) - .def("__pow__", [](const RationalFunction& var, carl::uint exp) {return carl::pow(var, exp);}) + .def("__pow__", [](const RationalFunction& var, carl::uint exp) { return carl::pow(var, exp); }) - .def("__pos__", [](const RationalFunction& var) {return RationalFunction(var);}) - .def("__neg__", [](const RationalFunction& var) {return var * RationalFunction(-1);}) + .def("__pos__", [](const RationalFunction& var) { return RationalFunction(var); }) + .def("__neg__", [](const RationalFunction& var) { return var * RationalFunction(-1); }) .def("evaluate", &RationalFunction::evaluate) .def("gather_variables", static_cast (RationalFunction::*)() const>(&RationalFunction::gatherVariables)) .def_property_readonly("nominator", &RationalFunction::nominator) .def_property_readonly("numerator", &RationalFunction::nominator) .def_property_readonly("denominator", &RationalFunction::denominator) - .def("derive", [](RationalFunction const& ratFunc, carl::Variable const& var) { - return ratFunc.derivative(var, 1); - }, "Compute the derivative", py::arg("variable")) + .def( + "derive", [](RationalFunction const& ratFunc, carl::Variable const& var) { return ratFunc.derivative(var, 1); }, "Compute the derivative", + py::arg("variable")) .def("is_constant", &RationalFunction::isConstant) .def("constant_part", &RationalFunction::constantPart) .def("__str__", &streamToString) - .def("to_smt2", [](RationalFunction const& rf) { - return rf.toString(false, true); - }) + .def("to_smt2", [](RationalFunction const& rf) { return rf.toString(false, true); }) .def(py::self == py::self) .def(py::self != py::self) - .def("__eq__", [](const RationalFunction& lhs, const Polynomial& rhs) -> bool {return lhs == RationalFunction(rhs);}) - .def("__ne__", [](const RationalFunction& lhs, const Polynomial& rhs) -> bool {return lhs != RationalFunction(rhs);}) + .def("__eq__", [](const RationalFunction& lhs, const Polynomial& rhs) -> bool { return lhs == RationalFunction(rhs); }) + .def("__ne__", [](const RationalFunction& lhs, const Polynomial& rhs) -> bool { return lhs != RationalFunction(rhs); }) - .def(py::pickle( - [](const RationalFunction& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> RationalFunction { - throw NoPickling(); - } - )) - .def("__hash__", [](const RationalFunction& v) { std::hash h; return h(v);}) - ; + .def(py::pickle([](const RationalFunction& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> RationalFunction { throw NoPickling(); })) + .def("__hash__", [](const RationalFunction& v) { + std::hash h; + return h(v); + }); } diff --git a/src/pycarl/typed_core/term.cpp b/src/pycarl/typed_core/term.cpp index 1c7852d306..b4cfaffaba 100644 --- a/src/pycarl/typed_core/term.cpp +++ b/src/pycarl/typed_core/term.cpp @@ -3,30 +3,29 @@ #include "src/pycarl/helpers.h" #include "src/pycarl/types.h" - void define_term(py::module& m) { py::class_(m, "Term") .def(py::init()) .def(py::init()) .def(py::init()) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) - .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) + .def("__add__", static_cast(&carl::operator+)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) - .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) + .def("__sub__", static_cast(&carl::operator-)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) - .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) + .def("__mul__", static_cast(&carl::operator*)) .def(PY_DIV, [](const Term& lhs, const RationalFunction& rhs) { return RationalFunction(Polynomial(lhs)) / rhs; }) .def(PY_DIV, [](const Term& lhs, const Polynomial& rhs) { return RationalFunction(Polynomial(lhs)) / rhs; }) @@ -35,30 +34,26 @@ void define_term(py::module& m) { .def(PY_DIV, [](const Term& lhs, carl::Variable::Arg rhs) { return RationalFunction(Polynomial(lhs)) / rhs; }) .def(py::self / Rational()) - .def("__pow__", [](const Term& var, carl::uint exp) {return var.pow(exp);}) + .def("__pow__", [](const Term& var, carl::uint exp) { return var.pow(exp); }) - .def("__pos__", [](const Term& var) {return Term(var);}) - .def("__neg__", [](const Term& var) {return var * Term(-1);}) + .def("__pos__", [](const Term& var) { return Term(var); }) + .def("__neg__", [](const Term& var) { return var * Term(-1); }) .def(py::self != py::self) .def(py::self == py::self) - .def("is_constant", [](const Term& arg) {return arg.isConstant();}) - .def("is_one", [](const Term& arg) {return arg.isOne();}) - .def_property_readonly("tdeg", [](const Term& arg) { return arg.tdeg();} ) + .def("is_constant", [](const Term& arg) { return arg.isConstant(); }) + .def("is_one", [](const Term& arg) { return arg.isOne(); }) + .def_property_readonly("tdeg", [](const Term& arg) { return arg.tdeg(); }) - .def_property_readonly("coeff", [] (const Term& arg) { return arg.coeff(); }) + .def_property_readonly("coeff", [](const Term& arg) { return arg.coeff(); }) .def_property_readonly("monomial", [](const Term& arg) { return arg.monomial(); }) .def("__str__", &streamToString) - .def(py::pickle( - [](const Term& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> Term { - throw NoPickling(); - } - )) - .def("__hash__", [](const Term& v) { std::hash h; return h(v);}) - ; + .def(py::pickle([](const Term& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> Term { throw NoPickling(); })) + .def("__hash__", [](const Term& v) { + std::hash h; + return h(v); + }); } diff --git a/src/pycarl/typed_formula/common.h b/src/pycarl/typed_formula/common.h index 4367a62b39..44637ec2be 100644 --- a/src/pycarl/typed_formula/common.h +++ b/src/pycarl/typed_formula/common.h @@ -2,5 +2,5 @@ #include "types.h" -//toString +// toString #include "src/pycarl/helpers.h" diff --git a/src/pycarl/typed_formula/constraint.cpp b/src/pycarl/typed_formula/constraint.cpp index c6c2fe049c..3d5fd29933 100644 --- a/src/pycarl/typed_formula/constraint.cpp +++ b/src/pycarl/typed_formula/constraint.cpp @@ -2,7 +2,6 @@ #include "common.h" - // void define_constraint(py::module& m) { py::class_(m, "Constraint") @@ -10,45 +9,23 @@ void define_constraint(py::module& m) { .def(py::init(), py::arg("var"), py::arg("rel"), py::arg("bound")) .def(py::init()) .def("__str__", &streamToString) - .def("to_smt2", [](Constraint const& c) { - return c.toString(2, false, true); - }) + .def("to_smt2", [](Constraint const& c) { return c.toString(2, false, true); }) - .def("__invert__", [](const Constraint& lhs){ - return Formula(carl::FormulaType::NOT, Formula(lhs)); - }) - .def("__and__", [](const Constraint& lhs, const Constraint& rhs){ - return Formula(carl::FormulaType::AND, {Formula(lhs), Formula(rhs)}); - }) - .def("__and__", [](const Constraint& lhs, const Formula& rhs){ - return Formula(carl::FormulaType::AND, {Formula(lhs), rhs}); - }) - .def("__or__", [](const Constraint& lhs, const Constraint& rhs){ - return Formula(carl::FormulaType::OR, {Formula(lhs), Formula(lhs)}); - }) - .def("__or__", [](const Constraint& lhs, const Formula& rhs){ - return Formula(carl::FormulaType::OR, {Formula(lhs), rhs}); - }) - .def("__xor__", [](const Constraint& lhs, const Constraint& rhs){ - return Formula(carl::FormulaType::XOR, {Formula(lhs), Formula(rhs)}); - }) - .def("__xor__", [](const Constraint& lhs, const Formula& rhs){ - return Formula(carl::FormulaType::XOR, {Formula(lhs), rhs}); - }) + .def("__invert__", [](const Constraint& lhs) { return Formula(carl::FormulaType::NOT, Formula(lhs)); }) + .def("__and__", [](const Constraint& lhs, const Constraint& rhs) { return Formula(carl::FormulaType::AND, {Formula(lhs), Formula(rhs)}); }) + .def("__and__", [](const Constraint& lhs, const Formula& rhs) { return Formula(carl::FormulaType::AND, {Formula(lhs), rhs}); }) + .def("__or__", [](const Constraint& lhs, const Constraint& rhs) { return Formula(carl::FormulaType::OR, {Formula(lhs), Formula(lhs)}); }) + .def("__or__", [](const Constraint& lhs, const Formula& rhs) { return Formula(carl::FormulaType::OR, {Formula(lhs), rhs}); }) + .def("__xor__", [](const Constraint& lhs, const Constraint& rhs) { return Formula(carl::FormulaType::XOR, {Formula(lhs), Formula(rhs)}); }) + .def("__xor__", [](const Constraint& lhs, const Formula& rhs) { return Formula(carl::FormulaType::XOR, {Formula(lhs), rhs}); }) - //.def("satisfied_by", [](const Constraint& constraint, const carl::EvaluationMap& evaluation) { return Formula(constraint).satisfiedBy(evaluation); }) + //.def("satisfied_by", [](const Constraint& constraint, const carl::EvaluationMap& evaluation) { return + // Formula(constraint).satisfiedBy(evaluation); }) .def_property_readonly("relation", &Constraint::relation) .def_property_readonly("lhs", &Constraint::lhs) - .def(py::pickle( - [](const Constraint& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> Constraint { - throw NoPickling(); - } - )) - ; + .def(py::pickle([](const Constraint& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> Constraint { throw NoPickling(); })); } // void define_simple_constraint(py::module& m) { @@ -59,16 +36,9 @@ void define_simple_constraint(py::module& m) { .def("lhs", &SimpleConstraint::lhs, "Get the left hand side of the constraint") .def("rel", &SimpleConstraint::rel, "Get the relation of the constraint") - .def(py::pickle( - [](const SimpleConstraint& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> SimpleConstraint { - throw NoPickling(); - } - )) - ; - + .def(py::pickle([](const SimpleConstraint& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> SimpleConstraint { throw NoPickling(); })); + py::class_(m, "SimpleConstraintRatFunc") .def(py::init()) .def(py::init()) @@ -77,13 +47,6 @@ void define_simple_constraint(py::module& m) { .def("lhs", &SimpleConstraintRatFunc::lhs, "Get the left hand side of the constraint") .def("rel", &SimpleConstraintRatFunc::rel, "Get the relation of the constraint") - .def(py::pickle( - [](const SimpleConstraintRatFunc& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> SimpleConstraintRatFunc { - throw NoPickling(); - } - )) - ; + .def(py::pickle([](const SimpleConstraintRatFunc& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> SimpleConstraintRatFunc { throw NoPickling(); })); } diff --git a/src/pycarl/typed_formula/formula.cpp b/src/pycarl/typed_formula/formula.cpp index 18c1a7e5df..84623c0722 100644 --- a/src/pycarl/typed_formula/formula.cpp +++ b/src/pycarl/typed_formula/formula.cpp @@ -2,49 +2,30 @@ #include "common.h" - void define_formula(py::module& m) { py::class_(m, "Formula") .def(py::init(), "Create Formula given Boolean variable") .def(py::init()) .def(py::init()) .def(py::init>()) - .def(py::init([](bool b) { - return b ? Formula(carl::FormulaType::TRUE) : Formula(carl::FormulaType::FALSE); - })) + .def(py::init([](bool b) { return b ? Formula(carl::FormulaType::TRUE) : Formula(carl::FormulaType::FALSE); })) .def("__str__", &streamToString>) - .def("to_smt2", [](Formula const& f) { - return f.toString(false, 2); - }) + .def("to_smt2", [](Formula const& f) { return f.toString(false, 2); }) - .def("__invert__", [](const Formula& lhs){ - return lhs.negated(); - }) - .def("__and__", [](const Formula& lhs, const Constraint& rhs){ - return Formula(carl::FormulaType::AND, {lhs, Formula(rhs)}); - }) - .def("__and__", [](const Formula& lhs, const Formula& rhs){ - return Formula(carl::FormulaType::AND, {lhs, rhs}); - }) - .def("__or__", [](const Formula& lhs, const Constraint& rhs){ - return Formula(carl::FormulaType::OR, {lhs, Formula(rhs)}); - }) - .def("__or__", [](const Formula& lhs, const Formula& rhs){ - return Formula(carl::FormulaType::OR, {lhs, rhs}); - }) - .def("__xor__", [](const Formula& lhs, const Constraint& rhs){ - return Formula(carl::FormulaType::XOR, {lhs, Formula(rhs)}); - }) - .def("__xor__", [](const Formula& lhs, const Formula& rhs){ - return Formula(carl::FormulaType::XOR, {lhs, rhs}); - }) + .def("__invert__", [](const Formula& lhs) { return lhs.negated(); }) + .def("__and__", [](const Formula& lhs, const Constraint& rhs) { return Formula(carl::FormulaType::AND, {lhs, Formula(rhs)}); }) + .def("__and__", [](const Formula& lhs, const Formula& rhs) { return Formula(carl::FormulaType::AND, {lhs, rhs}); }) + .def("__or__", [](const Formula& lhs, const Constraint& rhs) { return Formula(carl::FormulaType::OR, {lhs, Formula(rhs)}); }) + .def("__or__", [](const Formula& lhs, const Formula& rhs) { return Formula(carl::FormulaType::OR, {lhs, rhs}); }) + .def("__xor__", [](const Formula& lhs, const Constraint& rhs) { return Formula(carl::FormulaType::XOR, {lhs, Formula(rhs)}); }) + .def("__xor__", [](const Formula& lhs, const Formula& rhs) { return Formula(carl::FormulaType::XOR, {lhs, rhs}); }) //.def("satisfied_by", &Formula::satisfiedBy) .def("__len__", &Formula::size) - .def("__iter__", [](const Formula& f) { - return py::make_iterator(f.begin(), f.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def( + "__iter__", [](const Formula& f) { return py::make_iterator(f.begin(), f.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) .def_property_readonly("type", &Formula::getType) @@ -57,13 +38,6 @@ void define_formula(py::module& m) { .def("get_subformulas", &Formula::subformulas, "Get list of subformulas for n-ary formula") .def("get_constraint", &Formula::constraint, "Get constraint of constraint formula") - .def(py::pickle( - [](const Formula& val) -> std::tuple { - throw NoPickling(); - }, - [](const std::tuple& data) -> Formula { - throw NoPickling(); - } - )) - ; + .def(py::pickle([](const Formula& val) -> std::tuple { throw NoPickling(); }, + [](const std::tuple& data) -> Formula { throw NoPickling(); })); } diff --git a/src/pycarl/typed_formula/types.h b/src/pycarl/typed_formula/types.h index 816de2bc45..8d3b53b4ca 100644 --- a/src/pycarl/typed_formula/types.h +++ b/src/pycarl/typed_formula/types.h @@ -2,12 +2,11 @@ #include "src/pycarl/types.h" -#include #include +#include #include typedef carl::Constraint Constraint; typedef carl::SimpleConstraint SimpleConstraint; typedef carl::SimpleConstraint SimpleConstraintRatFunc; typedef carl::Formula Formula; - diff --git a/src/pycarl/typed_parse/parser.h b/src/pycarl/typed_parse/parser.h index 71ec555041..c928963bdb 100644 --- a/src/pycarl/typed_parse/parser.h +++ b/src/pycarl/typed_parse/parser.h @@ -1,10 +1,10 @@ #pragma once +#include +#include +#include #include "src/pycarl/common.h" #include "src/pycarl/types.h" -#include -#include -#include template struct ParserResultWrapper { diff --git a/src/pycarl/types.h b/src/pycarl/types.h index a56514a75a..ea61cf6225 100644 --- a/src/pycarl/types.h +++ b/src/pycarl/types.h @@ -2,12 +2,12 @@ #include "pycarl/definitions.h" +#include #include -#include #include #include -#include #include +#include #include #ifdef PYCARL_USE_CLN diff --git a/src/pycarl/types/cln_types.h b/src/pycarl/types/cln_types.h index a3dedeebb4..00a8f0b4c0 100644 --- a/src/pycarl/types/cln_types.h +++ b/src/pycarl/types/cln_types.h @@ -1,9 +1,7 @@ #pragma once -#include "pycarl/definitions.h" #include - +#include "pycarl/definitions.h" typedef cln::cl_RA Rational; typedef cln::cl_I Integer; - diff --git a/src/pycarl/types/gmp_types.h b/src/pycarl/types/gmp_types.h index 4042f7787c..75f333f83c 100644 --- a/src/pycarl/types/gmp_types.h +++ b/src/pycarl/types/gmp_types.h @@ -1,6 +1,5 @@ #pragma once #include - typedef mpq_class Rational; typedef mpz_class Integer; \ No newline at end of file diff --git a/src/storage/bitvector.cpp b/src/storage/bitvector.cpp index fa53f88c7a..a5db5d02f0 100644 --- a/src/storage/bitvector.cpp +++ b/src/storage/bitvector.cpp @@ -1,6 +1,6 @@ #include "bitvector.h" -#include "storm/storage/BitVector.h" #include "src/helpers.h" +#include "storm/storage/BitVector.h" void define_bitvector(py::module& m) { using BitVector = storm::storage::BitVector; @@ -14,27 +14,32 @@ void define_bitvector(py::module& m) { .def("size", &BitVector::size) .def("number_of_set_bits", &BitVector::getNumberOfSetBits) - //.def("get", &BitVector::get, "index"_a) // no idea why this does not work - .def("get", [](BitVector const& b, uint_fast64_t i) { - return b.get(i); - }, "index"_a) - .def("set", [](BitVector& b, uint_fast64_t i, bool v) { - b.set(i, v); - }, py::arg("index"), py::arg("value") = true, "Set") + //.def("get", &BitVector::get, "index"_a) // no idea why this does not work + .def( + "get", [](BitVector const& b, uint_fast64_t i) { return b.get(i); }, "index"_a) + .def( + "set", [](BitVector& b, uint_fast64_t i, bool v) { b.set(i, v); }, py::arg("index"), py::arg("value") = true, "Set") .def("as_int", &BitVector::getAsInt, py::arg("index"), py::arg("no_bits"), "Get as unsigned int") .def("__len__", [](BitVector const& b) { return b.size(); }) - .def("__getitem__", [](BitVector const& b, uint_fast64_t i) { - if (i >= b.size()) - throw py::index_error(); - return b.get(i); - }) + .def("__getitem__", + [](BitVector const& b, uint_fast64_t i) { + if (i >= b.size()) + throw py::index_error(); + return b.get(i); + }) .def("__setitem__", [](BitVector& b, uint_fast64_t i, bool v) { b.set(i, v); }) - .def("__iter__", [](const BitVector &b) { return py::make_iterator(b.begin(), b.end()); }, - py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def( + "__iter__", [](const BitVector& b) { return py::make_iterator(b.begin(), b.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - .def("store_as_string", [](const BitVector& bv) {std::stringstream strs; bv.store(strs); return strs.str();}) + .def("store_as_string", + [](const BitVector& bv) { + std::stringstream strs; + bv.store(strs); + return strs.str(); + }) .def_static("load_from_string", &BitVector::load, py::arg("description")) .def(py::self == py::self) .def(py::self != py::self) @@ -50,9 +55,5 @@ void define_bitvector(py::module& m) { .def(py::self |= py::self) .def("__str__", &streamToString) - .def("__hash__", [](const BitVector &b) { - return storm::storage::Murmur3BitVectorHash()(b); - }) - ; - + .def("__hash__", [](const BitVector& b) { return storm::storage::Murmur3BitVectorHash()(b); }); } diff --git a/src/storage/choiceorigins.cpp b/src/storage/choiceorigins.cpp index 1bc501296c..ae8a384d2a 100644 --- a/src/storage/choiceorigins.cpp +++ b/src/storage/choiceorigins.cpp @@ -1,36 +1,41 @@ #include "choiceorigins.h" #include "storm/adapters/JsonAdapter.h" +#include "storm/storage/jani/Model.h" #include "storm/storage/sparse/JaniChoiceOrigins.h" #include "storm/storage/sparse/PrismChoiceOrigins.h" -#include "storm/storage/jani/Model.h" using ChoiceOrigins = storm::storage::sparse::ChoiceOrigins; using JaniChoiceOrigins = storm::storage::sparse::JaniChoiceOrigins; using PrismChoiceOrigins = storm::storage::sparse::PrismChoiceOrigins; void define_origins(py::module& m) { - - py::class_> co(m, "ChoiceOrigins", "This class represents the origin of choices of a model in terms of the input model spec."); + py::class_> co(m, "ChoiceOrigins", + "This class represents the origin of choices of a model in terms of the input model spec."); co.def("is_prism_choice_origins", &ChoiceOrigins::isPrismChoiceOrigins) - .def("is_jani_choice_origins", &ChoiceOrigins::isJaniChoiceOrigins) - .def("as_prism_choice_origins", [](ChoiceOrigins &co) -> PrismChoiceOrigins& { return co.asPrismChoiceOrigins(); }) - .def("as_jani_choice_origins", [](ChoiceOrigins &co) -> JaniChoiceOrigins& { return co.asJaniChoiceOrigins(); }) - .def("get_identifier_info", &ChoiceOrigins::getIdentifierInfo, "identifier"_a, "human readable string") - .def("get_choice_info", &ChoiceOrigins::getChoiceInfo, "identifier"_a, "human readable string") - .def("get_number_of_identifiers", &ChoiceOrigins::getNumberOfIdentifiers, "the number of considered identifier") - ; - - - py::class_>(m, "JaniChoiceOrigins", "This class represents for each choice the origin in the jani spec.", co) - .def(py::initconst&, std::vector const&, std::vector const&>(), "jani_model"_a, "index_to_identifier_mapping"_a, "identifier_to_edge_index__set_mapping"_a) - .def_property_readonly("model", &JaniChoiceOrigins::getModel, "retrieves the associated JANI model") - .def("get_edge_index_set", [](JaniChoiceOrigins const& co, uint64_t choice) -> auto& { return co.getEdgeIndexSet(choice); }, "returns the set of edges that induced the choice", py::arg("choice_index")) - ; + .def("is_jani_choice_origins", &ChoiceOrigins::isJaniChoiceOrigins) + .def("as_prism_choice_origins", [](ChoiceOrigins& co) -> PrismChoiceOrigins& { return co.asPrismChoiceOrigins(); }) + .def("as_jani_choice_origins", [](ChoiceOrigins& co) -> JaniChoiceOrigins& { return co.asJaniChoiceOrigins(); }) + .def("get_identifier_info", &ChoiceOrigins::getIdentifierInfo, "identifier"_a, "human readable string") + .def("get_choice_info", &ChoiceOrigins::getChoiceInfo, "identifier"_a, "human readable string") + .def("get_number_of_identifiers", &ChoiceOrigins::getNumberOfIdentifiers, "the number of considered identifier"); - py::class_>(m, "PrismChoiceOrigins", "This class represents for each choice the set of prism commands that induced the choice.", co) - .def(py::initconst&, std::vector const&, std::vector const&>(), "prism_program"_a, "index_to_identifier_mapping"_a, "identifier_to_command_set_mapping"_a) - .def_property_readonly("program", &PrismChoiceOrigins::getProgram, "retrieves the associated Prism program") - .def("get_command_set", [](PrismChoiceOrigins const& co, uint64_t choice) -> auto& { return co.getCommandSet(choice); }, "Returns the set of prism commands that induced the choice", py::arg("choice_index")) - ; + py::class_>(m, "JaniChoiceOrigins", + "This class represents for each choice the origin in the jani spec.", co) + .def(py::init const&, std::vector const&, + std::vector const&>(), + "jani_model"_a, "index_to_identifier_mapping"_a, "identifier_to_edge_index__set_mapping"_a) + .def_property_readonly("model", &JaniChoiceOrigins::getModel, "retrieves the associated JANI model") + .def( + "get_edge_index_set", [](JaniChoiceOrigins const& co, uint64_t choice) -> auto& { return co.getEdgeIndexSet(choice); }, + "returns the set of edges that induced the choice", py::arg("choice_index")); + py::class_>( + m, "PrismChoiceOrigins", "This class represents for each choice the set of prism commands that induced the choice.", co) + .def(py::init const&, std::vector const&, + std::vector const&>(), + "prism_program"_a, "index_to_identifier_mapping"_a, "identifier_to_command_set_mapping"_a) + .def_property_readonly("program", &PrismChoiceOrigins::getProgram, "retrieves the associated Prism program") + .def( + "get_command_set", [](PrismChoiceOrigins const& co, uint64_t choice) -> auto& { return co.getCommandSet(choice); }, + "Returns the set of prism commands that induced the choice", py::arg("choice_index")); } \ No newline at end of file diff --git a/src/storage/choiceorigins.h b/src/storage/choiceorigins.h index 5082bb95ee..9ed381ea5b 100644 --- a/src/storage/choiceorigins.h +++ b/src/storage/choiceorigins.h @@ -2,5 +2,4 @@ #include "common.h" - void define_origins(py::module& m); \ No newline at end of file diff --git a/src/storage/dd.cpp b/src/storage/dd.cpp index dffd9aa790..7837ce2423 100644 --- a/src/storage/dd.cpp +++ b/src/storage/dd.cpp @@ -1,49 +1,47 @@ #include "dd.h" +#include "src/helpers.h" +#include "storm/storage/dd/Add.h" +#include "storm/storage/dd/Bdd.h" +#include "storm/storage/dd/Dd.h" #include "storm/storage/dd/DdManager.h" #include "storm/storage/dd/DdMetaVariable.h" -#include "storm/storage/dd/Dd.h" -#include "storm/storage/dd/Bdd.h" -#include "storm/storage/dd/Add.h" -#include "src/helpers.h" template void define_dd(py::module& m, std::string const& libstring) { py::class_> ddMetaVariable(m, (std::string("DdMetaVariable_") + libstring).c_str()); - ddMetaVariable.def("compute_indices", &storm::dd::DdMetaVariable::getIndices, py::arg("sorted")=true); + ddMetaVariable.def("compute_indices", &storm::dd::DdMetaVariable::getIndices, py::arg("sorted") = true); ddMetaVariable.def_property_readonly("name", &storm::dd::DdMetaVariable::getName); ddMetaVariable.def_property_readonly("lowest_value", &storm::dd::DdMetaVariable::getLow); ddMetaVariable.def_property_readonly("type", &storm::dd::DdMetaVariable::getType); ddMetaVariable.def("__str__", &storm::dd::DdMetaVariable::getName); py::class_, std::shared_ptr>> ddManager(m, (std::string("DdManager_") + libstring).c_str()); - ddManager.def("get_meta_variable", [](storm::dd::DdManager const& manager, storm::expressions::Variable const& var) {return manager.getMetaVariable(var);}, py::arg("expression_variable")); + ddManager.def( + "get_meta_variable", [](storm::dd::DdManager const& manager, storm::expressions::Variable const& var) { return manager.getMetaVariable(var); }, + py::arg("expression_variable")); py::class_> dd(m, (std::string("Dd_") + libstring).c_str(), "Dd"); dd.def_property_readonly("node_count", &storm::dd::Dd::getNodeCount, "get node count"); dd.def_property_readonly("dd_manager", &storm::dd::Dd::getDdManager, "get the manager"); - dd.def_property_readonly("meta_variables", [](storm::dd::Dd const& dd) {return dd.getContainedMetaVariables();}, "the contained meta variables"); - - + dd.def_property_readonly("meta_variables", [](storm::dd::Dd const& dd) { return dd.getContainedMetaVariables(); }, "the contained meta variables"); py::class_> bdd(m, (std::string("Bdd_") + libstring).c_str(), "Bdd", dd); bdd.def("to_expression", &storm::dd::Bdd::toExpression, py::arg("expression_manager")); py::class_> add(m, (std::string("Add_") + libstring + "_Double").c_str(), "Add", dd); - add.def("__iter__", [](const storm::dd::Add &s) { return py::make_iterator(s.begin(), s.end()); }, - py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */); + add.def( + "__iter__", [](const storm::dd::Add& s) { return py::make_iterator(s.begin(), s.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */); py::class_> addIterator(m, (std::string("AddIterator_") + libstring + "_Double").c_str(), "AddIterator"); - addIterator.def("get", [](const storm::dd::AddIterator &it) { return *it; } ); - + addIterator.def("get", [](const storm::dd::AddIterator& it) { return *it; }); } - void define_dd_nt(py::module& m) { py::enum_(m, "DdMetaVariableType") - .value("Int", storm::dd::MetaVariableType::Int) - .value("Bool", storm::dd::MetaVariableType::Bool) - .value("Bitvector", storm::dd::MetaVariableType::BitVector); - + .value("Int", storm::dd::MetaVariableType::Int) + .value("Bool", storm::dd::MetaVariableType::Bool) + .value("Bitvector", storm::dd::MetaVariableType::BitVector); } template void define_dd(py::module& m, std::string const& libstring); \ No newline at end of file diff --git a/src/storage/decomposition.cpp b/src/storage/decomposition.cpp index 08db02b9fb..a2e6bc9660 100644 --- a/src/storage/decomposition.cpp +++ b/src/storage/decomposition.cpp @@ -4,37 +4,30 @@ #include "storm/storage/MaximalEndComponent.h" #include "storm/storage/MaximalEndComponentDecomposition.h" - using MEC = storm::storage::MaximalEndComponent; -template using MECDecomposition = storm::storage::MaximalEndComponentDecomposition; - +template +using MECDecomposition = storm::storage::MaximalEndComponentDecomposition; void define_maximal_end_components(py::module& m) { - py::class_>(m, "MaximalEndComponent", "Maximal end component") .def_property_readonly("size", &MEC::size, "Number of states in MEC") - .def("__iter__", [](MEC const& mec) { - return py::make_iterator(mec.begin(), mec.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - ; - + .def( + "__iter__", [](MEC const& mec) { return py::make_iterator(mec.begin(), mec.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */); } template void define_maximal_end_component_decomposition(py::module& m, std::string const& vt_suffix) { - - py::class_, std::shared_ptr>>(m, ("MaximalEndComponentDecomposition"+vt_suffix).c_str(), "Decomposition of maximal end components") + py::class_, std::shared_ptr>>(m, ("MaximalEndComponentDecomposition" + vt_suffix).c_str(), + "Decomposition of maximal end components") .def(py::init const&>(), py::arg("model"), "Create MECs from model") .def_property_readonly("size", &MECDecomposition::size, "Number of MECs in the decomposition") - .def("__iter__", [](MECDecomposition const& mecs) { - return py::make_iterator(mecs.begin(), mecs.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) - ; - + .def( + "__iter__", [](MECDecomposition const& mecs) { return py::make_iterator(mecs.begin(), mecs.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */); } - template void define_maximal_end_component_decomposition(py::module& m, std::string const& vt_suffix); template void define_maximal_end_component_decomposition(py::module& m, std::string const& vt_suffix); template void define_maximal_end_component_decomposition(py::module& m, std::string const& vt_suffix); diff --git a/src/storage/distribution.cpp b/src/storage/distribution.cpp index f970e73d75..49548699e5 100644 --- a/src/storage/distribution.cpp +++ b/src/storage/distribution.cpp @@ -11,11 +11,9 @@ void define_distribution(py::module& m, std::string vt_suffix) { std::string distributionClassName = std::string("Distribution") + vt_suffix; py::class_ distribution(m, distributionClassName.c_str(), "Finite Support Distribution"); - distribution - .def("__str__", &streamToString); + distribution.def("__str__", &streamToString); } - template void define_distribution(py::module&, std::string vt_suffix); template void define_distribution(py::module&, std::string vt_suffix); template void define_distribution(py::module&, std::string vt_suffix); diff --git a/src/storage/expressions.cpp b/src/storage/expressions.cpp index c352e0e2b8..1e5c01cfc8 100644 --- a/src/storage/expressions.cpp +++ b/src/storage/expressions.cpp @@ -1,32 +1,36 @@ -#include #include "expressions.h" +#include #include "src/helpers.h" +#include "storm-parsers/parser/ExpressionParser.h" #include "storm/adapters/IntervalAdapter.h" -#include "storm/storage/expressions/ExpressionManager.h" #include "storm/storage/expressions/Expression.h" -#include "storm/storage/expressions/Valuation.h" +#include "storm/storage/expressions/ExpressionManager.h" #include "storm/storage/expressions/OperatorType.h" -#include "storm-parsers/parser/ExpressionParser.h" #include "storm/storage/expressions/ToDiceStringVisitor.h" +#include "storm/storage/expressions/Valuation.h" -//Define python bindings +// Define python bindings void define_expressions(py::module& m) { using Expression = storm::expressions::Expression; using Variable = storm::expressions::Variable; using Valuation = storm::expressions::Valuation; // ExpressionManager - py::class_>(m, "ExpressionManager", "Manages variables for expressions") + py::class_>(m, "ExpressionManager", + "Manages variables for expressions") .def(py::init(), "Constructor") .def("create_boolean", &storm::expressions::ExpressionManager::boolean, py::arg("boolean"), "Create expression from boolean") .def("create_integer", &storm::expressions::ExpressionManager::integer, py::arg("integer"), "Create expression from integer number") - .def("create_rational", [](storm::expressions::ExpressionManager const& manager, storm::RationalNumber number) { - return manager.rational(number); - }, py::arg("rational"), "Create expression from rational number") - .def("create_boolean_variable", &storm::expressions::ExpressionManager::declareBooleanVariable, "create Boolean variable", py::arg("name"), py::arg("auxiliary") = false) - .def("create_integer_variable", &storm::expressions::ExpressionManager::declareIntegerVariable, "create Integer variable", py::arg("name"), py::arg("auxiliary") = false) - .def("create_rational_variable", &storm::expressions::ExpressionManager::declareRationalVariable, "create Rational variable", py::arg("name"), py::arg("auxiliary") = false) + .def( + "create_rational", [](storm::expressions::ExpressionManager const& manager, storm::RationalNumber number) { return manager.rational(number); }, + py::arg("rational"), "Create expression from rational number") + .def("create_boolean_variable", &storm::expressions::ExpressionManager::declareBooleanVariable, "create Boolean variable", py::arg("name"), + py::arg("auxiliary") = false) + .def("create_integer_variable", &storm::expressions::ExpressionManager::declareIntegerVariable, "create Integer variable", py::arg("name"), + py::arg("auxiliary") = false) + .def("create_rational_variable", &storm::expressions::ExpressionManager::declareRationalVariable, "create Rational variable", py::arg("name"), + py::arg("auxiliary") = false) .def("has_variable", &storm::expressions::ExpressionManager::hasVariable, "checks whether a variable with a name is already taken", py::arg("name")) .def("get_variable", &storm::expressions::ExpressionManager::getVariable, "get variably by name", py::arg("name")) .def("get_variables", &storm::expressions::ExpressionManager::getVariables, "Retrieves the set of all variables known to this manager.") @@ -45,104 +49,102 @@ void define_expressions(py::module& m) { .def("has_bitvector_type", &storm::expressions::Variable::hasBitVectorType, "Check if the variable is of bitvector type") .def("get_expression", &storm::expressions::Variable::getExpression, "Get expression from variable") .def("__eq__", &storm::expressions::Variable::operator==) - .def("__hash__", &storm::expressions::Variable::getIndex) - ; - - - + .def("__hash__", &storm::expressions::Variable::getIndex); py::enum_(m, "OperatorType", "Type of an operator (of any sort)") - .value("And", storm::expressions::OperatorType::And) - .value("Or", storm::expressions::OperatorType::Or) - .value("Xor", storm::expressions::OperatorType::Xor) - .value("Implies", storm::expressions::OperatorType::Implies) - .value("Iff", storm::expressions::OperatorType::Iff) - .value("Plus", storm::expressions::OperatorType::Plus) - .value("Minus", storm::expressions::OperatorType::Minus) - .value("Times", storm::expressions::OperatorType::Times) - .value("Divide", storm::expressions::OperatorType::Divide) - .value("Min", storm::expressions::OperatorType::Min) - .value("Max", storm::expressions::OperatorType::Max) - .value("Power", storm::expressions::OperatorType::Power) - .value("Modulo", storm::expressions::OperatorType::Modulo) - .value("Equal", storm::expressions::OperatorType::Equal) - .value("NotEqual", storm::expressions::OperatorType::NotEqual) - .value("Less", storm::expressions::OperatorType::Less) - .value("LessOrEqual", storm::expressions::OperatorType::LessOrEqual) - .value("Greater", storm::expressions::OperatorType::Greater) - .value("GreaterOrEqual", storm::expressions::OperatorType::GreaterOrEqual) - .value("Not", storm::expressions::OperatorType::Not) - .value("Floor", storm::expressions::OperatorType::Floor) - .value("Ceil", storm::expressions::OperatorType::Ceil) - .value("Ite", storm::expressions::OperatorType::Ite) - ; - + .value("And", storm::expressions::OperatorType::And) + .value("Or", storm::expressions::OperatorType::Or) + .value("Xor", storm::expressions::OperatorType::Xor) + .value("Implies", storm::expressions::OperatorType::Implies) + .value("Iff", storm::expressions::OperatorType::Iff) + .value("Plus", storm::expressions::OperatorType::Plus) + .value("Minus", storm::expressions::OperatorType::Minus) + .value("Times", storm::expressions::OperatorType::Times) + .value("Divide", storm::expressions::OperatorType::Divide) + .value("Min", storm::expressions::OperatorType::Min) + .value("Max", storm::expressions::OperatorType::Max) + .value("Power", storm::expressions::OperatorType::Power) + .value("Modulo", storm::expressions::OperatorType::Modulo) + .value("Equal", storm::expressions::OperatorType::Equal) + .value("NotEqual", storm::expressions::OperatorType::NotEqual) + .value("Less", storm::expressions::OperatorType::Less) + .value("LessOrEqual", storm::expressions::OperatorType::LessOrEqual) + .value("Greater", storm::expressions::OperatorType::Greater) + .value("GreaterOrEqual", storm::expressions::OperatorType::GreaterOrEqual) + .value("Not", storm::expressions::OperatorType::Not) + .value("Floor", storm::expressions::OperatorType::Floor) + .value("Ceil", storm::expressions::OperatorType::Ceil) + .value("Ite", storm::expressions::OperatorType::Ite); // Expression py::class_> expression(m, "Expression", "Holds an expression"); expression.def(py::init(), "other_expression"_a) .def("contains_variables", &storm::expressions::Expression::containsVariables, "Check if the expression contains variables.") - .def("contains_variable", &storm::expressions::Expression::containsVariable, "Check if the expression contains any of the given variables.", py::arg("variables")) - .def("get_variables" , &storm::expressions::Expression::getVariables, "Get the variables") - .def("is_literal", &storm::expressions::Expression::isLiteral, "Check if the expression is a literal") - .def("is_variable", &storm::expressions::Expression::isVariable, "Check if the expression is a variable") - .def("identifier", &storm::expressions::Expression::getIdentifier, "Retrieves the identifier associated with this expression if this expression is a variable") + .def("contains_variable", &storm::expressions::Expression::containsVariable, "Check if the expression contains any of the given variables.", + py::arg("variables")) + .def("get_variables", &storm::expressions::Expression::getVariables, "Get the variables") + .def("is_literal", &storm::expressions::Expression::isLiteral, "Check if the expression is a literal") + .def("is_variable", &storm::expressions::Expression::isVariable, "Check if the expression is a variable") + .def("identifier", &storm::expressions::Expression::getIdentifier, + "Retrieves the identifier associated with this expression if this expression is a variable") .def("has_boolean_type", &storm::expressions::Expression::hasBooleanType, "Check if the expression is a boolean") .def("has_integer_type", &storm::expressions::Expression::hasIntegerType, "Check if the expression is an integer") .def("has_rational_type", &storm::expressions::Expression::hasRationalType, "Check if the expression is a rational") .def_property_readonly("type", &storm::expressions::Expression::getType, "Get the Type") .def_property_readonly("manager", &storm::expressions::Expression::getManager, "Get the manager") .def("simplify", &storm::expressions::Expression::simplify, "Simplify expression") - .def("substitute", [](Expression const& expr, std::map const& map) { return expr.substitute(map);}, "substitution_map"_a) - .def("evaluate_as_int", [](Expression const& expr) - {return expr.evaluateAsInt();}, "Get the integer value this expression evaluates to") - .def("evaluate_as_bool", [](Expression const& expr) - {return expr.evaluateAsBool();}, "Get the boolean value this expression evaluates to") - .def("evaluate_as_double", [](Expression const& expr) - {return expr.evaluateAsDouble();}, "Get the double value this expression evaluates to") - .def("evaluate_as_rational", [](Expression const& expr) - {return expr.evaluateAsRational();}, "Get the rational number this expression evaluates to") + .def( + "substitute", [](Expression const& expr, std::map const& map) { return expr.substitute(map); }, "substitution_map"_a) + .def( + "evaluate_as_int", [](Expression const& expr) { return expr.evaluateAsInt(); }, "Get the integer value this expression evaluates to") + .def( + "evaluate_as_bool", [](Expression const& expr) { return expr.evaluateAsBool(); }, "Get the boolean value this expression evaluates to") + .def( + "evaluate_as_double", [](Expression const& expr) { return expr.evaluateAsDouble(); }, "Get the double value this expression evaluates to") + .def( + "evaluate_as_rational", [](Expression const& expr) { return expr.evaluateAsRational(); }, "Get the rational number this expression evaluates to") .def("__str__", &storm::expressions::Expression::toString, "To string") - .def_property_readonly("is_function_application", &storm::expressions::Expression::isFunctionApplication, "True iff the expression is a function application (of any sort") + .def_property_readonly("is_function_application", &storm::expressions::Expression::isFunctionApplication, + "True iff the expression is a function application (of any sort") .def_property_readonly("operator", &storm::expressions::Expression::getOperator, "The operator of the expression (if it is a function application)") .def_property_readonly("arity", &storm::expressions::Expression::getArity, "The arity of the expression") - .def("get_operand", &storm::expressions::Expression::getOperand - , "Get the operand at the given index", py::arg("operandIndex")) - - .def_static("Plus", [](Expression const& lhs, Expression const& rhs) {return lhs + rhs;}) - .def_static("Minus", [](Expression const& lhs, Expression const& rhs) {return lhs - rhs;}) - .def_static("Multiply", [](Expression const& lhs, Expression const& rhs) {return lhs * rhs;}) - .def_static("Divide", [](Expression const& lhs, Expression const& rhs) {return lhs / rhs;}) - .def_static("And", [](Expression const& lhs, Expression const& rhs) {return lhs && rhs;}) - .def_static("Or", [](Expression const& lhs, Expression const& rhs) {return lhs || rhs;}) - .def_static("Geq", [](Expression const& lhs, Expression const& rhs) {return lhs >= rhs;}) - .def_static("Eq", [](Expression const& lhs, Expression const& rhs) {return lhs == rhs;}) - .def_static("Neq", [](Expression const& lhs, Expression const& rhs) {return lhs != rhs;}) - .def_static("Greater", [](Expression const& lhs, Expression const& rhs) {return lhs > rhs;}) - .def_static("Less", [](Expression const& lhs, Expression const& rhs) {return lhs < rhs;}) - .def_static("Leq", [](Expression const& lhs, Expression const& rhs) {return lhs <= rhs;}) - .def_static("Modulo", [](Expression const& lhs, Expression const& rhs) {return storm::expressions::modulo(lhs, rhs);}) - .def_static("Implies", [](Expression const& lhs, Expression const& rhs) {return storm::expressions::implies(lhs, rhs);}) - .def_static("Iff", [](Expression const& lhs, Expression const& rhs) {return storm::expressions::iff(lhs, rhs);}) - .def_static("Conjunction", [](std::vector const& expr) {return storm::expressions::conjunction(expr); }) - .def_static("Disjunction", [](std::vector const& expr) {return storm::expressions::disjunction(expr); }) - ; - + .def("get_operand", &storm::expressions::Expression::getOperand, "Get the operand at the given index", py::arg("operandIndex")) + + .def_static("Plus", [](Expression const& lhs, Expression const& rhs) { return lhs + rhs; }) + .def_static("Minus", [](Expression const& lhs, Expression const& rhs) { return lhs - rhs; }) + .def_static("Multiply", [](Expression const& lhs, Expression const& rhs) { return lhs * rhs; }) + .def_static("Divide", [](Expression const& lhs, Expression const& rhs) { return lhs / rhs; }) + .def_static("And", [](Expression const& lhs, Expression const& rhs) { return lhs && rhs; }) + .def_static("Or", [](Expression const& lhs, Expression const& rhs) { return lhs || rhs; }) + .def_static("Geq", [](Expression const& lhs, Expression const& rhs) { return lhs >= rhs; }) + .def_static("Eq", [](Expression const& lhs, Expression const& rhs) { return lhs == rhs; }) + .def_static("Neq", [](Expression const& lhs, Expression const& rhs) { return lhs != rhs; }) + .def_static("Greater", [](Expression const& lhs, Expression const& rhs) { return lhs > rhs; }) + .def_static("Less", [](Expression const& lhs, Expression const& rhs) { return lhs < rhs; }) + .def_static("Leq", [](Expression const& lhs, Expression const& rhs) { return lhs <= rhs; }) + .def_static("Modulo", [](Expression const& lhs, Expression const& rhs) { return storm::expressions::modulo(lhs, rhs); }) + .def_static("Implies", [](Expression const& lhs, Expression const& rhs) { return storm::expressions::implies(lhs, rhs); }) + .def_static("Iff", [](Expression const& lhs, Expression const& rhs) { return storm::expressions::iff(lhs, rhs); }) + .def_static("Conjunction", [](std::vector const& expr) { return storm::expressions::conjunction(expr); }) + .def_static("Disjunction", [](std::vector const& expr) { return storm::expressions::disjunction(expr); }); py::class_(m, "ExpressionParser", "Parser for storm-expressions") - .def(py::init(), "Expression Manager to use", py::arg("expression_manager")) - .def("set_identifier_mapping", [](storm::parser::ExpressionParser& p, std::unordered_map const& identifierMapping) {p.setIdentifierMapping(identifierMapping);}, "sets identifiers") - .def("parse", &storm::parser::ExpressionParser::parseFromString, py::arg("string"), py::arg("ignore_error") = false, "parse") - ; + .def(py::init(), "Expression Manager to use", py::arg("expression_manager")) + .def( + "set_identifier_mapping", + [](storm::parser::ExpressionParser& p, std::unordered_map const& identifierMapping) { + p.setIdentifierMapping(identifierMapping); + }, + "sets identifiers") + .def("parse", &storm::parser::ExpressionParser::parseFromString, py::arg("string"), py::arg("ignore_error") = false, "parse"); py::class_(m, "ExpressionType", "The type of an expression") - .def_property_readonly("is_boolean", &storm::expressions::Type::isBooleanType) - .def_property_readonly("is_integer", &storm::expressions::Type::isIntegerType) - .def_property_readonly("is_rational", &storm::expressions::Type::isRationalType) - .def("__str__", &storm::expressions::Type::getStringRepresentation); + .def_property_readonly("is_boolean", &storm::expressions::Type::isBooleanType) + .def_property_readonly("is_integer", &storm::expressions::Type::isIntegerType) + .def_property_readonly("is_rational", &storm::expressions::Type::isRationalType) + .def("__str__", &storm::expressions::Type::getStringRepresentation); py::class_(m, "DiceStringVisitor", "Translate expressions to dice") - .def(py::init(), py::arg("nr_bits")) - .def("to_string", [](storm::expressions::ToDiceStringVisitor& visitor, storm::expressions::Expression const& expr) { return visitor.toString(expr);}); - + .def(py::init(), py::arg("nr_bits")) + .def("to_string", [](storm::expressions::ToDiceStringVisitor& visitor, storm::expressions::Expression const& expr) { return visitor.toString(expr); }); } diff --git a/src/storage/geometry.cpp b/src/storage/geometry.cpp index cc1f033e16..cc146e83f6 100644 --- a/src/storage/geometry.cpp +++ b/src/storage/geometry.cpp @@ -1,6 +1,6 @@ #include "geometry.h" -#include "src/helpers.h" #include +#include "src/helpers.h" template void define_geometry(py::module& m, std::string vt_suffix) { @@ -9,12 +9,7 @@ void define_geometry(py::module& m, std::string vt_suffix) { polytope.def_property_readonly("vertices", &Polytope::getVertices); polytope.def("create_downward_closure", &Polytope::downwardClosure); polytope.def("get_vertices_clockwise", &Polytope::getVerticesInClockwiseOrder); - } -template -void define_geometry(py::module&, std::string); -template -void define_geometry(py::module&, std::string); - - +template void define_geometry(py::module&, std::string); +template void define_geometry(py::module&, std::string); diff --git a/src/storage/jani.cpp b/src/storage/jani.cpp index 56b774c14a..e6602b0362 100644 --- a/src/storage/jani.cpp +++ b/src/storage/jani.cpp @@ -1,12 +1,12 @@ #include "jani.h" -#include -#include -#include #include -#include +#include #include #include +#include +#include #include +#include #include "src/helpers.h" using namespace storm::jani; @@ -23,60 +23,72 @@ void define_jani(py::module& m) { .def_property_readonly("name", &Model::getName, "model name") .def_property_readonly("model_type", &storm::jani::Model::getModelType, "Model type") .def("set_model_type", &Model::setModelType, "Sets (only) the model type") - .def_property_readonly("automata", [](const Model& model) -> auto& {return model.getAutomata();}, "get automata") - .def_property_readonly("global_variables", [](const Model& model) -> auto& {return model.getGlobalVariables();}, py::return_value_policy::reference) - .def_property_readonly("constants", [](const Model& model) -> auto& {return model.getConstants();}, "get constants") + .def_property_readonly( + "automata", [](const Model& model) -> auto& { return model.getAutomata(); }, "get automata") + .def_property_readonly( + "global_variables", [](const Model& model) -> auto& { return model.getGlobalVariables(); }, py::return_value_policy::reference) + .def_property_readonly( + "constants", [](const Model& model) -> auto& { return model.getConstants(); }, "get constants") .def("get_constant", &Model::getConstant, "name"_a, "get constant by name") .def("restrict_edges", &Model::restrictEdges, "restrict model to edges given by set", py::arg("edge_set")) .def_property_readonly("expression_manager", &Model::getExpressionManager, "get expression manager", pybind11::return_value_policy::reference_internal) .def_property_readonly("has_undefined_constants", &Model::hasUndefinedConstants, "Flag if program has undefined constants") - .def_property_readonly("undefined_constants_are_graph_preserving", &Model::undefinedConstantsAreGraphPreserving, "Flag if the undefined constants do not change the graph structure") + .def_property_readonly("undefined_constants_are_graph_preserving", &Model::undefinedConstantsAreGraphPreserving, + "Flag if the undefined constants do not change the graph structure") .def("__str__", &janiToString) .def_property("initial_states_restriction", &Model::getInitialStatesRestriction, &Model::setInitialStatesRestriction, "initial states restriction") .def("add_constant", &Model::addConstant, "adds constant to model", py::arg("constant")) - .def("define_constants", &Model::defineUndefinedConstants, "define constants with a mapping from the corresponding expression variables to expressions", py::arg("map")) + .def("define_constants", &Model::defineUndefinedConstants, "define constants with a mapping from the corresponding expression variables to expressions", + py::arg("map")) .def("substitute_constants", &Model::substituteConstants, "substitute constants") .def("remove_constant", &Model::removeConstant, "remove a constant. Make sure the constant does not appear in the model.", "constant_name"_a) - .def("get_automaton", [](Model const& model, std::string const& name) {return model.getAutomaton(name);}, "name"_a) + .def( + "get_automaton", [](Model const& model, std::string const& name) { return model.getAutomaton(name); }, "name"_a) .def("get_automaton_index", &Model::getAutomatonIndex, "name"_a, "get index for automaton name") .def("add_automaton", &Model::addAutomaton, "automaton"_a, "add an automaton (with a unique name)") .def("set_standard_system_composition", &Model::setStandardSystemComposition, "sets the composition to the standard composition") .def("replace_automaton", &Model::replaceAutomaton, "index"_a, "new_automaton"_a, "replace automaton at index") .def("check_valid", &Model::checkValid, "Some basic checks to ensure validity") - .def("substitute_functions", [](Model& model) {model.substituteFunctions();}, "substitute functions") + .def( + "substitute_functions", [](Model& model) { model.substituteFunctions(); }, "substitute functions") .def_static("encode_automaton_and_edge_index", &Model::encodeAutomatonAndEdgeIndices, "get edge/automaton-index") .def_static("decode_automaton_and_edge_index", &Model::decodeAutomatonAndEdgeIndices, "get edge and automaton from edge/automaton index") .def("make_standard_compliant", &Model::makeStandardJaniCompliant, "make standard JANI compliant") .def("has_standard_composition", &Model::hasStandardComposition, "is the composition the standard composition") - .def("flatten_composition", &Model::flattenComposition, py::arg("smt_solver_factory")=std::make_shared()) - .def("finalize", &Model::finalize,"finalizes the model. After this action, be careful changing the data structure.") - .def("to_dot", [](Model& model) {std::stringstream ss; model.writeDotToStream(ss); return ss.str(); }) - ; + .def("flatten_composition", &Model::flattenComposition, py::arg("smt_solver_factory") = std::make_shared()) + .def("finalize", &Model::finalize, "finalizes the model. After this action, be careful changing the data structure.") + .def("to_dot", [](Model& model) { + std::stringstream ss; + model.writeDotToStream(ss); + return ss.str(); + }); py::class_> automaton(m, "JaniAutomaton", "A Jani Automation"); automaton.def(py::init()) - .def_property_readonly("edges",[](const Automaton& a) -> auto& { - return a.getEdges(); - }, "get edges") + .def_property_readonly( + "edges", [](const Automaton& a) -> auto& { return a.getEdges(); }, "get edges") .def_property_readonly("name", &Automaton::getName) .def_property_readonly("location_variable", &Automaton::getLocationExpressionVariable) - .def_property_readonly("variables", [](Automaton& aut) -> VariableSet& {return aut.getVariables();}, py::return_value_policy::reference_internal) - .def_property_readonly("locations", [](Automaton& aut) -> auto& {return aut.getLocations();}) + .def_property_readonly( + "variables", [](Automaton& aut) -> VariableSet& { return aut.getVariables(); }, py::return_value_policy::reference_internal) + .def_property_readonly("locations", [](Automaton& aut) -> auto& { return aut.getLocations(); }) .def("add_location", &Automaton::addLocation, "location"_a, "adds a new location, returns the index") - .def("add_initial_location", [](Automaton& aut, uint64_t index) { aut.addInitialLocation(index); }, "index"_a) + .def( + "add_initial_location", [](Automaton& aut, uint64_t index) { aut.addInitialLocation(index); }, "index"_a) .def_property_readonly("initial_location_indices", &Automaton::getInitialLocationIndices) - .def_property("initial_states_restriction", [](Automaton& aut) { aut.getInitialStatesExpression(); }, &Automaton::setInitialStatesRestriction, "initial state restriction") + .def_property( + "initial_states_restriction", [](Automaton& aut) { aut.getInitialStatesExpression(); }, &Automaton::setInitialStatesRestriction, + "initial state restriction") .def("add_edge", &Automaton::addEdge, "edge"_a) - .def("get_location_index", &Automaton::getLocationIndex, "name"_a) - ; + .def("get_location_index", &Automaton::getLocationIndex, "name"_a); py::class_> edge(m, "JaniEdge", "A Jani Edge"); - edge.def(py::init, std::shared_ptr, std::vector>>(), - "source_location_index"_a, "action_index"_a, "rate"_a, "template_edge"_a, "destinations_with_probabilities"_a) + edge.def(py::init, std::shared_ptr, + std::vector>>(), + "source_location_index"_a, "action_index"_a, "rate"_a, "template_edge"_a, "destinations_with_probabilities"_a) .def_property_readonly("source_location_index", &Edge::getSourceLocationIndex, "index for source location") - .def_property_readonly("destinations", [](Edge const& e) -> auto& { - return e.getDestinations(); - }, "edge destinations") + .def_property_readonly( + "destinations", [](Edge const& e) -> auto& { return e.getDestinations(); }, "edge destinations") .def_property_readonly("action_index", &Edge::getActionIndex, "action index") .def_property_readonly("template_edge", &Edge::getTemplateEdge, "template edge") .def_property_readonly("rate", &Edge::getOptionalRate, "edge rate") @@ -84,131 +96,139 @@ void define_jani(py::module& m) { .def_property_readonly("guard", &Edge::getGuard, "edge guard") .def_property("color", &Edge::getColor, &Edge::setColor, "color for the edge") .def("substitute", &Edge::substitute, py::arg("mapping"), py::arg("substitute_transcendental_numbers")) - .def("has_silent_action", &Edge::hasSilentAction, "Is the edge labelled with the silent action") - ; + .def("has_silent_action", &Edge::hasSilentAction, "Is the edge labelled with the silent action"); py::class_> templateEdge(m, "JaniTemplateEdge", "Template edge, internal data structure for edges"); templateEdge.def(py::init()) - .def_property_readonly("assignments", [](TemplateEdge& te) -> auto& { return te.getAssignments(); }) - .def_property("guard", &TemplateEdge::getGuard, &TemplateEdge::setGuard) - .def_property_readonly("destinations",[](TemplateEdge& te) -> auto& { return te.getDestinations(); }) - .def("add_destination", &TemplateEdge::addDestination) - ; + .def_property_readonly("assignments", [](TemplateEdge& te) -> auto& { return te.getAssignments(); }) + .def_property("guard", &TemplateEdge::getGuard, &TemplateEdge::setGuard) + .def_property_readonly("destinations", [](TemplateEdge& te) -> auto& { return te.getDestinations(); }) + .def("add_destination", &TemplateEdge::addDestination); py::class_> edgeDestination(m, "JaniEdgeDestination", "Destination in Jani"); edgeDestination.def_property_readonly("target_location_index", &EdgeDestination::getLocationIndex) .def_property_readonly("probability", &EdgeDestination::getProbability) - .def_property_readonly("assignments", &EdgeDestination::getOrderedAssignments) - ; + .def_property_readonly("assignments", &EdgeDestination::getOrderedAssignments); - py::class_> templateEdgeDestination(m, "JaniTemplateEdgeDestination", "Template edge destination, internal data structure for edge destinations"); + py::class_> templateEdgeDestination( + m, "JaniTemplateEdgeDestination", "Template edge destination, internal data structure for edge destinations"); templateEdgeDestination.def(py::init(), "ordered_assignments"_a) - .def_property_readonly("assignments", [](TemplateEdgeDestination& ted) -> auto& {return ted.getOrderedAssignments();}); + .def_property_readonly("assignments", [](TemplateEdgeDestination& ted) -> auto& { return ted.getOrderedAssignments(); }); py::class_> orderedAssignments(m, "JaniOrderedAssignments", "Set of assignments"); - orderedAssignments.def("__iter__", [](OrderedAssignments &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ + orderedAssignments + .def( + "__iter__", [](OrderedAssignments& v) { return py::make_iterator(v.begin(), v.end()); }, + py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */ .def(py::init const&>(), "assignments") .def("__str__", &streamToString) .def("clone", &OrderedAssignments::clone, "clone assignments (performs a deep copy)") - .def("substitute", &OrderedAssignments::substitute, "substitute in rhs according to given substitution map", "substitution_map"_a, "substitute_transcendental_numbers"_a) - .def("add", [](OrderedAssignments& oa, Assignment const& newAssignment, bool addToExisting) {return oa.add(newAssignment, addToExisting); }, "new_assignment"_a, "add_to_existing"_a = false) - ; + .def("substitute", &OrderedAssignments::substitute, "substitute in rhs according to given substitution map", "substitution_map"_a, + "substitute_transcendental_numbers"_a) + .def( + "add", [](OrderedAssignments& oa, Assignment const& newAssignment, bool addToExisting) { return oa.add(newAssignment, addToExisting); }, + "new_assignment"_a, "add_to_existing"_a = false); py::class_> assignment(m, "JaniAssignment", "Jani Assignment"); - assignment.def(py::init(), "lhs"_a, "rhs"_a, "lvl"_a = 0) + assignment.def(py::init(), "lhs"_a, "rhs"_a, "lvl"_a = 0) .def("__str__", &streamToString) .def_property("expression", &Assignment::getAssignedExpression, &Assignment::setAssignedExpression) - .def_property_readonly("variable", &Assignment::getVariable, "variable that is assigned to, if any") - ; + .def_property_readonly("variable", &Assignment::getVariable, "variable that is assigned to, if any"); py::class_> location(m, "JaniLocation", "A Location in JANI"); location.def(py::init(), "name"_a, "assignments"_a) - .def_property_readonly("name", &Location::getName, "name of the location") - .def_property_readonly("assignments", [](Location& loc) {loc.getAssignments();}, "location assignments") - ; + .def_property_readonly("name", &Location::getName, "name of the location") + .def_property_readonly("assignments", [](Location& loc) { loc.getAssignments(); }, "location assignments"); py::class_> variableSet(m, "JaniVariableSet", "Jani Set of Variables"); variableSet.def(py::init<>()) - .def("__iter__", [](VariableSet &v) { - return py::make_iterator(v.begin(), v.end()); - }, py::keep_alive<0, 1>()) + .def( + "__iter__", [](VariableSet& v) { return py::make_iterator(v.begin(), v.end()); }, py::keep_alive<0, 1>()) .def("add_variable", [](VariableSet& vs, Variable& v) -> void { vs.addVariable(v); }) .def("empty", &VariableSet::empty, "is there a variable in the set?") - .def("get_variable_by_name", [](VariableSet& v, std::string const& name) -> auto& { return v.getVariable(name);}, py::return_value_policy::reference) - .def("get_variable_by_expr_variable", [](VariableSet& v, storm::expressions::Variable const& var) -> auto& { return v.getVariable(var);}, py::return_value_policy::reference) - .def("erase_variable", &VariableSet::eraseVariable, "variable") - ; + .def( + "get_variable_by_name", [](VariableSet& v, std::string const& name) -> auto& { return v.getVariable(name); }, py::return_value_policy::reference) + .def( + "get_variable_by_expr_variable", [](VariableSet& v, storm::expressions::Variable const& var) -> auto& { return v.getVariable(var); }, + py::return_value_policy::reference) + .def("erase_variable", &VariableSet::eraseVariable, "variable"); py::class_> janiType(m, "JaniType", "A Variable Type in JANI"); janiType.def_property_readonly("is_array_type", &JaniType::isArrayType) - .def_property_readonly("is_bounded_type", &JaniType::isBoundedType) - .def_property_readonly("is_clock_type", &JaniType::isClockType) - .def_property_readonly("is_basic_type", &JaniType::isBasicType) - .def_property_readonly("is_continuous_type", &JaniType::isContinuousType) - .def("__str__", &JaniType::getStringRepresentation); + .def_property_readonly("is_bounded_type", &JaniType::isBoundedType) + .def_property_readonly("is_clock_type", &JaniType::isClockType) + .def_property_readonly("is_basic_type", &JaniType::isBasicType) + .def_property_readonly("is_continuous_type", &JaniType::isContinuousType) + .def("__str__", &JaniType::getStringRepresentation); py::class_> basicType(m, "BasicType", "A basic type in JANI", janiType); basicType.def_property_readonly("inner_type", &BasicType::get, "the inner type"); py::class_> boundedType(m, "BoundedType", "A bounded type in JANI", janiType); boundedType.def_property_readonly("base_type", &BoundedType::getBaseType, "the base type") - .def_property_readonly("lower_bound", [](const BoundedType& tp) -> storm::expressions::Expression const& {return tp.getLowerBound();}, "the lower bound") - .def_property_readonly("upper_bound", [](const BoundedType& tp) -> storm::expressions::Expression const& {return tp.getUpperBound();}, "the upper bound"); + .def_property_readonly( + "lower_bound", [](const BoundedType& tp) -> storm::expressions::Expression const& { return tp.getLowerBound(); }, "the lower bound") + .def_property_readonly( + "upper_bound", [](const BoundedType& tp) -> storm::expressions::Expression const& { return tp.getUpperBound(); }, "the upper bound"); py::class_> clockType(m, "ClockType", "A clock type in JANI", janiType); py::class_> arrayType(m, "ArrayType", "An array type in JANI", janiType); - arrayType.def_property_readonly("base_type", [](const ArrayType& tp) -> JaniType const& {return tp.getBaseType();}, "the base type"); + arrayType.def_property_readonly("base_type", [](const ArrayType& tp) -> JaniType const& { return tp.getBaseType(); }, "the base type"); py::class_> continuousType(m, "ContinuousType", "A continuous type in JANI", janiType); py::class_> variable(m, "JaniVariable", "A Variable in JANI"); variable.def_property_readonly("name", &Variable::getName, "name of constant") - .def_property_readonly("type", [](Variable& v) -> JaniType const& {return v.getType(); }, "type of the variable") - .def_property_readonly("expression_variable", &Variable::getExpressionVariable, "expression variable for this variable") - .def_property_readonly("init_expression", &Variable::getInitExpression) - .def_property_readonly("is_transient", &Variable::isTransient); + .def_property_readonly( + "type", [](Variable& v) -> JaniType const& { return v.getType(); }, "type of the variable") + .def_property_readonly("expression_variable", &Variable::getExpressionVariable, "expression variable for this variable") + .def_property_readonly("init_expression", &Variable::getInitExpression) + .def_property_readonly("is_transient", &Variable::isTransient); py::class_> constant(m, "JaniConstant", "A Constant in JANI"); constant.def(py::init()) .def_property_readonly("defined", &Constant::isDefined, "is constant defined by some expression") .def_property_readonly("name", &Constant::getName, "name of constant") .def_property_readonly("type", &Constant::getType, "type of constant") - .def_property_readonly("expression_variable", &Constant::getExpressionVariable, "expression variable for this constant") - ; + .def_property_readonly("expression_variable", &Constant::getExpressionVariable, "expression variable for this constant"); - m.def("eliminate_reward_accumulations", [](const Model& model, std::vector& properties) { + m.def( + "eliminate_reward_accumulations", + [](const Model& model, std::vector& properties) { storm::logic::RewardAccumulationEliminationVisitor v(model); v.eliminateRewardAccumulations(properties); return properties; - }, "Eliminate reward accumulations", py::arg("model"), py::arg("properties")); - + }, + "Eliminate reward accumulations", py::arg("model"), py::arg("properties")); py::class_ informationObject(m, "JaniInformationObject", "An object holding information about a JANI model"); informationObject.def_readwrite("model_type", &InformationObject::modelType) - .def_readwrite("nr_automata", &InformationObject::nrAutomata) - .def_readwrite("nr_edges", &InformationObject::nrEdges) - .def_readwrite("nr_variables", &InformationObject::nrVariables) - .def_readwrite("state_domain_size", &InformationObject::stateDomainSize) - .def_readwrite("avg_var_domain_size", &InformationObject::avgVarDomainSize); - - - m.def("collect_information", [](const Model& model) {return storm::jani::collectModelInformation(model);}); - - m.def("export_jani_to_file", [](std::string const& filepath, - Model const& model, - std::vector const& properties, - bool checkValid, - bool compact) { - return JsonExporter::toFile(model, properties, filepath, checkValid, compact);}, - "Writes a jani model to file, possibly including properties.", - py::arg("filename"), py::arg("model"), py::arg("properties")=std::vector(), py::arg("check_valid")=true, py::arg("compact")=false); + .def_readwrite("nr_automata", &InformationObject::nrAutomata) + .def_readwrite("nr_edges", &InformationObject::nrEdges) + .def_readwrite("nr_variables", &InformationObject::nrVariables) + .def_readwrite("state_domain_size", &InformationObject::stateDomainSize) + .def_readwrite("avg_var_domain_size", &InformationObject::avgVarDomainSize); + + m.def("collect_information", [](const Model& model) { return storm::jani::collectModelInformation(model); }); + + m.def( + "export_jani_to_file", + [](std::string const& filepath, Model const& model, std::vector const& properties, bool checkValid, bool compact) { + return JsonExporter::toFile(model, properties, filepath, checkValid, compact); + }, + "Writes a jani model to file, possibly including properties.", py::arg("filename"), py::arg("model"), + py::arg("properties") = std::vector(), py::arg("check_valid") = true, py::arg("compact") = false); } void define_jani_transformers(py::module& m) { py::class_(m, "JaniLocationExpander", "A transformer for Jani expanding variables into locations") - .def(py::init(), py::arg("model")) - .def("transform", &JaniLocationExpander::transform, py::arg("automaton_name"), py::arg("variable_name")) - ; + .def(py::init(), py::arg("model")) + .def("transform", &JaniLocationExpander::transform, py::arg("automaton_name"), py::arg("variable_name")); py::class_(m, "JaniScopeChanger", "A transformer for Jani changing variables from local to global and vice versa") - .def(py::init<>()) - .def("make_variables_local", [](JaniScopeChanger const& sc, Model const& model , std::vector const& props = {}) { Model newModel(model); sc.makeVariablesLocal(newModel, props); return newModel;}, py::arg("model"), py::arg("properties") = std::vector()); + .def(py::init<>()) + .def( + "make_variables_local", + [](JaniScopeChanger const& sc, Model const& model, std::vector const& props = {}) { + Model newModel(model); + sc.makeVariablesLocal(newModel, props); + return newModel; + }, + py::arg("model"), py::arg("properties") = std::vector()); } diff --git a/src/storage/labeling.cpp b/src/storage/labeling.cpp index fd60c84fb3..0cb488b060 100644 --- a/src/storage/labeling.cpp +++ b/src/storage/labeling.cpp @@ -1,46 +1,47 @@ #include "labeling.h" #include "src/helpers.h" +#include "storm/models/sparse/ChoiceLabeling.h" #include "storm/models/sparse/ItemLabeling.h" #include "storm/models/sparse/StateLabeling.h" -#include "storm/models/sparse/ChoiceLabeling.h" // Define python bindings void define_labeling(py::module& m) { - // ItemLabeling - py::class_> labeling(m,"ItemLabeling", "Labeling"); - labeling.def("add_label", [](storm::models::sparse::ItemLabeling& labeling, std::string label) { - labeling.addLabel(label); - }, py::arg("label"), "Add label") + py::class_> labeling(m, "ItemLabeling", "Labeling"); + labeling.def( + "add_label", [](storm::models::sparse::ItemLabeling& labeling, std::string label) { labeling.addLabel(label); }, py::arg("label"), "Add label") .def("get_labels", &storm::models::sparse::ItemLabeling::getLabels, "Get all labels") .def("contains_label", &storm::models::sparse::ItemLabeling::containsLabel, "Check if the given label is contained in the labeling", py::arg("label")) - .def("__str__", &streamToString) - ; - + .def("__str__", &streamToString); // StateLabeling py::class_>(m, "StateLabeling", "Labeling for states", labeling) .def(py::init(), "state_count"_a) .def("get_labels_of_state", &storm::models::sparse::StateLabeling::getLabelsOfState, "Get labels of given state", py::arg("state")) .def("add_label_to_state", &storm::models::sparse::StateLabeling::addLabelToState, "Add label to state", py::arg("label"), py::arg("state")) - .def("has_state_label", &storm::models::sparse::StateLabeling::getStateHasLabel, "Check if the given state has the given label", py::arg("label"), py::arg("state")) + .def("has_state_label", &storm::models::sparse::StateLabeling::getStateHasLabel, "Check if the given state has the given label", py::arg("label"), + py::arg("state")) .def("get_states", &storm::models::sparse::StateLabeling::getStates, "Get all states which have the given label", py::arg("label")) - .def("set_states", [](storm::models::sparse::StateLabeling& labeling, std::string const& label, storm::storage::BitVector const& states) { + .def( + "set_states", + [](storm::models::sparse::StateLabeling& labeling, std::string const& label, storm::storage::BitVector const& states) { labeling.setStates(label, states); - }, "Add a label to the given states", py::arg("label"), py::arg("states")) - .def("__str__", &streamToString) - ; - + }, + "Add a label to the given states", py::arg("label"), py::arg("states")) + .def("__str__", &streamToString); py::class_(m, "ChoiceLabeling", "Labeling for choices", labeling) - .def(py::init(), "choice_count"_a) - .def("get_labels_of_choice", &storm::models::sparse::ChoiceLabeling::getLabelsOfChoice, py::arg("choice"), "Get labels of the given choice") - .def("add_label_to_choice", &storm::models::sparse::ChoiceLabeling::addLabelToChoice, "Adds a label to a given choice", py::arg("label"), py::arg("state")) - .def("get_choices", &storm::models::sparse::ChoiceLabeling::getChoices, py::arg("label"), "Get all choices which have the given label") - .def("set_choices", [](storm::models::sparse::ChoiceLabeling& labeling, std::string const& label, storm::storage::BitVector const& choices) { + .def(py::init(), "choice_count"_a) + .def("get_labels_of_choice", &storm::models::sparse::ChoiceLabeling::getLabelsOfChoice, py::arg("choice"), "Get labels of the given choice") + .def("add_label_to_choice", &storm::models::sparse::ChoiceLabeling::addLabelToChoice, "Adds a label to a given choice", py::arg("label"), + py::arg("state")) + .def("get_choices", &storm::models::sparse::ChoiceLabeling::getChoices, py::arg("label"), "Get all choices which have the given label") + .def( + "set_choices", + [](storm::models::sparse::ChoiceLabeling& labeling, std::string const& label, storm::storage::BitVector const& choices) { labeling.setChoices(label, choices); - }, "Add a label to a the given choices", py::arg("label"), py::arg("choices")) - .def("__str__", &streamToString) - ; + }, + "Add a label to a the given choices", py::arg("label"), py::arg("choices")) + .def("__str__", &streamToString); } diff --git a/src/storage/matrix.cpp b/src/storage/matrix.cpp index 15c01ecc41..2ecda18d03 100644 --- a/src/storage/matrix.cpp +++ b/src/storage/matrix.cpp @@ -1,42 +1,50 @@ #include "matrix.h" +#include "src/helpers.h" #include "storm/adapters/IntervalAdapter.h" #include "storm/adapters/RationalFunctionAdapter.h" -#include "storm/storage/SparseMatrix.h" #include "storm/storage/BitVector.h" +#include "storm/storage/SparseMatrix.h" #include "storm/utility/graph.h" -#include "src/helpers.h" -template using SparseMatrix = storm::storage::SparseMatrix; -template using SparseMatrixBuilder = storm::storage::SparseMatrixBuilder; -template using entry_index = typename storm::storage::SparseMatrix::index_type; -template using MatrixEntry = storm::storage::MatrixEntry, ValueType>; +template +using SparseMatrix = storm::storage::SparseMatrix; +template +using SparseMatrixBuilder = storm::storage::SparseMatrixBuilder; +template +using entry_index = typename storm::storage::SparseMatrix::index_type; +template +using MatrixEntry = storm::storage::MatrixEntry, ValueType>; using RationalFunction = storm::RationalFunction; using row_index = unsigned int; void define_sparse_matrix_nt(py::module& m) { - m.def("_topological_sort_double", [](SparseMatrix& matrix, std::vector 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& matrix, std::vector 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_double", + [](SparseMatrix& matrix, std::vector 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& matrix, std::vector initial) { return storm::utility::graph::getTopologicalSort(matrix, initial); }, + "matrix"_a, "initial"_a, "get topological sort w.r.t. a transition matrix"); } template void define_sparse_matrix(py::module& m, std::string const& vtSuffix) { - // MatrixEntry py::class_>(m, (vtSuffix + "SparseMatrixEntry").c_str(), "Entry of sparse matrix") .def("__str__", &streamToString>) - //def_property threw "pointer being freed not allocated" after exiting + // def_property threw "pointer being freed not allocated" after exiting .def("value", &MatrixEntry::getValue, "Value") .def("set_value", &MatrixEntry::setValue, py::arg("value"), "Set value") - .def_property_readonly("column", &MatrixEntry::getColumn, "Column") - ; - + .def_property_readonly("column", &MatrixEntry::getColumn, "Column"); // SparseMatrixBuilder - py::class_>(m, ( vtSuffix + "SparseMatrixBuilder").c_str(), "Builder of sparse matrix") - .def(py::init(), "rows"_a = 0, "columns"_a = 0, "entries"_a = 0, "force_dimensions"_a = true, "has_custom_row_grouping"_a = false, "row_groups"_a = 0) + py::class_>(m, (vtSuffix + "SparseMatrixBuilder").c_str(), "Builder of sparse matrix") + .def(py::init(), "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::addNextValue, R"dox( + .def("add_next_value", &SparseMatrixBuilder::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. @@ -49,90 +57,102 @@ void define_sparse_matrix(py::module& m, std::string const& vtSuffix) { :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 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")) + )dox", + py::arg("row"), py::arg("column"), py::arg("value")) - .def("new_row_group", &SparseMatrixBuilder::newRowGroup, py::arg("starting_row"), "Start a new row group in the matrix") - .def("build", &SparseMatrixBuilder::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::getLastRow, "Get the most recently used row") - .def("get_current_row_group_count", &SparseMatrixBuilder::getCurrentRowGroupCount, "Get the current row group count") - .def("get_last_column", &SparseMatrixBuilder::getLastColumn, "the most recently used column") - .def("replace_columns", &SparseMatrixBuilder::replaceColumns, R"dox( + .def("new_row_group", &SparseMatrixBuilder::newRowGroup, py::arg("starting_row"), "Start a new row group in the matrix") + .def("build", &SparseMatrixBuilder::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::getLastRow, "Get the most recently used row") + .def("get_current_row_group_count", &SparseMatrixBuilder::getCurrentRowGroupCount, "Get the current row group count") + .def("get_last_column", &SparseMatrixBuilder::getLastColumn, "the most recently used column") + .def("replace_columns", &SparseMatrixBuilder::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 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")) - ; + )dox", + py::arg("replacements"), py::arg("offset")); // SparseMatrix py::class_>(m, (vtSuffix + "SparseMatrix").c_str(), "Sparse matrix") - .def("__iter__", [](SparseMatrix& matrix) { - return py::make_iterator(matrix.begin(), matrix.end()); - }, py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) + .def( + "__iter__", [](SparseMatrix& matrix) { return py::make_iterator(matrix.begin(), matrix.end()); }, + py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */) .def("__str__", &streamToString>) .def_property_readonly("nr_rows", &SparseMatrix::getRowCount, "Number of rows") .def_property_readonly("nr_columns", &SparseMatrix::getColumnCount, "Number of columns") .def_property_readonly("nr_entries", &SparseMatrix::getEntryCount, "Number of non-zero entries") - .def("get_row_group_start", [](SparseMatrix& matrix, entry_index row) {return matrix.getRowGroupIndices()[row];}) - .def("get_row_group_end", [](SparseMatrix& matrix, entry_index row) {return matrix.getRowGroupIndices()[row+1];}) + .def("get_row_group_start", [](SparseMatrix& matrix, entry_index row) { return matrix.getRowGroupIndices()[row]; }) + .def("get_row_group_end", [](SparseMatrix& matrix, entry_index row) { return matrix.getRowGroupIndices()[row + 1]; }) .def_property_readonly("has_trivial_row_grouping", &SparseMatrix::hasTrivialRowGrouping, "Trivial row grouping") .def("make_row_grouping_trivial", &SparseMatrix::makeRowGroupingTrivial, "Makes row groups trivial. Use with care.") - .def("get_row", [](SparseMatrix& matrix, entry_index 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_for_group", [](SparseMatrix& matrix, entry_index group) { + .def( + "get_row", [](SparseMatrix& matrix, entry_index 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_for_group", + [](SparseMatrix& matrix, entry_index group) { auto range = matrix.getRowGroupIndices(group); return std::vector(range.begin(), range.end()); - }, py::arg("row_group"), "Get rows within a row group") - .def("print_row", [](SparseMatrix const& matrix, entry_index row) { + }, + py::arg("row_group"), "Get rows within a row group") + .def( + "print_row", + [](SparseMatrix const& matrix, entry_index row) { std::stringstream stream; - auto rows = matrix.getRows(row, row+1); + auto rows = matrix.getRows(row, row + 1); for (auto transition : rows) { stream << transition << ", "; } return stream.str(); - }, py::arg("row"), "Print rows from start to end") - .def("submatrix", [](SparseMatrix const& matrix, storm::storage::BitVector const& rowConstraint, storm::storage::BitVector const& columnConstraint, bool insertDiagonalEntries = false, bool useGroups = true) { - return matrix.getSubmatrix(useGroups, rowConstraint, columnConstraint, insertDiagonalEntries); - }, py::arg("row_constraint"), py::arg("column_constraint"), py::arg("insert_diagonal_entries") = false, py::arg("use_groups") = true, "Get submatrix") + }, + py::arg("row"), "Print rows from start to end") + .def( + "submatrix", + [](SparseMatrix const& matrix, storm::storage::BitVector const& rowConstraint, storm::storage::BitVector const& columnConstraint, + bool insertDiagonalEntries = false, + bool useGroups = true) { return matrix.getSubmatrix(useGroups, rowConstraint, columnConstraint, insertDiagonalEntries); }, + py::arg("row_constraint"), py::arg("column_constraint"), py::arg("insert_diagonal_entries") = false, py::arg("use_groups") = true, "Get submatrix") // Entry_index lead to problems - .def("row_iter", [](SparseMatrix& 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") + .def( + "row_iter", [](SparseMatrix& 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::getRowCount) - .def("__getitem__", [](SparseMatrix& matrix, entry_index i) { + .def( + "__getitem__", + [](SparseMatrix& matrix, entry_index 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& matrix, py::slice slice) { + return matrix.getRows(i, i + 1); + }, + py::return_value_policy::reference, py::keep_alive<1, 0>()) + .def( + "__getitem__", + [](SparseMatrix& 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 + throw py::value_error(); // not supported return matrix.getRows(start, stop); - }, py::return_value_policy::reference, py::keep_alive<1, 0>()) - ; - + }, + py::return_value_policy::reference, py::keep_alive<1, 0>()); // Rows py::class_::rows>(m, (vtSuffix + "SparseMatrixRows").c_str(), "Set of rows in a sparse matrix") - .def("__iter__", [](typename SparseMatrix::rows& rows) { - return py::make_iterator(rows.begin(), rows.end()); - }, py::keep_alive<0, 1>()) + .def( + "__iter__", [](typename SparseMatrix::rows& rows) { return py::make_iterator(rows.begin(), rows.end()); }, py::keep_alive<0, 1>()) .def("__str__", &containerToString::rows>) - .def("__len__", &storm::storage::SparseMatrix::rows::getNumberOfEntries) - ; + .def("__len__", &storm::storage::SparseMatrix::rows::getNumberOfEntries); } template void define_sparse_matrix(py::module& m, std::string const& vtSuffix); template void define_sparse_matrix(py::module& m, std::string const& vtSuffix); template void define_sparse_matrix(py::module& m, std::string const& vtSuffix); template void define_sparse_matrix(py::module& m, std::string const& vtSuffix); - diff --git a/src/storage/memorystructure.cpp b/src/storage/memorystructure.cpp index d6b1f814d8..e57fbac399 100644 --- a/src/storage/memorystructure.cpp +++ b/src/storage/memorystructure.cpp @@ -1,18 +1,20 @@ #include "memorystructure.h" -#include #include +#include #include #include #include - void define_memorystructure_untyped(py::module& m) { typedef storm::storage::MemoryStructure MemoryStructure; py::class_> memoryStructure(m, "MemoryStructure"); - memoryStructure.def("product", [](MemoryStructure& ms, MemoryStructure const& memModel) {return ms.product(memModel);}); - memoryStructure.def("_product_model_double", [](MemoryStructure& ms, storm::models::sparse::Model const& sparseModel) {return ms.product(sparseModel);}); - memoryStructure.def("_product_model_exact", [](MemoryStructure& ms, storm::models::sparse::Model const& sparseModel) {return ms.product(sparseModel);}); - memoryStructure.def("_product_model_parametric", [](MemoryStructure& ms, storm::models::sparse::Model const& sparseModel) {return ms.product(sparseModel);}); + memoryStructure.def("product", [](MemoryStructure& ms, MemoryStructure const& memModel) { return ms.product(memModel); }); + memoryStructure.def("_product_model_double", + [](MemoryStructure& ms, storm::models::sparse::Model const& sparseModel) { return ms.product(sparseModel); }); + memoryStructure.def("_product_model_exact", + [](MemoryStructure& ms, storm::models::sparse::Model const& sparseModel) { return ms.product(sparseModel); }); + memoryStructure.def("_product_model_parametric", + [](MemoryStructure& ms, storm::models::sparse::Model const& sparseModel) { return ms.product(sparseModel); }); memoryStructure.def_property_readonly("nr_states", &MemoryStructure::getNumberOfStates); memoryStructure.def_property_readonly("state_labeling", &MemoryStructure::getStateLabeling); } @@ -21,16 +23,20 @@ template void define_memorystructure_typed(py::module& m, std::string const& vtSuffix) { typedef storm::storage::MemoryStructureBuilder MemoryStructureBuilder; py::class_> msb(m, ("MemoryStructureBuilder" + vtSuffix).c_str()); - msb.def(py::init const&, bool>(), py::arg("nr_memory_states"), py::arg("model"), py::arg("only_initial_states_relevant")=true); + msb.def(py::init const&, bool>(), py::arg("nr_memory_states"), py::arg("model"), + py::arg("only_initial_states_relevant") = true); msb.def("build", &MemoryStructureBuilder::build); msb.def("set_label", &MemoryStructureBuilder::setLabel, py::arg("state"), py::arg("label")); - msb.def("set_transition", &MemoryStructureBuilder::setTransition, py::arg("start_state"), py::arg("goal_state"), py::arg("model_states"), py::arg("model_choices")=boost::none); + msb.def("set_transition", &MemoryStructureBuilder::setTransition, py::arg("start_state"), py::arg("goal_state"), py::arg("model_states"), + py::arg("model_choices") = boost::none); msb.def("set_initial_memory_state", &MemoryStructureBuilder::setInitialMemoryState, py::arg("state"), py::arg("value")); typedef storm::storage::SparseModelMemoryProduct MemoryStructureProduct; py::class_> msp(m, ("MemoryStructureProduct" + vtSuffix).c_str()); msp.def("build", &MemoryStructureProduct::build, py::arg("preserve_model_type") = false); - msp.def("set_build_full_product", &MemoryStructureProduct::setBuildFullProduct, "Enforces that every state is considered reachable and thus constructed. This causes the product to have the size of the product of the original model and the memory structure."); + msp.def("set_build_full_product", &MemoryStructureProduct::setBuildFullProduct, + "Enforces that every state is considered reachable and thus constructed. This causes the product to have the size of the product of the original " + "model and the memory structure."); } template void define_memorystructure_typed(py::module& m, std::string const& vt_suffix); diff --git a/src/storage/model.cpp b/src/storage/model.cpp index 16f17ee1a1..fce6191d51 100644 --- a/src/storage/model.cpp +++ b/src/storage/model.cpp @@ -4,50 +4,66 @@ #include "storm/adapters/IntervalAdapter.h" #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/models/ModelBase.h" -#include "storm/models/sparse/Model.h" +#include "storm/models/sparse/Ctmc.h" #include "storm/models/sparse/Dtmc.h" +#include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/Mdp.h" +#include "storm/models/sparse/Model.h" #include "storm/models/sparse/Pomdp.h" -#include "storm/models/sparse/Ctmc.h" -#include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/Smg.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/models/symbolic/Model.h" -#include "storm/models/symbolic/Dtmc.h" -#include "storm/models/symbolic/Mdp.h" #include "storm/models/symbolic/Ctmc.h" +#include "storm/models/symbolic/Dtmc.h" #include "storm/models/symbolic/MarkovAutomaton.h" +#include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/Model.h" #include "storm/models/symbolic/StandardRewardModel.h" -#include "storm/utility/dd.h" -#include "storm/storage/dd/DdManager.h" #include "storm/storage/Scheduler.h" +#include "storm/storage/dd/DdManager.h" +#include "storm/utility/dd.h" #include -#include #include +#include // Typedefs using ModelBase = storm::models::ModelBase; -template using ModelComponents = storm::storage::sparse::ModelComponents; -template using SparseModel = storm::models::sparse::Model; -template using SparseDeterministicModel = storm::models::sparse::DeterministicModel; -template using SparseNondeterministicModel = storm::models::sparse::NondeterministicModel; -template using SparseDtmc = storm::models::sparse::Dtmc; -template using SparseMdp = storm::models::sparse::Mdp; -template using SparsePomdp = storm::models::sparse::Pomdp; -template using SparseCtmc = storm::models::sparse::Ctmc; -template using SparseMarkovAutomaton = storm::models::sparse::MarkovAutomaton; -template using SparseSmg = storm::models::sparse::Smg; -template using SparseRewardModel = storm::models::sparse::StandardRewardModel; - -template using SymbolicModel = storm::models::symbolic::Model; -template using SymbolicDtmc = storm::models::symbolic::Dtmc; -template using SymbolicMdp = storm::models::symbolic::Mdp; -template using SymbolicCtmc = storm::models::symbolic::Ctmc; -template using SymbolicMarkovAutomaton = storm::models::symbolic::MarkovAutomaton; -template using SymbolicRewardModel = storm::models::symbolic::StandardRewardModel; +template +using ModelComponents = storm::storage::sparse::ModelComponents; +template +using SparseModel = storm::models::sparse::Model; +template +using SparseDeterministicModel = storm::models::sparse::DeterministicModel; +template +using SparseNondeterministicModel = storm::models::sparse::NondeterministicModel; +template +using SparseDtmc = storm::models::sparse::Dtmc; +template +using SparseMdp = storm::models::sparse::Mdp; +template +using SparsePomdp = storm::models::sparse::Pomdp; +template +using SparseCtmc = storm::models::sparse::Ctmc; +template +using SparseMarkovAutomaton = storm::models::sparse::MarkovAutomaton; +template +using SparseSmg = storm::models::sparse::Smg; +template +using SparseRewardModel = storm::models::sparse::StandardRewardModel; +template +using SymbolicModel = storm::models::symbolic::Model; +template +using SymbolicDtmc = storm::models::symbolic::Dtmc; +template +using SymbolicMdp = storm::models::symbolic::Mdp; +template +using SymbolicCtmc = storm::models::symbolic::Ctmc; +template +using SymbolicMarkovAutomaton = storm::models::symbolic::MarkovAutomaton; +template +using SymbolicRewardModel = storm::models::symbolic::StandardRewardModel; // Thin wrappers template @@ -64,7 +80,6 @@ storm::storage::SparseMatrix& getTransitionMatrix(SparseModel& model) return model.getStateLabeling(); } - // Bindings for general models void define_model(py::module& m) { - // ModelType py::enum_(m, "ModelType", "Type of the model") .value("DTMC", storm::models::ModelType::Dtmc) @@ -87,8 +100,7 @@ void define_model(py::module& m) { .value("POMDP", storm::models::ModelType::Pomdp) .value("CTMC", storm::models::ModelType::Ctmc) .value("MA", storm::models::ModelType::MarkovAutomaton) - .value("SMG", storm::models::ModelType::Smg) - ; + .value("SMG", storm::models::ModelType::Smg); // ModelBase py::class_> modelBase(m, "_ModelBase", "Base class for all models"); @@ -104,292 +116,339 @@ void define_model(py::module& m) { .def_property_readonly("is_symbolic_model", &ModelBase::isSymbolicModel, "Flag whether the model is stored using decision diagrams") .def_property_readonly("is_discrete_time_model", &ModelBase::isDiscreteTimeModel, "Flag whether the model is a discrete time model") .def_property_readonly("is_nondeterministic_model", &ModelBase::isNondeterministicModel, "Flag whether the model contains nondeterminism") - .def("_as_sparse_dtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse DTMC") - .def("_as_sparse_exact_dtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse exact DTMC") - .def("_as_sparse_idtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse interval DTMC") - .def("_as_sparse_pdtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse parametric DTMC") - .def("_as_sparse_mdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse MDP") - .def("_as_sparse_exact_mdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse exact MDP") - .def("_as_sparse_imdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse interval MDP") - .def("_as_sparse_pmdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse parametric MDP") - .def("_as_sparse_pomdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse POMDP") - .def("_as_sparse_exact_pomdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse exact POMDP") - .def("_as_sparse_ipomdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse interval POMDP") - .def("_as_sparse_ppomdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse parametric POMDP") - .def("_as_sparse_ctmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse CTMC") - .def("_as_sparse_exact_ctmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse exact CTMC") - .def("_as_sparse_ictmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse interval CTMC") - .def("_as_sparse_pctmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse parametric CTMC") - .def("_as_sparse_ma", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse MA") - .def("_as_sparse_exact_ma", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse exact MA") - .def("_as_sparse_ima", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse interval MA") - .def("_as_sparse_pma", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse parametric MA") - .def("_as_sparse_smg", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse SMG") - .def("_as_sparse_exact_smg", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse exact SMG") - .def("_as_sparse_ismg", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse interval SMG") - .def("_as_sparse_psmg", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as sparse parametric SMG") - .def("_as_symbolic_dtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic DTMC") - .def("_as_symbolic_exact_dtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic exact DTMC") - .def("_as_symbolic_pdtmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic parametric DTMC") - .def("_as_symbolic_mdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic MDP") - .def("_as_symbolic_exact_mdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic exact MDP") - .def("_as_symbolic_pmdp", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic parametric MDP") - .def("_as_symbolic_ctmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic CTMC") - .def("_as_symbolic_exact_ctmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic exact CTMC") - .def("_as_symbolic_pctmc", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic parametric CTMC") - .def("_as_symbolic_ma", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic MA") - .def("_as_symbolic_exact_ma", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic exact MA") - .def("_as_symbolic_pma", [](ModelBase &modelbase) { - return modelbase.as>(); - }, "Get model as symbolic parametric MA") - ; + .def( + "_as_sparse_dtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse DTMC") + .def( + "_as_sparse_exact_dtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse exact DTMC") + .def( + "_as_sparse_idtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse interval DTMC") + .def( + "_as_sparse_pdtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse parametric DTMC") + .def( + "_as_sparse_mdp", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse MDP") + .def( + "_as_sparse_exact_mdp", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse exact MDP") + .def( + "_as_sparse_imdp", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse interval MDP") + .def( + "_as_sparse_pmdp", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse parametric MDP") + .def( + "_as_sparse_pomdp", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse POMDP") + .def( + "_as_sparse_exact_pomdp", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as sparse exact POMDP") + .def( + "_as_sparse_ipomdp", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse interval POMDP") + .def( + "_as_sparse_ppomdp", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as sparse parametric POMDP") + .def( + "_as_sparse_ctmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse CTMC") + .def( + "_as_sparse_exact_ctmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse exact CTMC") + .def( + "_as_sparse_ictmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse interval CTMC") + .def( + "_as_sparse_pctmc", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse parametric CTMC") + .def( + "_as_sparse_ma", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse MA") + .def( + "_as_sparse_exact_ma", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as sparse exact MA") + .def( + "_as_sparse_ima", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse interval MA") + .def( + "_as_sparse_pma", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as sparse parametric MA") + .def( + "_as_sparse_smg", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse SMG") + .def( + "_as_sparse_exact_smg", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse exact SMG") + .def( + "_as_sparse_ismg", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse interval SMG") + .def( + "_as_sparse_psmg", [](ModelBase& modelbase) { return modelbase.as>(); }, "Get model as sparse parametric SMG") + .def( + "_as_symbolic_dtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic DTMC") + .def( + "_as_symbolic_exact_dtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic exact DTMC") + .def( + "_as_symbolic_pdtmc", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic parametric DTMC") + .def( + "_as_symbolic_mdp", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic MDP") + .def( + "_as_symbolic_exact_mdp", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic exact MDP") + .def( + "_as_symbolic_pmdp", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic parametric MDP") + .def( + "_as_symbolic_ctmc", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic CTMC") + .def( + "_as_symbolic_exact_ctmc", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic exact CTMC") + .def( + "_as_symbolic_pctmc", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic parametric CTMC") + .def( + "_as_symbolic_ma", [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic MA") + .def( + "_as_symbolic_exact_ma", + [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic exact MA") + .def( + "_as_symbolic_pma", + [](ModelBase& modelbase) { return modelbase.as>(); }, + "Get model as symbolic parametric MA"); } - // Bindings for sparse models template void define_sparse_model(py::module& m, std::string const& vtSuffix) { - py::class_, std::shared_ptr>, ModelBase> model(m, ("_Sparse" + vtSuffix + "Model").c_str(), - "A probabilistic model in a sparse matrix representation"); + "A probabilistic model in a sparse matrix representation"); model.def_property_readonly("supports_uncertainty", &SparseModel::supportsUncertainty, "Flag whether model supports uncertainty via intervals") .def_property_readonly("labeling", &getLabeling, "Labels") - .def("has_choice_labeling", [](SparseModel const& model) {return model.hasChoiceLabeling();}, "Does the model have an associated choice labelling?") - .def_property_readonly("choice_labeling", [](SparseModel const& model) {return model.getChoiceLabeling();}, "get choice labelling") - .def("has_choice_origins", [](SparseModel const& model) {return model.hasChoiceOrigins();}, "has choice origins?") - .def_property_readonly("choice_origins", [](SparseModel const& model) {return model.getChoiceOrigins();}) + .def( + "has_choice_labeling", [](SparseModel const& model) { return model.hasChoiceLabeling(); }, + "Does the model have an associated choice labelling?") + .def_property_readonly( + "choice_labeling", [](SparseModel const& model) { return model.getChoiceLabeling(); }, "get choice labelling") + .def( + "has_choice_origins", [](SparseModel const& model) { return model.hasChoiceOrigins(); }, "has choice origins?") + .def_property_readonly("choice_origins", [](SparseModel const& model) { return model.getChoiceOrigins(); }) .def("labels_state", &SparseModel::getLabelsOfState, py::arg("state"), "Get labels of state") .def_property_readonly("initial_states", &getSparseInitialStates, "Initial states") - .def_property_readonly("initial_states_as_bitvector", [](SparseModel const& model) {return model.getInitialStates();}) + .def_property_readonly("initial_states_as_bitvector", [](SparseModel const& model) { return model.getInitialStates(); }) .def("set_initial_states", &SparseModel::setInitialStates, py::arg("states"), "Set initial states") - .def_property_readonly("states", [](SparseModel& model) { - return SparseModelStates(model); - }, "Get states") - .def_property_readonly("reward_models", [](SparseModel& model) {return model.getRewardModels(); }, "Reward models") - .def_property_readonly("transition_matrix", py::cpp_function(&getTransitionMatrix, py::return_value_policy::reference, py::keep_alive<1, 0>()), "Transition matrix") - .def_property_readonly("backward_transition_matrix", py::cpp_function(&SparseModel::getBackwardTransitions, py::return_value_policy::reference, py::keep_alive<1, 0>()), "Backward transition matrix") - .def("get_reward_model", [](SparseModel& model, std::string const& name) -> SparseRewardModel& {return model.getRewardModel(name);}, py::return_value_policy::reference, py::keep_alive<1, 0>(), "Reward model") - .def("has_reward_model", [](SparseModel const& model, std::string const& name) {return model.hasRewardModel(name);}, py::arg("name")) - .def("add_reward_model", [](SparseModel& model, std::string const& name, SparseRewardModel const& rewModel) { model.addRewardModel(name, rewModel);}) - .def("has_state_valuations", [](SparseModel const& model) {return model.hasStateValuations();}, "has state valuation?") - .def_property_readonly("state_valuations", [](SparseModel const& model) {return model.getStateValuations();}, "state valuations") + .def_property_readonly( + "states", [](SparseModel& model) { return SparseModelStates(model); }, "Get states") + .def_property_readonly( + "reward_models", [](SparseModel& model) { return model.getRewardModels(); }, "Reward models") + .def_property_readonly("transition_matrix", + py::cpp_function(&getTransitionMatrix, py::return_value_policy::reference, py::keep_alive<1, 0>()), + "Transition matrix") + .def_property_readonly("backward_transition_matrix", + py::cpp_function(&SparseModel::getBackwardTransitions, py::return_value_policy::reference, py::keep_alive<1, 0>()), + "Backward transition matrix") + .def( + "get_reward_model", + [](SparseModel& model, std::string const& name) -> SparseRewardModel& { return model.getRewardModel(name); }, + py::return_value_policy::reference, py::keep_alive<1, 0>(), "Reward model") + .def( + "has_reward_model", [](SparseModel const& model, std::string const& name) { return model.hasRewardModel(name); }, py::arg("name")) + .def("add_reward_model", + [](SparseModel& model, std::string const& name, SparseRewardModel const& rewModel) { model.addRewardModel(name, rewModel); }) + .def( + "has_state_valuations", [](SparseModel const& model) { return model.hasStateValuations(); }, "has state valuation?") + .def_property_readonly( + "state_valuations", [](SparseModel const& model) { return model.getStateValuations(); }, "state valuations") .def("reduce_to_state_based_rewards", &SparseModel::reduceToStateBasedRewards) .def("is_sink_state", &SparseModel::isSinkState, py::arg("state")) .def("__str__", &getModelInfoPrinter) - .def("to_dot", [](SparseModel& model) { std::stringstream ss; model.writeDotToStream(ss); return ss.str(); }, "Write dot to a string") - ; + .def( + "to_dot", + [](SparseModel& model) { + std::stringstream ss; + model.writeDotToStream(ss); + return ss.str(); + }, + "Write dot to a string"); if constexpr (std::is_same_v) { - model.def("collect_probability_parameters", [](SparseModel const& model) -> std::set { - return storm::models::sparse::getProbabilityParameters(model); - }, "Collect probability parameters") - .def("collect_reward_parameters", [](SparseModel const& model) -> std::set { - return storm::models::sparse::getRewardParameters(model); - }, "Collect reward parameters") - .def("collect_rate_parameters", [](SparseModel const& model) -> std::set { - return storm::models::sparse::getRateParameters(model); - }, "Collect rate parameters") - .def("collect_all_parameters", [](SparseModel const& model) -> std::set { - return storm::models::sparse::getAllParameters(model); - }, "Collect all parameters") - .def("get_states_with_parameter", [](SparseModel const& model, storm::RationalFunctionVariable const& var) -> storm::storage::BitVector { - storm::storage::BitVector result(model.getNumberOfStates()); - for (uint64_t s = 0; s < model.getNumberOfStates(); ++s) { - for(auto const& entry : model.getTransitionMatrix().getRowGroup(s)) { - if (entry.getValue().gatherVariables().count(var) > 0) { - result.set(s); - break; + model + .def( + "collect_probability_parameters", + [](SparseModel const& model) -> std::set { + return storm::models::sparse::getProbabilityParameters(model); + }, + "Collect probability parameters") + .def( + "collect_reward_parameters", + [](SparseModel const& model) -> std::set { + return storm::models::sparse::getRewardParameters(model); + }, + "Collect reward parameters") + .def( + "collect_rate_parameters", + [](SparseModel const& model) -> std::set { + return storm::models::sparse::getRateParameters(model); + }, + "Collect rate parameters") + .def( + "collect_all_parameters", + [](SparseModel const& model) -> std::set { return storm::models::sparse::getAllParameters(model); }, + "Collect all parameters") + .def( + "get_states_with_parameter", + [](SparseModel const& model, storm::RationalFunctionVariable const& var) -> storm::storage::BitVector { + storm::storage::BitVector result(model.getNumberOfStates()); + for (uint64_t s = 0; s < model.getNumberOfStates(); ++s) { + for (auto const& entry : model.getTransitionMatrix().getRowGroup(s)) { + if (entry.getValue().gatherVariables().count(var) > 0) { + result.set(s); + break; + } } } - } - return result; - }, py::arg("parameter"), "Find states with a particular parameter") - ; + return result; + }, + py::arg("parameter"), "Find states with a particular parameter"); } - py::class_, std::shared_ptr>> detModel(m, ("_SparseDeterministic" + vtSuffix + "Model").c_str(), "Deterministic sparse model", model) - ; - py::class_, std::shared_ptr>> nondetModel(m, ("_SparseNondeterministic" + vtSuffix + "Model").c_str(), "Nondeterministic sparse model", model) - ; + py::class_, std::shared_ptr>> detModel( + m, ("_SparseDeterministic" + vtSuffix + "Model").c_str(), "Deterministic sparse model", model); + py::class_, std::shared_ptr>> nondetModel( + m, ("_SparseNondeterministic" + vtSuffix + "Model").c_str(), "Nondeterministic sparse model", model); - py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Dtmc").c_str(), "DTMC in sparse representation", detModel) + py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Dtmc").c_str(), "DTMC in sparse representation", + detModel) .def(py::init>(), py::arg("other_model")) .def(py::init const&>(), py::arg("components")) - .def("__str__", &getModelInfoPrinter) - ; - py::class_, std::shared_ptr>> mdp(m, ("Sparse" + vtSuffix + "Mdp").c_str(), "MDP in sparse representation", nondetModel); + .def("__str__", &getModelInfoPrinter); + py::class_, std::shared_ptr>> mdp(m, ("Sparse" + vtSuffix + "Mdp").c_str(), "MDP in sparse representation", + nondetModel); mdp.def(py::init>(), py::arg("other_model")) - .def(py::init const&, storm::models::ModelType>(), py::arg("components"), py::arg("type")=storm::models::ModelType::Mdp) + .def(py::init const&, storm::models::ModelType>(), py::arg("components"), py::arg("type") = storm::models::ModelType::Mdp) .def_property_readonly("nondeterministic_choice_indices", [](SparseMdp const& mdp) { return mdp.getNondeterministicChoiceIndices(); }) - .def("get_nr_available_actions", [](SparseMdp const& mdp, uint64_t stateIndex) { return mdp.getNondeterministicChoiceIndices()[stateIndex+1] - mdp.getNondeterministicChoiceIndices()[stateIndex] ; }, py::arg("state")) - .def("get_choice_index", [](SparseMdp 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 const& mdp, storm::storage::Scheduler const& scheduler, bool dropUnreachableStates) { return mdp.applyScheduler(scheduler, dropUnreachableStates); } , "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true) - .def("__str__", &getModelInfoPrinter) - ; - py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Pomdp").c_str(), "POMDP in sparse representation", mdp) + .def( + "get_nr_available_actions", + [](SparseMdp const& mdp, uint64_t stateIndex) { + return mdp.getNondeterministicChoiceIndices()[stateIndex + 1] - mdp.getNondeterministicChoiceIndices()[stateIndex]; + }, + py::arg("state")) + .def( + "get_choice_index", + [](SparseMdp 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 const& mdp, storm::storage::Scheduler const& scheduler, bool dropUnreachableStates) { + return mdp.applyScheduler(scheduler, dropUnreachableStates); + }, + "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true) + .def("__str__", &getModelInfoPrinter); + py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Pomdp").c_str(), "POMDP in sparse representation", + mdp) .def(py::init>(), py::arg("other_model")) - .def(py::init const&, bool>(), py::arg("components"), py::arg("canonic_flag")=false) + .def(py::init const&, bool>(), py::arg("components"), py::arg("canonic_flag") = false) .def("__str__", &getModelInfoPrinter) .def("get_observation", &SparsePomdp::getObservation, py::arg("state")) .def_property_readonly("observations", &SparsePomdp::getObservations) .def_property_readonly("nr_observations", &SparsePomdp::getNrObservations) .def("has_observation_valuations", &SparsePomdp::hasObservationValuations) - .def_property_readonly("observation_valuations", &SparsePomdp::getObservationValuations) - ; - py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Ctmc").c_str(), "CTMC in sparse representation", detModel) + .def_property_readonly("observation_valuations", &SparsePomdp::getObservationValuations); + py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Ctmc").c_str(), "CTMC in sparse representation", + detModel) .def(py::init>(), py::arg("other_model")) .def(py::init const&>(), py::arg("components")) .def_property_readonly("exit_rates", [](SparseCtmc const& ctmc) { return ctmc.getExitRateVector(); }) .def("probability_matrix", &SparseCtmc::computeProbabilityMatrix) - .def("__str__", &getModelInfoPrinter) - ; - py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "MA").c_str(), "MA in sparse representation", nondetModel) + .def("__str__", &getModelInfoPrinter); + py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "MA").c_str(), + "MA in sparse representation", nondetModel) .def(py::init>(), py::arg("other_model")) .def(py::init const&>(), py::arg("components")) .def_property_readonly("exit_rates", [](SparseMarkovAutomaton const& ma) { return ma.getExitRates(); }) .def_property_readonly("markovian_states", [](SparseMarkovAutomaton const& ma) { return ma.getMarkovianStates(); }) - .def_property_readonly("nondeterministic_choice_indices", [](SparseMarkovAutomaton const& ma) { return ma.getNondeterministicChoiceIndices(); }) - .def("apply_scheduler", [](SparseMarkovAutomaton const& ma, storm::storage::Scheduler const& scheduler, bool dropUnreachableStates) { return ma.applyScheduler(scheduler, dropUnreachableStates); } , "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true) + .def_property_readonly("nondeterministic_choice_indices", + [](SparseMarkovAutomaton const& ma) { return ma.getNondeterministicChoiceIndices(); }) + .def( + "apply_scheduler", + [](SparseMarkovAutomaton const& ma, storm::storage::Scheduler const& scheduler, bool dropUnreachableStates) { + return ma.applyScheduler(scheduler, dropUnreachableStates); + }, + "apply scheduler", "scheduler"_a, "drop_unreachable_states"_a = true) .def("__str__", &getModelInfoPrinter) .def_property_readonly("is_closed", &SparseMarkovAutomaton::isClosed, "Check whether the MA is closed.") - .def("close", &SparseMarkovAutomaton::close, "Close the MA by applying maximal progress assumption") + .def("close", &SparseMarkovAutomaton::close, "Close the MA by applying maximal progress assumption") .def_property_readonly("has_zeno_cycle", &SparseMarkovAutomaton::containsZenoCycle, "Check whether the MA has a Zeno cycle.") - .def_property_readonly("convertible_to_ctmc", &SparseMarkovAutomaton::isConvertibleToCtmc, "Check whether the MA can be converted into a CTMC.") - .def("convert_to_ctmc", &SparseMarkovAutomaton::convertToCtmc, "Convert the MA into a CTMC.") - ; + .def_property_readonly("convertible_to_ctmc", &SparseMarkovAutomaton::isConvertibleToCtmc, + "Check whether the MA can be converted into a CTMC.") + .def("convert_to_ctmc", &SparseMarkovAutomaton::convertToCtmc, "Convert the MA into a CTMC."); - py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Smg").c_str(), "SMG in sparse representation", nondetModel) + py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "Smg").c_str(), "SMG in sparse representation", + nondetModel) .def(py::init>(), py::arg("other_model")) .def(py::init const&>(), py::arg("components")) .def("get_state_player_indications", &SparseSmg::getStatePlayerIndications, "Get for each state its corresponding player") - .def("get_player_of_state", &SparseSmg::getPlayerOfState, py::arg("state"), "Get player for the given state") - ; + .def("get_player_of_state", &SparseSmg::getPlayerOfState, py::arg("state"), "Get player for the given state"); py::class_>(m, ("Sparse" + vtSuffix + "RewardModel").c_str(), "Reward structure for sparse models") .def(py::init> const&, std::optional> const&, - std::optional> const&>(), py::arg("optional_state_reward_vector") = std::nullopt, - py::arg("optional_state_action_reward_vector") = std::nullopt, py::arg("optional_transition_reward_matrix") = std::nullopt) + std::optional> const&>(), + py::arg("optional_state_reward_vector") = std::nullopt, py::arg("optional_state_action_reward_vector") = std::nullopt, + py::arg("optional_transition_reward_matrix") = std::nullopt) .def_property_readonly("has_state_rewards", &SparseRewardModel::hasStateRewards) .def_property_readonly("has_state_action_rewards", &SparseRewardModel::hasStateActionRewards) .def_property_readonly("has_transition_rewards", &SparseRewardModel::hasTransitionRewards) - .def_property_readonly("transition_rewards", [](SparseRewardModel& rewardModel) {return rewardModel.getTransitionRewardMatrix();}) - .def_property_readonly("state_rewards", [](SparseRewardModel& rewardModel) {return rewardModel.getStateRewardVector();}) - .def("get_state_reward", [](SparseRewardModel& rewardModel, uint64_t state) {return rewardModel.getStateReward(state);}) - .def("set_state_reward", [](SparseRewardModel& rewardModel, uint64_t state, ValueType const& value) {return rewardModel.setStateReward(state, value);}) - .def("get_zero_reward_states", &SparseRewardModel::template getStatesWithZeroReward, "get states where all rewards are zero", py::arg("transition_matrix")) - .def("get_state_action_reward", [](SparseRewardModel& rewardModel, uint64_t action_index) {return rewardModel.getStateActionReward(action_index);}) - .def_property_readonly("state_action_rewards", [](SparseRewardModel& rewardModel) {return rewardModel.getStateActionRewardVector();}) - .def("reduce_to_state_based_rewards", [](SparseRewardModel& rewardModel, storm::storage::SparseMatrix 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("transition_rewards", [](SparseRewardModel& rewardModel) { return rewardModel.getTransitionRewardMatrix(); }) + .def_property_readonly("state_rewards", [](SparseRewardModel& rewardModel) { return rewardModel.getStateRewardVector(); }) + .def("get_state_reward", [](SparseRewardModel& rewardModel, uint64_t state) { return rewardModel.getStateReward(state); }) + .def("set_state_reward", + [](SparseRewardModel& rewardModel, uint64_t state, ValueType const& value) { return rewardModel.setStateReward(state, value); }) + .def("get_zero_reward_states", &SparseRewardModel::template getStatesWithZeroReward, "get states where all rewards are zero", + py::arg("transition_matrix")) + .def("get_state_action_reward", + [](SparseRewardModel& rewardModel, uint64_t action_index) { return rewardModel.getStateActionReward(action_index); }) + .def_property_readonly("state_action_rewards", [](SparseRewardModel& rewardModel) { return rewardModel.getStateActionRewardVector(); }) + .def( + "reduce_to_state_based_rewards", + [](SparseRewardModel& rewardModel, storm::storage::SparseMatrix const& transitions, bool onlyStateRewards) { + return rewardModel.reduceToStateBasedRewards(transitions, onlyStateRewards); + }, + py::arg("transition_matrix"), py::arg("only_state_rewards"), "Reduce to state-based rewards"); } // Bindings for symbolic models template void define_symbolic_model(py::module& m, std::string vt_suffix) { - - py::class_, std::shared_ptr>, ModelBase> model(m, ("_Symbolic"+vt_suffix+"Model").c_str(), "A probabilistic model in a symbolic representation"); - model.def_property_readonly("reward_models", [](SymbolicModel& model) {return model.getRewardModels(); }, "Reward models") + py::class_, std::shared_ptr>, ModelBase> model( + m, ("_Symbolic" + vt_suffix + "Model").c_str(), "A probabilistic model in a symbolic representation"); + model.def_property_readonly( + "reward_models", [](SymbolicModel& model) { return model.getRewardModels(); }, "Reward models") .def_property_readonly("dd_manager", &SymbolicModel::getManager, "dd manager") - .def_property_readonly("reachable_states", &SymbolicModel::getReachableStates, "reachable states as DD") + .def_property_readonly("reachable_states", &SymbolicModel::getReachableStates, "reachable states as DD") .def_property_readonly("initial_states", &SymbolicModel::getInitialStates, "initial states as DD") - .def("get_states", [](SymbolicModel const& model, storm::expressions::Expression const& expr) {return model.getStates(expr);}, py::arg("expression"), "Get states that are described by the expression") - .def("compute_depth", [](SymbolicModel const& model) {return storm::utility::dd::computeReachableStates(model.getInitialStates(), model.getQualitativeTransitionMatrix(false), model.getRowVariables(), model.getColumnVariables()).second;}, "Computes the depth of the model, i.e., the distance to the node with the largest minimal distance from the initial states") + .def( + "get_states", [](SymbolicModel const& model, storm::expressions::Expression const& expr) { return model.getStates(expr); }, + py::arg("expression"), "Get states that are described by the expression") + .def( + "compute_depth", + [](SymbolicModel const& model) { + return storm::utility::dd::computeReachableStates(model.getInitialStates(), model.getQualitativeTransitionMatrix(false), + model.getRowVariables(), model.getColumnVariables()) + .second; + }, + "Computes the depth of the model, i.e., the distance to the node with the largest minimal distance from the initial states") .def("reduce_to_state_based_rewards", &SymbolicModel::reduceToStateBasedRewards) - .def("__str__", &getModelInfoPrinter) - ; + .def("__str__", &getModelInfoPrinter); if constexpr (std::is_same_v) { - model.def("get_parameters", &SymbolicModel::getParameters, "Get parameters") - ; + model.def("get_parameters", &SymbolicModel::getParameters, "Get parameters"); } - py::class_, std::shared_ptr>>(m, ("Symbolic"+vt_suffix+"Dtmc").c_str(), "DTMC in symbolic representation", model) - .def("__str__", &getModelInfoPrinter) - ; - py::class_, std::shared_ptr>>(m, ("Symbolic"+vt_suffix+"Mdp").c_str(), "MDP in symbolic representation", model) - .def("__str__", &getModelInfoPrinter) - ; - py::class_, std::shared_ptr>>(m, ("Symbolic"+vt_suffix+"Ctmc").c_str(), "CTMC in symbolic representation", model) - .def("__str__", &getModelInfoPrinter) - ; - py::class_, std::shared_ptr>>(m, ("Symbolic"+vt_suffix+"MA").c_str(), "MA in symbolic representation", model) - .def("__str__", &getModelInfoPrinter) - ; + py::class_, std::shared_ptr>>(m, ("Symbolic" + vt_suffix + "Dtmc").c_str(), + "DTMC in symbolic representation", model) + .def("__str__", &getModelInfoPrinter); + py::class_, std::shared_ptr>>(m, ("Symbolic" + vt_suffix + "Mdp").c_str(), + "MDP in symbolic representation", model) + .def("__str__", &getModelInfoPrinter); + py::class_, std::shared_ptr>>(m, ("Symbolic" + vt_suffix + "Ctmc").c_str(), + "CTMC in symbolic representation", model) + .def("__str__", &getModelInfoPrinter); + py::class_, std::shared_ptr>>( + m, ("Symbolic" + vt_suffix + "MA").c_str(), "MA in symbolic representation", model) + .def("__str__", &getModelInfoPrinter); - py::class_>(m, ("Symbolic"+vt_suffix+"RewardModel").c_str(), "Reward structure for symbolic models") + py::class_>(m, ("Symbolic" + vt_suffix + "RewardModel").c_str(), "Reward structure for symbolic models") .def_property_readonly("has_state_rewards", &SymbolicRewardModel::hasStateRewards) .def_property_readonly("has_state_action_rewards", &SymbolicRewardModel::hasStateActionRewards) - .def_property_readonly("has_transition_rewards", &SymbolicRewardModel::hasTransitionRewards) - ; + .def_property_readonly("has_transition_rewards", &SymbolicRewardModel::hasTransitionRewards); } - template void define_sparse_model(py::module& m, std::string const& vt_suffix); template void define_sparse_model(py::module& m, std::string const& vt_suffix); template void define_sparse_model(py::module& m, std::string const& vt_suffix); diff --git a/src/storage/model_components.cpp b/src/storage/model_components.cpp index 9f46bbe874..8554922a5e 100644 --- a/src/storage/model_components.cpp +++ b/src/storage/model_components.cpp @@ -3,59 +3,61 @@ #include "storm/adapters/IntervalAdapter.h" #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/models/symbolic/StandardRewardModel.h" -#include "storm/storage/sparse/ModelComponents.h" -#include "storm/storage/SparseMatrix.h" #include "storm/models/sparse/StateLabeling.h" +#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/storage/BitVector.h" - +#include "storm/storage/SparseMatrix.h" +#include "storm/storage/sparse/ModelComponents.h" using StateLabeling = storm::models::sparse::StateLabeling; using BitVector = storm::storage::BitVector; -template using SparseMatrix = storm::storage::SparseMatrix; -template using SparseRewardModel = storm::models::sparse::StandardRewardModel; - -template using SparseModelComponents = storm::storage::sparse::ModelComponents; +template +using SparseMatrix = storm::storage::SparseMatrix; +template +using SparseRewardModel = storm::models::sparse::StandardRewardModel; +template +using SparseModelComponents = storm::storage::sparse::ModelComponents; template void define_sparse_model_components(py::module& m, std::string const& vtSuffix) { + py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "ModelComponents").c_str(), + "Components required for building a sparse model") - py::class_, std::shared_ptr>>(m, ("Sparse" + vtSuffix + "ModelComponents").c_str(), "Components required for building a sparse model") - - .def(py::init const&, StateLabeling const&, std::unordered_map> const&, - bool, boost::optional const&, boost::optional> const&>(), - py::arg("transition_matrix") = SparseMatrix(), - py::arg("state_labeling") = storm::models::sparse::StateLabeling(), - py::arg("reward_models") = std::unordered_map>(), py::arg("rate_transitions") = false, - py::arg("markovian_states") = boost::none, py::arg("player1_matrix") = boost::none) + .def(py::init const&, StateLabeling const&, std::unordered_map> const&, bool, + boost::optional const&, boost::optional> const&>(), + py::arg("transition_matrix") = SparseMatrix(), py::arg("state_labeling") = storm::models::sparse::StateLabeling(), + py::arg("reward_models") = std::unordered_map>(), 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::transitionMatrix, "The transition matrix") .def_readwrite("state_labeling", &SparseModelComponents::stateLabeling, "The state labeling") .def_readwrite("reward_models", &SparseModelComponents::rewardModels, "Reward models associated with the model") .def_readwrite("choice_labeling", &SparseModelComponents::choiceLabeling, "A list that stores a labeling for each choice") - .def_readwrite("state_valuations", &SparseModelComponents::stateValuations, "A list that stores for each state to which variable valuation it belongs") - .def_readwrite("choice_origins", &SparseModelComponents::choiceOrigins, "Stores for each choice from which parts of the input model description it originates") + .def_readwrite("state_valuations", &SparseModelComponents::stateValuations, + "A list that stores for each state to which variable valuation it belongs") + .def_readwrite("choice_origins", &SparseModelComponents::choiceOrigins, + "Stores for each choice from which parts of the input model description it originates") // POMDP specific components .def_readwrite("observability_classes", &SparseModelComponents::observabilityClasses, "The POMDP observations") // Continuous time specific components (CTMCs, Markov Automata): - .def_readwrite("rate_transitions", &SparseModelComponents::rateTransitions, "True iff the transition values (for Markovian choices) are interpreted as rates") - .def_readwrite("exit_rates", &SparseModelComponents::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::markovianStates, "A list that stores which states are Markovian (only for Markov Automata)") + .def_readwrite("rate_transitions", &SparseModelComponents::rateTransitions, + "True iff the transition values (for Markovian choices) are interpreted as rates") + .def_readwrite("exit_rates", &SparseModelComponents::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::markovianStates, + "A list that stores which states are Markovian (only for Markov Automata)") // Stochastic two player game specific components: .def_readwrite("player1_matrix", &SparseModelComponents::player1Matrix, "Matrix of player 1 choices (needed for stochastic two player games") // Stochastic multiplayer game specific components: - .def_readwrite("state_player_indications", &SparseModelComponents::statePlayerIndications, "The vector mapping states to player indices") - ; - + .def_readwrite("state_player_indications", &SparseModelComponents::statePlayerIndications, "The vector mapping states to player indices"); } - template void define_sparse_model_components(py::module& m, std::string const& vtSuffix); template void define_sparse_model_components(py::module& m, std::string const& vtSuffix); template void define_sparse_model_components(py::module& m, std::string const& vtSuffix); diff --git a/src/storage/prism.cpp b/src/storage/prism.cpp index 0906ff26da..ffa6b67288 100644 --- a/src/storage/prism.cpp +++ b/src/storage/prism.cpp @@ -1,128 +1,139 @@ #include "prism.h" -#include -#include #include -#include +#include #include -#include "src/helpers.h" -#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include -#include -#include -#include -#include -#include "storm/exceptions/NotSupportedException.h" -#include "storm/exceptions/NotImplementedException.h" -#include -#include "storm/exceptions/InvalidTypeException.h" -#include "storm/exceptions/InvalidStateException.h" -#include "storm/exceptions/InvalidAccessException.h" +#include #include -#include - +#include "src/helpers.h" +#include "storm/exceptions/InvalidAccessException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/InvalidTypeException.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/exceptions/NotSupportedException.h" using namespace storm::prism; -template +template void define_stateGeneration(py::module& m); void define_prism(py::module& m) { py::class_> program(m, "PrismProgram", "A Prism Program"); program.def_property_readonly("constants", &Program::getConstants, "Get Program Constants") - .def_property_readonly("global_boolean_variables", &Program::getGlobalBooleanVariables, "Retrieves the global boolean variables of the program") - .def_property_readonly("global_integer_variables", &Program::getGlobalIntegerVariables, "Retrieves the global integer variables of the program") - .def_property_readonly("variables", [](Program const& prog) {return prog.getAllExpressionVariables(true);}, "Retrieves all expression variables (including constants) of the program") - .def("get_variables", &Program::getAllExpressionVariables, py::arg("include_constants") = true, "Get all expression variables (and constants) used by the program") - .def_property_readonly("nr_modules", &storm::prism::Program::getNumberOfModules, "Number of modules") - .def_property_readonly("modules", &storm::prism::Program::getModules, "Modules in the program") - .def_property_readonly("model_type", &storm::prism::Program::getModelType, "Model type") - .def_property_readonly("has_undefined_constants", &storm::prism::Program::hasUndefinedConstants, "Flag if program has undefined constants") - .def_property_readonly("undefined_constants_are_graph_preserving", &storm::prism::Program::undefinedConstantsAreGraphPreserving, "Flag if the undefined constants do not change the graph structure") - .def("get_undefined_constants", &Program::getUndefinedConstants, "Collect the undefined constants") - .def("substitute_constants", &Program::substituteConstants, "Substitute constants within program") - .def("substitute_formulas", &Program::substituteFormulas, "Substitute formulas within program") - .def("define_constants", &Program::defineUndefinedConstants, "Define constants") - .def("restrict_commands", &Program::restrictCommands, "Restrict commands") - .def("simplify", &Program::simplify, "Simplify") - .def("has_label", &Program::hasLabel, py::arg("name")) - .def("substitute_nonstandard_predicates", &Program::substituteNonStandardPredicates, "Remove nonstandard predicates from the prism program") - .def("used_constants",&Program::usedConstants, "Compute Used Constants") - .def("label_unlabelled_commands", &Program::labelUnlabelledCommands, "Label unlabelled commands", py::arg("name_suggestions")) - .def("replace_variable_initialization_by_init_expression", &Program::replaceVariableInitializationByInitExpression, "Replaces initializations from the individual variables to a init expression.") - .def("replace_constant_by_variable", &Program::replaceConstantByVariable, py::arg("constant"), py::arg("lower_bound"), py::arg("upper_bound"), py::arg("observable") = true, "Operation to take a constant and make it into a global variable (ranging from lower to upper bound).") - .def_property_readonly("has_initial_states_expression", &Program::hasInitialConstruct, "Is an initial states expression given.") - .def_property_readonly("initial_states_expression", [](Program const& p) {return p.hasInitialConstruct() ? std::make_optional(p.getInitialStatesExpression()) : std::nullopt;}, "Get the initial states expression, or none, if none exists") - .def("update_initial_states_expression", &Program::updateInitialStatesExpression, py::arg("new_expression"), "Replace initial expression. Can only be called if initial expression exists.") - .def("has_constant", &Program::hasConstant, py::arg("name")) - .def("get_constant", &Program::getConstant, py::arg("name"), "Requires that the program has a constant with this name") - .def("has_reward_model", [](Program const& p, std::string const& name) {return p.hasRewardModel(name);}, py::arg("name"), "Is a reward model with the specified name defined?") - .def_property_readonly("reward_models", &Program::getRewardModels, "The defined reward models") - .def("get_module", [](Program const& prog, std::string const& name) {return prog.getModule(name);}, py::arg("module_name")) - // TODO the following is a duplicate and should be deprecated. - .def_property_readonly("is_deterministic_model", &Program::isDeterministicModel, "Does the program describe a deterministic model?") - .def_property_readonly("expression_manager", &Program::getManager, "Get the expression manager for expressions in this program") - .def("get_synchronizing_action_indices", &Program::getSynchronizingActionIndices, "Get the synchronizing action indices") - .def("get_action_name", &Program::getActionName, py::arg("action_index"), "Get the action name for a given action index") - .def("get_module_indices_by_action_index", &Program::getModuleIndicesByActionIndex, py::arg("action_index"), "get all modules that have a particular action index") - .def_property_readonly("number_of_unlabeled_commands", &Program::getNumberOfUnlabeledCommands, "Gets the number of commands that are not labelled") - .def("flatten", &Program::flattenModules, "Put program into a single module", py::arg("smt_factory")=std::shared_ptr(new storm::utility::solver::SmtSolverFactory())) - .def("to_jani", [](storm::prism::Program const& program, std::vector const& properties, bool allVariablesGlobal, std::string suffix) { - return program.toJani(properties, allVariablesGlobal, suffix); - }, "Transform to Jani program", py::arg("properties"), py::arg("all_variables_global") = true, py::arg("suffix") = "") - .def("__str__", &streamToString) - .def("get_label_expression", [](storm::prism::Program const& program, std::string const& label){ - return program.getLabelExpression(label); - }, "Get the expression of the given label.", py::arg("label")) - .def_property_readonly("labels", &Program::getLabels, "Get all labels in the program") - ; + .def_property_readonly("global_boolean_variables", &Program::getGlobalBooleanVariables, "Retrieves the global boolean variables of the program") + .def_property_readonly("global_integer_variables", &Program::getGlobalIntegerVariables, "Retrieves the global integer variables of the program") + .def_property_readonly( + "variables", [](Program const& prog) { return prog.getAllExpressionVariables(true); }, + "Retrieves all expression variables (including constants) of the program") + .def("get_variables", &Program::getAllExpressionVariables, py::arg("include_constants") = true, + "Get all expression variables (and constants) used by the program") + .def_property_readonly("nr_modules", &storm::prism::Program::getNumberOfModules, "Number of modules") + .def_property_readonly("modules", &storm::prism::Program::getModules, "Modules in the program") + .def_property_readonly("model_type", &storm::prism::Program::getModelType, "Model type") + .def_property_readonly("has_undefined_constants", &storm::prism::Program::hasUndefinedConstants, "Flag if program has undefined constants") + .def_property_readonly("undefined_constants_are_graph_preserving", &storm::prism::Program::undefinedConstantsAreGraphPreserving, + "Flag if the undefined constants do not change the graph structure") + .def("get_undefined_constants", &Program::getUndefinedConstants, "Collect the undefined constants") + .def("substitute_constants", &Program::substituteConstants, "Substitute constants within program") + .def("substitute_formulas", &Program::substituteFormulas, "Substitute formulas within program") + .def("define_constants", &Program::defineUndefinedConstants, "Define constants") + .def("restrict_commands", &Program::restrictCommands, "Restrict commands") + .def("simplify", &Program::simplify, "Simplify") + .def("has_label", &Program::hasLabel, py::arg("name")) + .def("substitute_nonstandard_predicates", &Program::substituteNonStandardPredicates, "Remove nonstandard predicates from the prism program") + .def("used_constants", &Program::usedConstants, "Compute Used Constants") + .def("label_unlabelled_commands", &Program::labelUnlabelledCommands, "Label unlabelled commands", py::arg("name_suggestions")) + .def("replace_variable_initialization_by_init_expression", &Program::replaceVariableInitializationByInitExpression, + "Replaces initializations from the individual variables to a init expression.") + .def("replace_constant_by_variable", &Program::replaceConstantByVariable, py::arg("constant"), py::arg("lower_bound"), py::arg("upper_bound"), + py::arg("observable") = true, "Operation to take a constant and make it into a global variable (ranging from lower to upper bound).") + .def_property_readonly("has_initial_states_expression", &Program::hasInitialConstruct, "Is an initial states expression given.") + .def_property_readonly( + "initial_states_expression", + [](Program const& p) { return p.hasInitialConstruct() ? std::make_optional(p.getInitialStatesExpression()) : std::nullopt; }, + "Get the initial states expression, or none, if none exists") + .def("update_initial_states_expression", &Program::updateInitialStatesExpression, py::arg("new_expression"), + "Replace initial expression. Can only be called if initial expression exists.") + .def("has_constant", &Program::hasConstant, py::arg("name")) + .def("get_constant", &Program::getConstant, py::arg("name"), "Requires that the program has a constant with this name") + .def( + "has_reward_model", [](Program const& p, std::string const& name) { return p.hasRewardModel(name); }, py::arg("name"), + "Is a reward model with the specified name defined?") + .def_property_readonly("reward_models", &Program::getRewardModels, "The defined reward models") + .def( + "get_module", [](Program const& prog, std::string const& name) { return prog.getModule(name); }, py::arg("module_name")) + // TODO the following is a duplicate and should be deprecated. + .def_property_readonly("is_deterministic_model", &Program::isDeterministicModel, "Does the program describe a deterministic model?") + .def_property_readonly("expression_manager", &Program::getManager, "Get the expression manager for expressions in this program") + .def("get_synchronizing_action_indices", &Program::getSynchronizingActionIndices, "Get the synchronizing action indices") + .def("get_action_name", &Program::getActionName, py::arg("action_index"), "Get the action name for a given action index") + .def("get_module_indices_by_action_index", &Program::getModuleIndicesByActionIndex, py::arg("action_index"), + "get all modules that have a particular action index") + .def_property_readonly("number_of_unlabeled_commands", &Program::getNumberOfUnlabeledCommands, "Gets the number of commands that are not labelled") + .def("flatten", &Program::flattenModules, "Put program into a single module", + py::arg("smt_factory") = std::shared_ptr(new storm::utility::solver::SmtSolverFactory())) + .def( + "to_jani", + [](storm::prism::Program const& program, std::vector const& properties, bool allVariablesGlobal, std::string suffix) { + return program.toJani(properties, allVariablesGlobal, suffix); + }, + "Transform to Jani program", py::arg("properties"), py::arg("all_variables_global") = true, py::arg("suffix") = "") + .def("__str__", &streamToString) + .def( + "get_label_expression", [](storm::prism::Program const& program, std::string const& label) { return program.getLabelExpression(label); }, + "Get the expression of the given label.", py::arg("label")) + .def_property_readonly("labels", &Program::getLabels, "Get all labels in the program"); py::class_ module(m, "PrismModule", "A module in a Prism program"); - module.def_property_readonly("commands", [](Module const& module) {return module.getCommands();}, "Commands in the module") - .def_property_readonly("name", &Module::getName, "Name of the module") - .def_property_readonly("integer_variables", &Module::getIntegerVariables, "All integer Variables of this module") - .def_property_readonly("boolean_variables", &Module::getBooleanVariables, "All boolean Variables of this module") - .def("get_integer_variable", &Module::getIntegerVariable, py::arg("variable_name")) - .def("get_boolean_variable", &Module::getBooleanVariable, py::arg("variable_name")) - .def("get_command_indices_by_action_index", &Module::getCommandIndicesByActionIndex, py::arg("action_index")) - .def("__str__", &streamToString) - ; + module.def_property_readonly( + "commands", [](Module const& module) { return module.getCommands(); }, "Commands in the module") + .def_property_readonly("name", &Module::getName, "Name of the module") + .def_property_readonly("integer_variables", &Module::getIntegerVariables, "All integer Variables of this module") + .def_property_readonly("boolean_variables", &Module::getBooleanVariables, "All boolean Variables of this module") + .def("get_integer_variable", &Module::getIntegerVariable, py::arg("variable_name")) + .def("get_boolean_variable", &Module::getBooleanVariable, py::arg("variable_name")) + .def("get_command_indices_by_action_index", &Module::getCommandIndicesByActionIndex, py::arg("action_index")) + .def("__str__", &streamToString); py::class_ command(m, "PrismCommand", "A command in a Prism program"); command.def_property_readonly("global_index", &Command::getGlobalIndex, "Get global index") - .def_property_readonly("labeled", &Command::isLabeled, "Is the command labeled") - .def_property_readonly("action_index", &Command::getActionIndex, "What is the action index of the command") - .def_property_readonly("guard_expression", &Command::getGuardExpression, "Get guard expression") - .def_property_readonly("is_labeled", &Command::isLabeled, "Retrieves whether the command possesses a synchronization label") - .def_property_readonly("action_name", &Command::getActionName, "Retrieves the action name of this command") - .def_property_readonly("updates", [](Command const& command) { - return command.getUpdates(); - }, "Updates in the command") - .def("__str__", &streamToString) - ; + .def_property_readonly("labeled", &Command::isLabeled, "Is the command labeled") + .def_property_readonly("action_index", &Command::getActionIndex, "What is the action index of the command") + .def_property_readonly("guard_expression", &Command::getGuardExpression, "Get guard expression") + .def_property_readonly("is_labeled", &Command::isLabeled, "Retrieves whether the command possesses a synchronization label") + .def_property_readonly("action_name", &Command::getActionName, "Retrieves the action name of this command") + .def_property_readonly( + "updates", [](Command const& command) { return command.getUpdates(); }, "Updates in the command") + .def("__str__", &streamToString); py::class_ update(m, "PrismUpdate", "An update in a Prism command"); update.def(py::init const&>()) - .def_property_readonly("assignments", [](Update const& update) { - return update.getAssignments(); - }, "Assignments in the update") - .def_property_readonly("probability_expression", &Update::getLikelihoodExpression, "The probability expression for this update") - .def_property_readonly("global_index", &Update::getGlobalIndex, "Retrieves the global index of the update, that is, a unique index over all modules") - .def("substitute", &Update::substitute, "Substitutes all identifiers in the update according to the given map") - .def("simplify", &Update::simplify, "Simplifies the update in various ways (also removes identity assignments)") - .def("get_assignment", &Update::getAssignment, py::arg("variable_name"), "Retrieves a reference to the assignment for the variable with the given name") - .def("get_as_variable_to_expression_map", &Update::getAsVariableToExpressionMap, "Creates a mapping representation of this update") - .def("__str__", &streamToString) - ; + .def_property_readonly( + "assignments", [](Update const& update) { return update.getAssignments(); }, "Assignments in the update") + .def_property_readonly("probability_expression", &Update::getLikelihoodExpression, "The probability expression for this update") + .def_property_readonly("global_index", &Update::getGlobalIndex, "Retrieves the global index of the update, that is, a unique index over all modules") + .def("substitute", &Update::substitute, "Substitutes all identifiers in the update according to the given map") + .def("simplify", &Update::simplify, "Simplifies the update in various ways (also removes identity assignments)") + .def("get_assignment", &Update::getAssignment, py::arg("variable_name"), "Retrieves a reference to the assignment for the variable with the given name") + .def("get_as_variable_to_expression_map", &Update::getAsVariableToExpressionMap, "Creates a mapping representation of this update") + .def("__str__", &streamToString); py::class_ assignment(m, "PrismAssignment", "An assignment in prism"); assignment.def(py::init()) - .def_property_readonly("variable", &Assignment::getVariable, "Variable that is updated") - .def_property_readonly("expression", &Assignment::getExpression, "Expression for the update") - .def("__str__", &streamToString) - ; + .def_property_readonly("variable", &Assignment::getVariable, "Variable that is updated") + .def_property_readonly("expression", &Assignment::getExpression, "Expression for the update") + .def("__str__", &streamToString); py::class_