From 45c6415eaa959cffb1e3a592469af28e0ddf9539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Schr=C3=B6er?= Date: Fri, 13 Dec 2019 19:29:28 +0100 Subject: [PATCH] StateGenerator: expose choice origins --- src/storage/prism.cpp | 60 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/storage/prism.cpp b/src/storage/prism.cpp index 75cd9b3..0439b81 100644 --- a/src/storage/prism.cpp +++ b/src/storage/prism.cpp @@ -164,13 +164,39 @@ class ValuationMapping { } }; +template +class GeneratorChoice { + public: + typedef std::vector origins_type; + typedef std::vector> distribution_type; + + origins_type origins; + distribution_type distribution; + + private: + static origins_type getOriginsVector(storm::generator::Choice &choice) { + auto originsSet = boost::any_cast>(&choice.getOriginData()); + if (originsSet != nullptr) { + return origins_type(originsSet->begin(), originsSet->end()); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, + "Type of choice origin data (aka " + << choice.getOriginData().type().name() + << ") is not implemented."); + } + } + + public: + GeneratorChoice(storm::generator::Choice &choice) : origins(getOriginsVector(choice)), distribution(choice.begin(), choice.end()) {} +}; + template class StateGenerator { + public: typedef std::unordered_map IdToStateMap; - typedef std::vector> distribution_type; - typedef distribution_type choice_type; // currently we just collapse choices into distributions - typedef std::vector choice_list_type; + typedef std::vector> choice_list_type; + private: storm::prism::Program const& program; storm::generator::PrismNextStateGenerator generator; std::function stateToIdCallback; @@ -182,8 +208,14 @@ class StateGenerator { IdToStateMap stateMap; boost::optional currentStateIndex; + static storm::generator::NextStateGeneratorOptions makeNextStateGeneratorOptions() { + storm::generator::NextStateGeneratorOptions options; + options.setBuildChoiceOrigins(true); + return options; + } + public: - StateGenerator(storm::prism::Program const& program_) : program(program_), generator(program_), stateStorage(generator.getStateSize()) { + StateGenerator(storm::prism::Program const& program_) : program(program_), generator(program_, StateGenerator::makeNextStateGeneratorOptions()), stateStorage(generator.getStateSize()) { stateToIdCallback = [this] (storm::generator::CompressedState const& state) -> StateType { StateType newIndex = stateStorage.getNumberOfStates(); std::pair indexBucketPair = stateStorage.stateToId.findOrAddAndGetBucket(state, newIndex); @@ -237,8 +269,8 @@ class StateGenerator { } choice_list_type choices_result; auto behavior = generator.expand(stateToIdCallback); - for (auto choice : behavior.getChoices()) { - choices_result.push_back(choice_type(choice.begin(), choice.end())); + for (auto& choice : behavior.getChoices()) { + choices_result.push_back(GeneratorChoice(choice)); } return choices_result; @@ -255,6 +287,20 @@ void define_stateGeneration(py::module& m) { .def_readonly("rational_values", &ValuationMapping::rationalValues) .def("__str__", &ValuationMapping::toString); + py::class_, + std::shared_ptr>> + generator_choice(m, "GeneratorChoice", R"doc( + Representation of a choice taken by the generator. + + :ivar origins: A list of command ids that generated this choice. + :vartype origins: List[int] + :ivar distribution: The probability distribution of this choice. + :vartype distribution: List[Pair[StateId, Probability]] + )doc"); + generator_choice + .def_readonly("origins", &GeneratorChoice::origins) + .def_readonly("distribution", &GeneratorChoice::distribution); + py::class_, std::shared_ptr>> state_generator(m, "StateGenerator", R"doc( Interactively explore states using Storm's PrismNextStateGenerator. @@ -285,6 +331,6 @@ void define_stateGeneration(py::module& m) { .def("expand", &StateGenerator::expand, R"doc( Expand the currently loaded state and return its successors. - :rtype: [[(state_id, probability)]] + :rtype: [GeneratorChoice] )doc"); }