#include "storm/models/sparse/NondeterministicModel.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/adapters/CarlAdapter.h" #include "storm/exceptions/InvalidOperationException.h" namespace storm { namespace models { namespace sparse { template NondeterministicModel::NondeterministicModel(storm::models::ModelType const& modelType, storm::storage::SparseMatrix const& transitionMatrix, storm::models::sparse::StateLabeling const& stateLabeling, std::unordered_map const& rewardModels, boost::optional const& optionalChoiceLabeling) : Model(modelType, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) { // Intentionally left empty. } template NondeterministicModel::NondeterministicModel(storm::models::ModelType const& modelType, storm::storage::SparseMatrix&& transitionMatrix, storm::models::sparse::StateLabeling&& stateLabeling, std::unordered_map&& rewardModels, boost::optional&& optionalChoiceLabeling) : Model(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) { // Intentionally left empty. } template uint_fast64_t NondeterministicModel::getNumberOfChoices() const { return this->getTransitionMatrix().getRowCount(); } template std::vector const& NondeterministicModel::getNondeterministicChoiceIndices() const { return this->getTransitionMatrix().getRowGroupIndices(); } template uint_fast64_t NondeterministicModel::getNumberOfChoices(uint_fast64_t state) const { auto indices = this->getNondeterministicChoiceIndices(); return indices[state+1] - indices[state]; } template void NondeterministicModel::reduceToStateBasedRewards() { for (auto& rewardModel : this->getRewardModels()) { rewardModel.second.reduceToStateBasedRewards(this->getTransitionMatrix(), false); } } template void NondeterministicModel::printModelInformationToStream(std::ostream& out) const { this->printModelInformationHeaderToStream(out); out << "Choices: \t" << this->getNumberOfChoices() << std::endl; this->printModelInformationFooterToStream(out); } template void NondeterministicModel::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector const* firstValue, std::vector const* secondValue, std::vector const* stateColoring, std::vector const* colors, std::vector* scheduler, bool finalizeOutput) const { Model::writeDotToStream(outStream, includeLabeling, subsystem, firstValue, secondValue, stateColoring, colors, scheduler, false); // Write the probability distributions for all the states. for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) { uint_fast64_t rowCount = this->getNondeterministicChoiceIndices()[state + 1] - this->getNondeterministicChoiceIndices()[state]; bool highlightChoice = true; // For this, we need to iterate over all available nondeterministic choices in the current state. for (uint_fast64_t choice = 0; choice < rowCount; ++choice) { uint_fast64_t rowIndex = this->getNondeterministicChoiceIndices()[state] + choice; typename storm::storage::SparseMatrix::const_rows row = this->getTransitionMatrix().getRow(rowIndex); if (scheduler != nullptr) { // If the scheduler picked the current choice, we will not make it dotted, but highlight it. if ((*scheduler)[state] == choice) { highlightChoice = true; } else { highlightChoice = false; } } // For each nondeterministic choice, we draw an arrow to an intermediate node to better display // the grouping of transitions. outStream << "\t\"" << state << "c" << choice << "\" [shape = \"point\""; // If we were given a scheduler to highlight, we do so now. if (scheduler != nullptr) { if (highlightChoice) { outStream << ", fillcolor=\"red\""; } } outStream << "];" << std::endl; outStream << "\t" << state << " -> \"" << state << "c" << choice << "\" [ label= \"" << rowIndex << "\""; // If we were given a scheduler to highlight, we do so now. if (scheduler != nullptr) { if (highlightChoice) { outStream << ", color=\"red\", penwidth = 2"; } else { outStream << ", style = \"dotted\""; } } outStream << "];" << std::endl; // Now draw all probabilitic arcs that belong to this nondeterminstic choice. for (auto const& transition : row) { if (subsystem == nullptr || subsystem->get(transition.getColumn())) { outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ]"; // If we were given a scheduler to highlight, we do so now. if (scheduler != nullptr) { if (highlightChoice) { outStream << " [color=\"red\", penwidth = 2]"; } else { outStream << " [style = \"dotted\"]"; } } outStream << ";" << std::endl; } } } } if (finalizeOutput) { outStream << "}" << std::endl; } } template class NondeterministicModel; template class NondeterministicModel; #ifdef STORM_HAVE_CARL template class NondeterministicModel; template class NondeterministicModel>; template class NondeterministicModel; #endif } } }