Browse Source

Replaced the old choice labeling with the new one and used choice origins for the minimal command set counterexample generators

main
TimQu 10 years ago
parent
commit
6537fd8b72
  1. 3
      src/storm-dft/builder/ExplicitDFTModelBuilder.h
  2. 3
      src/storm-dft/builder/ExplicitDFTModelBuilderApprox.h
  3. 5
      src/storm/builder/ExplicitModelBuilderResult.cpp
  4. 3
      src/storm/builder/ExplicitModelBuilderResult.h
  5. 5
      src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp
  6. 4
      src/storm/builder/jit/ExplicitJitJaniModelBuilder.h
  7. 12
      src/storm/cli/entrypoints.h
  8. 251
      src/storm/counterexamples/MILPMinimalCommandSetGenerator.h
  9. 666
      src/storm/counterexamples/SMTMinimalCommandSetGenerator.h
  10. 5
      src/storm/generator/PrismNextStateGenerator.cpp
  11. 6
      src/storm/models/sparse/Ctmc.cpp
  12. 6
      src/storm/models/sparse/Ctmc.h
  13. 4
      src/storm/models/sparse/DeterministicModel.cpp
  14. 4
      src/storm/models/sparse/DeterministicModel.h
  15. 4
      src/storm/models/sparse/Dtmc.cpp
  16. 4
      src/storm/models/sparse/Dtmc.h
  17. 22
      src/storm/models/sparse/MarkovAutomaton.cpp
  18. 10
      src/storm/models/sparse/MarkovAutomaton.h
  19. 55
      src/storm/models/sparse/Mdp.cpp
  20. 15
      src/storm/models/sparse/Mdp.h
  21. 10
      src/storm/models/sparse/Model.cpp
  22. 17
      src/storm/models/sparse/Model.h
  23. 44
      src/storm/models/sparse/NondeterministicModel.cpp
  24. 19
      src/storm/models/sparse/NondeterministicModel.h
  25. 12
      src/storm/models/sparse/StochasticTwoPlayerGame.cpp
  26. 14
      src/storm/models/sparse/StochasticTwoPlayerGame.h
  27. 2
      src/storm/parser/DeterministicModelParser.cpp
  28. 2
      src/storm/parser/DirectEncodingParser.h
  29. 5
      src/storm/parser/NondeterministicModelParser.cpp
  30. 2
      src/storm/parser/NondeterministicModelParser.h
  31. 5
      src/storm/parser/SparseChoiceLabelingParser.cpp
  32. 6
      src/storm/parser/SparseChoiceLabelingParser.h
  33. 15
      src/storm/storage/sparse/ChoiceOrigins.cpp
  34. 6
      src/storm/storage/sparse/ChoiceOrigins.h
  35. 6
      src/storm/storage/sparse/PrismChoiceOrigins.cpp
  36. 88
      src/storm/transformer/StateDuplicator.h
  37. 78
      src/storm/transformer/SubsystemBuilder.h
  38. 2
      src/storm/utility/ModelInstantiator.h
  39. 45
      src/storm/utility/counterexamples.h
  40. 24
      src/storm/utility/storm.h
  41. 40
      src/test/builder/ExplicitJitJaniModelBuilderTest.cpp
  42. 24
      src/test/modelchecker/SparseDtmcParameterLiftingTest.cpp
  43. 10
      src/test/modelchecker/SparseMaPcaaModelCheckerTest.cpp
  44. 20
      src/test/modelchecker/SparseMdpParameterLiftingTest.cpp
  45. 10
      src/test/modelchecker/SparseMdpPcaaModelCheckerTest.cpp

3
src/storm-dft/builder/ExplicitDFTModelBuilder.h

@ -7,6 +7,7 @@
#include "storm/models/sparse/StateLabeling.h"
#include "storm/models/sparse/ChoiceLabeling.h"
#include "storm/models/sparse/StandardRewardModel.h"
#include "storm/models/sparse/Model.h"
#include "storm/storage/SparseMatrix.h"
@ -49,7 +50,7 @@ namespace storm {
std::vector<ValueType> exitRates;
// A vector that stores a labeling for each choice.
boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> choiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
};
const size_t INITIAL_BUCKETSIZE = 20000;

3
src/storm-dft/builder/ExplicitDFTModelBuilderApprox.h

@ -7,6 +7,7 @@
#include <limits>
#include "storm/models/sparse/StateLabeling.h"
#include "storm/models/sparse/ChoiceLabeling.h"
#include "storm/models/sparse/StandardRewardModel.h"
#include "storm/models/sparse/Model.h"
#include "storm/storage/SparseMatrix.h"
@ -51,7 +52,7 @@ namespace storm {
std::vector<ValueType> exitRates;
// A vector that stores a labeling for each choice.
boost::optional<std::vector<boost::container::flat_set<StateType>>> choiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
// A flag indicating if the model is deterministic.
bool deterministicModel;

5
src/storm/builder/ExplicitModelBuilderResult.cpp

@ -13,6 +13,11 @@ namespace storm {
ExplicitModelBuilderResult<ValueType, RewardModelType>::ExplicitModelBuilderResult(std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> model, std::shared_ptr<storm::storage::sparse::StateValuations> stateValuations,std::shared_ptr<storm::storage::sparse::ChoiceOrigins> choiceOrigins) : model(model), stateValuations(stateValuations), choiceOrigins(choiceOrigins) {
// Intentionally left empty
}
template <typename ValueType, typename RewardModelType>
bool ExplicitModelBuilderResult<ValueType, RewardModelType>::hasModel() {
return static_cast<bool>(model);
}
template <typename ValueType, typename RewardModelType>
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>>& ExplicitModelBuilderResult<ValueType, RewardModelType>::getModel() {

3
src/storm/builder/ExplicitModelBuilderResult.h

@ -11,8 +11,9 @@ namespace storm {
template<typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
class ExplicitModelBuilderResult {
public:
ExplicitModelBuilderResult(std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> model, std::shared_ptr<storm::storage::sparse::StateValuations> stateValuations,std::shared_ptr<storm::storage::sparse::ChoiceOrigins> choiceOrigins);
ExplicitModelBuilderResult(std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> model, std::shared_ptr<storm::storage::sparse::StateValuations> stateValuations = nullptr,std::shared_ptr<storm::storage::sparse::ChoiceOrigins> choiceOrigins = nullptr);
bool hasModel();
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>>& getModel();
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> const& getModel() const;

5
src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp

@ -15,7 +15,6 @@
#include "storm/storage/jani/ParallelComposition.h"
#include "storm/storage/jani/CompositionInformationVisitor.h"
#include "storm/builder/RewardModelInformation.h"
#include "storm/models/sparse/Dtmc.h"
@ -458,7 +457,7 @@ namespace storm {
}
template <typename ValueType, typename RewardModelType>
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> ExplicitJitJaniModelBuilder<ValueType, RewardModelType>::build() {
storm::builder::ExplicitModelBuilderResult<ValueType, RewardModelType> ExplicitJitJaniModelBuilder<ValueType, RewardModelType>::build() {
// (0) Assemble information about the model.
cpptempl::data_map modelData = generateModelData();
@ -506,7 +505,7 @@ namespace storm {
STORM_LOG_THROW(!error, storm::exceptions::WrongFormatException, "Model building failed. Reason: " << error.get());
// Return the constructed model.
return sparseModel;
return storm::builder::ExplicitModelBuilderResult<ValueType, RewardModelType>(sparseModel);
}
template <typename ValueType, typename RewardModelType>

4
src/storm/builder/jit/ExplicitJitJaniModelBuilder.h

@ -17,6 +17,8 @@
#include "storm/builder/BuilderOptions.h"
#include "storm/builder/jit/JitModelBuilderInterface.h"
#include "storm/builder/jit/ModelComponentsBuilder.h"
#include "storm/builder/ExplicitModelBuilderResult.h"
namespace storm {
namespace models {
@ -57,7 +59,7 @@ namespace storm {
/*!
* Builds and returns the sparse model.
*/
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> build();
storm::builder::ExplicitModelBuilderResult<ValueType, RewardModelType> build();
/*!
* Performs some checks that can help debug why the model builder does not work. Returns true if the

12
src/storm/cli/entrypoints.h

@ -311,23 +311,27 @@ namespace storm {
auto formulas = extractFormulasFromProperties(properties);
// Start by building the model.
storm::utility::Stopwatch modelBuildingWatch(true);
std::shared_ptr<storm::models::ModelBase> markovModel = buildSparseModel<ValueType>(model, formulas);
storm::builder::ExplicitModelBuilderResult<ValueType> builderResult = buildSparseModel<ValueType>(model, formulas);
modelBuildingWatch.stop();
STORM_PRINT_AND_LOG("Time for model construction: " << modelBuildingWatch << "." << std::endl << std::endl);
STORM_LOG_THROW(markovModel, storm::exceptions::UnexpectedException, "The model was not successfully built.");
// Extract the model from the result.
STORM_LOG_THROW(builderResult.hasModel(), storm::exceptions::UnexpectedException, "The model was not successfully built.");
std::shared_ptr<storm::models::ModelBase> markovModel = builderResult.getModel();
builderResult.getModel().reset();
STORM_LOG_WARN_COND(markovModel.unique(), "There are multiple references to the model. After preprocessing the model, the preprocessed as well as the original model might be stored in memory.");
// Print some information about the model.
markovModel->printModelInformationToStream(std::cout);
// Preprocess the model.
STORM_LOG_WARN_COND(builderResult.hasStateValuations() || builderResult.hasChoiceOrigins(), "state valuations and choice origins might be invalidated if the model is preprocessed..."); // TODO: check this more carefully.
BRANCH_ON_SPARSE_MODELTYPE(markovModel, markovModel, ValueType, preprocessModel, formulas);
std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel = markovModel->template as<storm::models::sparse::Model<ValueType>>();
// Finally, treat the formulas.
if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isCounterexampleSet()) {
generateCounterexamples<ValueType>(model, sparseModel, formulas);
generateCounterexamples<ValueType>(model, sparseModel, builderResult.getChoiceOrigins(), formulas);
} else if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isParameterLiftingSet()) {
STORM_LOG_THROW(storm::settings::getModule<storm::settings::modules::GeneralSettings>().isParametricSet(), storm::exceptions::InvalidSettingsException, "Invoked parameter lifting without enabling the parametric engine.");
storm::performParameterLifting<ValueType>(sparseModel, formulas);

251
src/storm/counterexamples/MILPMinimalLabelSetGenerator.h → src/storm/counterexamples/MILPMinimalCommandSetGenerator.h

@ -19,6 +19,8 @@
#include "storm/utility/solver.h"
#include "storm/solver/LpSolver.h"
#include "storm/storage/sparse/PrismChoiceOrigins.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/CounterexampleGeneratorSettings.h"
@ -28,10 +30,10 @@ namespace storm {
/*!
* This class provides functionality to generate a minimal counterexample to a probabilistic reachability
* property in terms of used labels.
* property in terms of used commands.
*/
template <class T>
class MILPMinimalLabelSetGenerator {
class MILPMinimalCommandSetGenerator {
private:
/*!
* A helper class that provides the functionality to compute a hash value for pairs of state indices.
@ -55,21 +57,21 @@ namespace storm {
};
/*!
* A helper struct capturing information about relevant and problematic choices of states and which labels
* A helper struct capturing information about relevant and problematic choices of states and which commands
* are relevant.
*/
struct ChoiceInformation {
std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> relevantChoicesForRelevantStates;
std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> problematicChoicesForProblematicStates;
boost::container::flat_set<uint_fast64_t> allRelevantLabels;
boost::container::flat_set<uint_fast64_t> knownLabels;
boost::container::flat_set<uint_fast64_t> allRelevantCommands;
boost::container::flat_set<uint_fast64_t> knownCommands;
};
/*!
* A helper struct capturing information about the variables of the MILP formulation.
*/
struct VariableInformation {
std::unordered_map<uint_fast64_t, storm::expressions::Variable> labelToVariableMap;
std::unordered_map<uint_fast64_t, storm::expressions::Variable> commandToVariableMap;
std::unordered_map<uint_fast64_t, std::list<storm::expressions::Variable>> stateToChoiceVariablesMap;
std::unordered_map<uint_fast64_t, storm::expressions::Variable> initialStateToChoiceVariableMap;
std::unordered_map<uint_fast64_t, storm::expressions::Variable> stateToProbabilityVariableMap;
@ -87,16 +89,16 @@ namespace storm {
* non-zero probability of satisfying phi until psi. Problematic states are relevant states that have at
* least one scheduler such that the probability of satisfying phi until psi is zero.
*
* @param labeledMdp The MDP whose states to search.
* @param mdp The MDP whose states to search.
* @param phiStates A bit vector characterizing all states satisfying phi.
* @param psiStates A bit vector characterizing all states satisfying psi.
* @return A structure that stores the relevant and problematic states.
*/
static struct StateInformation determineRelevantAndProblematicStates(storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
static struct StateInformation determineRelevantAndProblematicStates(storm::models::sparse::Mdp<T> const& mdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
StateInformation result;
result.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.relevantStates = storm::utility::graph::performProbGreater0E(mdp.getBackwardTransitions(), phiStates, psiStates);
result.relevantStates &= ~psiStates;
result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates = storm::utility::graph::performProb0E(mdp.getTransitionMatrix(), mdp.getNondeterministicChoiceIndices(), mdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates &= result.relevantStates;
STORM_LOG_DEBUG("Found " << phiStates.getNumberOfSetBits() << " filter states.");
STORM_LOG_DEBUG("Found " << psiStates.getNumberOfSetBits() << " target states.");
@ -108,21 +110,20 @@ namespace storm {
/*!
* Determines the relevant and problematic choices of the given MDP with respect to the given parameters.
*
* @param labeledMdp The MDP whose choices to search.
* @param mdp The MDP whose choices to search.
* @param stateInformation The relevant and problematic states of the model.
* @param psiStates A bit vector characterizing the psi states in the model.
* @return A structure that stores the relevant and problematic choices in the model as well as the set
* of relevant labels.
* of relevant commands.
*/
static struct ChoiceInformation determineRelevantAndProblematicChoices(storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, storm::storage::BitVector const& psiStates) {
static struct ChoiceInformation determineRelevantAndProblematicChoices(storm::models::sparse::Mdp<T> const& mdp, storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins, StateInformation const& stateInformation, storm::storage::BitVector const& psiStates) {
// Create result and shortcuts to needed data for convenience.
ChoiceInformation result;
storm::storage::SparseMatrix<T> const& transitionMatrix = labeledMdp.getTransitionMatrix();
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = labeledMdp.getNondeterministicChoiceIndices();
std::vector<boost::container::flat_set<uint_fast64_t>> const& choiceLabeling = labeledMdp.getChoiceLabeling();
storm::storage::SparseMatrix<T> const& transitionMatrix = mdp.getTransitionMatrix();
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = mdp.getNondeterministicChoiceIndices();
// Now traverse all choices of all relevant states and check whether there is a relevant target state.
// If so, the associated labels become relevant. Also, if a choice of relevant state has at least one
// If so, the associated commands become relevant. Also, if a choice of relevant state has at least one
// relevant successor, the choice is considered to be relevant.
for (auto state : stateInformation.relevantStates) {
result.relevantChoicesForRelevantStates.emplace(state, std::list<uint_fast64_t>());
@ -133,10 +134,10 @@ namespace storm {
bool currentChoiceRelevant = false;
bool allSuccessorsProblematic = true;
for (auto const& successorEntry : transitionMatrix.getRow(row)) {
// If there is a relevant successor, we need to add the labels of the current choice.
// If there is a relevant successor, we need to add the commands of the current choice.
if (stateInformation.relevantStates.get(successorEntry.getColumn()) || psiStates.get(successorEntry.getColumn())) {
for (auto const& label : choiceLabeling[row]) {
result.allRelevantLabels.insert(label);
for (auto const& command : choiceOrigins.getCommandSet(row)) {
result.allRelevantCommands.insert(command);
}
if (!currentChoiceRelevant) {
currentChoiceRelevant = true;
@ -156,30 +157,30 @@ namespace storm {
}
}
// Finally, determine the set of labels that are known to be taken.
result.knownLabels = storm::utility::counterexamples::getGuaranteedLabelSet(labeledMdp, psiStates, result.allRelevantLabels);
STORM_LOG_DEBUG("Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels.");
// Finally, determine the set of commands that are known to be taken.
result.knownCommands = storm::utility::counterexamples::getGuaranteedCommandSet(mdp, choiceOrigins, psiStates, result.allRelevantCommands);
STORM_LOG_DEBUG("Found " << result.allRelevantCommands.size() << " relevant commands and " << result.knownCommands.size() << " known commands.");
return result;
}
/*!
* Creates the variables for the labels of the model.
* Creates the variables for the commands of the model.
*
* @param solver The MILP solver.
* @param relevantLabels The set of relevant labels of the model.
* @return A mapping from labels to variable indices.
* @param relevantCommands The set of relevant commands of the model.
* @return A mapping from commands to variable indices.
*/
static std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> createLabelVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
static std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> createCommandVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantCommands) {
std::stringstream variableNameBuffer;
std::unordered_map<uint_fast64_t, storm::expressions::Variable> resultingMap;
for (auto const& label : relevantLabels) {
for (auto const& command : relevantCommands) {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "label" << label;
resultingMap[label] = solver.addBinaryVariable(variableNameBuffer.str(), 1);
variableNameBuffer << "command" << command;
resultingMap[command] = solver.addBinaryVariable(variableNameBuffer.str(), 1);
}
return std::make_pair(resultingMap, relevantLabels.size());
return std::make_pair(resultingMap, relevantCommands.size());
}
/*!
@ -214,16 +215,16 @@ namespace storm {
* in the model.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states of the model.
* @return A mapping from initial states to choice variable indices.
*/
static std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation) {
static std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, StateInformation const& stateInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<uint_fast64_t, storm::expressions::Variable> resultingMap;
for (auto initialState : labeledMdp.getStates("init")) {
for (auto initialState : mdp.getStates("init")) {
// Only consider this initial state if it is relevant.
if (stateInformation.relevantStates.get(initialState)) {
variableNameBuffer.str("");
@ -275,11 +276,11 @@ namespace storm {
* Creates the variables for the problematic states in the model.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states in the model.
* @return A mapping from problematic states to the index of the corresponding variables.
*/
static std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
static std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<uint_fast64_t, storm::expressions::Variable> resultingMap;
@ -297,7 +298,7 @@ namespace storm {
std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
for (uint_fast64_t row : relevantChoicesForState) {
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(row)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(row)) {
if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
if (resultingMap.find(successorEntry.getColumn()) == resultingMap.end()) {
variableNameBuffer.str("");
@ -317,12 +318,12 @@ namespace storm {
* Creates the variables for the problematic choices in the model.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
* @return A mapping from problematic choices to the index of the corresponding variables.
*/
static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash> resultingMap;
@ -330,7 +331,7 @@ namespace storm {
for (auto state : stateInformation.problematicStates) {
std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
for (uint_fast64_t row : relevantChoicesForState) {
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(row)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(row)) {
if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
variableNameBuffer.str("");
variableNameBuffer.clear();
@ -350,19 +351,19 @@ namespace storm {
* passed to the solver.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
*/
static VariableInformation createVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
static VariableInformation createVariables(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
// Create a struct that stores all information about variables.
VariableInformation result;
// Create variables for involved labels.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
result.labelToVariableMap = std::move(labelVariableResult.first);
result.numberOfVariables += labelVariableResult.second;
STORM_LOG_DEBUG("Created variables for labels.");
// Create variables for involved commands.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> commandVariableResult = createCommandVariables(solver, choiceInformation.allRelevantCommands);
result.commandToVariableMap = std::move(commandVariableResult.first);
result.numberOfVariables += commandVariableResult.second;
STORM_LOG_DEBUG("Created variables for commands.");
// Create scheduler variables for relevant states and their actions.
std::pair<std::unordered_map<uint_fast64_t, std::list<storm::expressions::Variable>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
@ -371,7 +372,7 @@ namespace storm {
STORM_LOG_DEBUG("Created variables for nondeterministic choices.");
// Create scheduler variables for nondeterministically choosing an initial state.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, mdp, stateInformation);
result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first);
result.numberOfVariables += initialChoiceVariableResult.second;
STORM_LOG_DEBUG("Created variables for the nondeterministic choice of the initial state.");
@ -389,13 +390,13 @@ namespace storm {
STORM_LOG_DEBUG("Created variables for the virtual initial state.");
// Create variables for problematic states.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, mdp, stateInformation, choiceInformation);
result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first);
result.numberOfVariables += problematicStateVariableResult.second;
STORM_LOG_DEBUG("Created variables for the problematic states.");
// Create variables for problematic choices.
std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, mdp, stateInformation, choiceInformation);
result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first;
result.numberOfVariables += problematicTransitionVariableResult.second;
STORM_LOG_DEBUG("Created variables for the problematic choices.");
@ -469,26 +470,25 @@ namespace storm {
}
/*!
* Asserts constraints that make sure the labels are included in the solution set if the policy selects a
* choice that is labeled with the label in question.
* Asserts constraints that make sure the commands are included in the solution set if the policy selects a
* choice that originates from the command in question.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
* @param variableInformation A struct with information about the variables of the model.
* @return The total number of constraints that were created.
*/
static uint_fast64_t assertChoicesImplyLabels(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
static uint_fast64_t assertChoicesImplyCommands(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
uint_fast64_t numberOfConstraintsCreated = 0;
std::vector<boost::container::flat_set<uint_fast64_t>> const& choiceLabeling = labeledMdp.getChoiceLabeling();
for (auto state : stateInformation.relevantStates) {
std::list<storm::expressions::Variable>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
for (auto label : choiceLabeling[choice]) {
storm::expressions::Expression constraint = variableInformation.labelToVariableMap.at(label) - *choiceVariableIterator >= solver.getConstant(0);
solver.addConstraint("ChoicesImplyLabels" + std::to_string(numberOfConstraintsCreated), constraint);
for (auto command : choiceOrigins.getCommandSet(choice)) {
storm::expressions::Expression constraint = variableInformation.commandToVariableMap.at(command) - *choiceVariableIterator >= solver.getConstant(0);
solver.addConstraint("ChoicesImplyCommands" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
++choiceVariableIterator;
@ -524,14 +524,14 @@ namespace storm {
* Asserts constraints that encode the correct reachability probabilities for all states.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param psiStates A bit vector characterizing the psi states in the model.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
* @param variableInformation A struct with information about the variables of the model.
* @return The total number of constraints that were created.
*/
static uint_fast64_t assertReachabilityProbabilities(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
static uint_fast64_t assertReachabilityProbabilities(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto state : stateInformation.relevantStates) {
std::list<storm::expressions::Variable>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
@ -539,7 +539,7 @@ namespace storm {
storm::expressions::Expression constraint = variableInformation.stateToProbabilityVariableMap.at(state);
double rightHandSide = 1;
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(choice)) {
if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
constraint = constraint - solver.getConstant(successorEntry.getValue()) * variableInformation.stateToProbabilityVariableMap.at(successorEntry.getColumn());
} else if (psiStates.get(successorEntry.getColumn())) {
@ -570,13 +570,13 @@ namespace storm {
* Asserts constraints that make sure an unproblematic state is reachable from each problematic state.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
* @param variableInformation A struct with information about the variables of the model.
* @return The total number of constraints that were created.
*/
static uint_fast64_t assertUnproblematicStateReachable(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
static uint_fast64_t assertUnproblematicStateReachable(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto stateListPair : choiceInformation.problematicChoicesForProblematicStates) {
@ -590,7 +590,7 @@ namespace storm {
}
storm::expressions::Expression constraint = *choiceVariableIterator;
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(problematicChoice)) {
constraint = constraint - variableInformation.problematicTransitionToVariableMap.at(std::make_pair(stateListPair.first, successorEntry.getColumn()));
}
constraint = constraint <= solver.getConstant(0);
@ -602,7 +602,7 @@ namespace storm {
for (auto state : stateInformation.problematicStates) {
for (auto problematicChoice : choiceInformation.problematicChoicesForProblematicStates.at(state)) {
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(problematicChoice)) {
storm::expressions::Expression constraint = variableInformation.problematicStateToVariableMap.at(state);
constraint = constraint - variableInformation.problematicStateToVariableMap.at(successorEntry.getColumn());
constraint = constraint + variableInformation.problematicTransitionToVariableMap.at(std::make_pair(state, successorEntry.getColumn()));
@ -617,19 +617,19 @@ namespace storm {
}
/*
* Asserts that labels that are on all paths from initial to target states are definitely taken.
* Asserts that commands that are on all paths from initial to target states are definitely taken.
*
* @param solver The MILP solver.
* @param choiceInformation The information about the choices in the model.
* @param variableInformation A struct with information about the variables of the model.
* @return The total number of constraints that were created.
*/
static uint_fast64_t assertKnownLabels(storm::solver::LpSolver& solver, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
static uint_fast64_t assertKnownCommands(storm::solver::LpSolver& solver, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto label : choiceInformation.knownLabels) {
storm::expressions::Expression constraint = variableInformation.labelToVariableMap.at(label) == solver.getConstant(1);
solver.addConstraint("KnownLabels" + std::to_string(numberOfConstraintsCreated), constraint);
for (auto command : choiceInformation.knownCommands) {
storm::expressions::Expression constraint = variableInformation.commandToVariableMap.at(command) == solver.getConstant(1);
solver.addConstraint("KnownCommands" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
@ -640,15 +640,15 @@ namespace storm {
* Asserts constraints that rule out many suboptimal policies.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param psiStates A bit vector characterizing the psi states in the model.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
* @param variableInformation A struct with information about the variables of the model.
* @return The total number of constraints that were created.
*/
static uint_fast64_t assertSchedulerCuts(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
storm::storage::SparseMatrix<T> backwardTransitions = labeledMdp.getBackwardTransitions();
static uint_fast64_t assertSchedulerCuts(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
storm::storage::SparseMatrix<T> backwardTransitions = mdp.getBackwardTransitions();
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto state : stateInformation.relevantStates) {
@ -657,7 +657,7 @@ namespace storm {
std::list<storm::expressions::Variable>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
bool psiStateReachableInOneStep = false;
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(choice)) {
if (psiStates.get(successorEntry.getColumn())) {
psiStateReachableInOneStep = true;
}
@ -665,7 +665,7 @@ namespace storm {
if (!psiStateReachableInOneStep) {
storm::expressions::Expression constraint = *choiceVariableIterator;
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(choice)) {
if (state != successorEntry.getColumn() && stateInformation.relevantStates.get(successorEntry.getColumn())) {
std::list<storm::expressions::Variable> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesMap.at(successorEntry.getColumn());
@ -710,7 +710,7 @@ namespace storm {
bool choiceTargetsCurrentState = false;
// Check if the current choice targets the current state.
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(relevantChoice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(relevantChoice)) {
if (state == successorEntry.getColumn()) {
choiceTargetsCurrentState = true;
break;
@ -727,7 +727,7 @@ namespace storm {
// If the current state is an initial state and is selected as a successor state by the virtual
// initial state, then this also justifies making a choice in the current state.
if (labeledMdp.getStates("init").get(state)) {
if (mdp.getStates("init").get(state)) {
constraint = constraint - variableInformation.initialStateToChoiceVariableMap.at(state);
}
constraint = constraint <= solver.getConstant(0);
@ -738,7 +738,7 @@ namespace storm {
// Assert that at least one initial state selects at least one action.
storm::expressions::Expression constraint = solver.getConstant(0);
for (auto initialState : labeledMdp.getStates("init")) {
for (auto initialState : mdp.getStates("init")) {
for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(initialState)) {
constraint = constraint + choiceVariable;
}
@ -770,7 +770,7 @@ namespace storm {
bool choiceTargetsPsiState = false;
// Check if the current choice targets the current state.
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(relevantChoice)) {
for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(relevantChoice)) {
if (psiStates.get(successorEntry.getColumn())) {
choiceTargetsPsiState = true;
break;
@ -797,7 +797,7 @@ namespace storm {
* the given threshold.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param psiStates A bit vector characterizing all psi states in the model.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
@ -807,7 +807,7 @@ namespace storm {
* @param includeSchedulerCuts If set to true, additional constraints are asserted that reduce the set of
* possible choices.
*/
static void buildConstraintSystem(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound, bool includeSchedulerCuts = false) {
static void buildConstraintSystem(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& mdp, storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound, bool includeSchedulerCuts = false) {
// Assert that the reachability probability in the subsystem exceeds the given threshold.
uint_fast64_t numberOfConstraints = assertProbabilityGreaterThanThreshold(solver, variableInformation, probabilityThreshold, strictBound);
STORM_LOG_DEBUG("Asserted that reachability probability exceeds threshold.");
@ -816,9 +816,9 @@ namespace storm {
numberOfConstraints += assertValidPolicy(solver, stateInformation, variableInformation);
STORM_LOG_DEBUG("Asserted that policy is valid.");
// Add constraints that assert the labels that belong to some taken choices are taken as well.
numberOfConstraints += assertChoicesImplyLabels(solver, labeledMdp, stateInformation, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted that labels implied by choices are taken.");
// Add constraints that assert the commands that belong to some taken choices are taken as well.
numberOfConstraints += assertChoicesImplyCommands(solver, mdp, choiceOrigins, stateInformation, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted that commands implied by choices are taken.");
// Add constraints that encode that the reachability probability from states which do not pick any action
// is zero.
@ -826,20 +826,20 @@ namespace storm {
STORM_LOG_DEBUG("Asserted that reachability probability is zero if no choice is taken.");
// Add constraints that encode the reachability probabilities for states.
numberOfConstraints += assertReachabilityProbabilities(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation);
numberOfConstraints += assertReachabilityProbabilities(solver, mdp, psiStates, stateInformation, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted constraints for reachability probabilities.");
// Add constraints that ensure the reachability of an unproblematic state from each problematic state.
numberOfConstraints += assertUnproblematicStateReachable(solver, labeledMdp, stateInformation, choiceInformation, variableInformation);
numberOfConstraints += assertUnproblematicStateReachable(solver, mdp, stateInformation, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted that unproblematic state reachable from problematic states.");
// Add constraints that express that certain labels are already known to be taken.
numberOfConstraints += assertKnownLabels(solver, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted known labels are taken.");
// Add constraints that express that certain commands are already known to be taken.
numberOfConstraints += assertKnownCommands(solver, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted known commands are taken.");
// If required, assert additional constraints that reduce the number of possible policies.
if (includeSchedulerCuts) {
numberOfConstraints += assertSchedulerCuts(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation);
numberOfConstraints += assertSchedulerCuts(solver, mdp, psiStates, stateInformation, choiceInformation, variableInformation);
STORM_LOG_DEBUG("Asserted scheduler cuts.");
}
@ -850,19 +850,19 @@ namespace storm {
}
/*!
* Computes the set of labels that was used in the given optimized model.
* Computes the set of commands that was used in the given optimized model.
*
* @param solver The MILP solver.
* @param variableInformation A struct with information about the variables of the model.
*/
static boost::container::flat_set<uint_fast64_t> getUsedLabelsInSolution(storm::solver::LpSolver const& solver, VariableInformation const& variableInformation) {
static boost::container::flat_set<uint_fast64_t> getUsedCommandsInSolution(storm::solver::LpSolver const& solver, VariableInformation const& variableInformation) {
boost::container::flat_set<uint_fast64_t> result;
for (auto const& labelVariablePair : variableInformation.labelToVariableMap) {
bool labelTaken = solver.getBinaryValue(labelVariablePair.second);
for (auto const& commandVariablePair : variableInformation.commandToVariableMap) {
bool commandTaken = solver.getBinaryValue(commandVariablePair.second);
if (labelTaken) {
result.insert(labelVariablePair.first);
if (commandTaken) {
result.insert(commandVariablePair.first);
}
}
return result;
@ -873,12 +873,12 @@ namespace storm {
* it is selected by the subsystem computed by the solver.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param stateInformation The information about the states in the model.
* @param choiceInformation The information about the choices in the model.
* @param variableInformation A struct with information about the variables of the model.
*/
static std::map<uint_fast64_t, uint_fast64_t> getChoices(storm::solver::LpSolver const& solver, storm::models::sparse::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
static std::map<uint_fast64_t, uint_fast64_t> getChoices(storm::solver::LpSolver const& solver, storm::models::sparse::Mdp<T> const& mdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
std::map<uint_fast64_t, uint_fast64_t> result;
for (auto state : stateInformation.relevantStates) {
@ -899,10 +899,10 @@ namespace storm {
* Computes the reachability probability and the selected initial state in the given optimized MILP model.
*
* @param solver The MILP solver.
* @param labeledMdp The labeled MDP.
* @param mdp The MDP.
* @param variableInformation A struct with information about the variables of the model.
*/
static std::pair<uint_fast64_t, double> getReachabilityProbability(storm::solver::LpSolver const& solver, storm::models::sparse::Mdp<T> const& labeledMdp, VariableInformation const& variableInformation) {
static std::pair<uint_fast64_t, double> getReachabilityProbability(storm::solver::LpSolver const& solver, storm::models::sparse::Mdp<T> const& mdp, VariableInformation const& variableInformation) {
uint_fast64_t selectedInitialState = 0;
for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
bool initialStateChosen = solver.getBinaryValue(initialStateVariablePair.second);
@ -917,18 +917,20 @@ namespace storm {
}
public:
static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, bool checkThresholdFeasible = false, bool includeSchedulerCuts = false) {
// (0) Check whether the MDP is indeed labeled.
if (!labeledMdp.hasChoiceLabeling()) {
throw storm::exceptions::InvalidArgumentException() << "Minimal label set generation is impossible for unlabeled model.";
}
static boost::container::flat_set<uint_fast64_t> getMinimalCommandSet(storm::models::sparse::Mdp<T> const& mdp, std::shared_ptr<storm::storage::sparse::ChoiceOrigins> const& choiceOrigins, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, bool checkThresholdFeasible = false, bool includeSchedulerCuts = false) {
// (0) Check whether there are choice origins available
STORM_LOG_THROW(choiceOrigins, storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without choice origns.");
STORM_LOG_THROW(choiceOrigins->isPrismChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without prism choice origins.");
storm::storage::sparse::PrismChoiceOrigins const& prismChoiceOrigins = choiceOrigins->asPrismChoiceOrigins();
// (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set.
double maximalReachabilityProbability = 0;
if (checkThresholdFeasible) {
storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelcheckerHelper;
std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::solver::GeneralMinMaxLinearEquationSolverFactory<T>()).values);
for (auto state : labeledMdp.getInitialStates()) {
std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(false, mdp.getTransitionMatrix(), mdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::solver::GeneralMinMaxLinearEquationSolverFactory<T>()).values);
for (auto state : mdp.getInitialStates()) {
maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
}
STORM_LOG_THROW((strictBound && maximalReachabilityProbability >= probabilityThreshold) || (!strictBound && maximalReachabilityProbability > probabilityThreshold), storm::exceptions::InvalidArgumentException, "Given probability threshold " << probabilityThreshold << " can not be " << (strictBound ? "achieved" : "exceeded") << " in model with maximal reachability probability of " << maximalReachabilityProbability << ".");
@ -936,40 +938,41 @@ namespace storm {
}
// (2) Identify relevant and problematic states.
StateInformation stateInformation = determineRelevantAndProblematicStates(labeledMdp, phiStates, psiStates);
StateInformation stateInformation = determineRelevantAndProblematicStates(mdp, phiStates, psiStates);
// (3) Determine sets of relevant labels and problematic choices.
ChoiceInformation choiceInformation = determineRelevantAndProblematicChoices(labeledMdp, stateInformation, psiStates);
// (3) Determine sets of relevant commands and problematic choices.
ChoiceInformation choiceInformation = determineRelevantAndProblematicChoices(mdp, prismChoiceOrigins, stateInformation, psiStates);
// (4) Encode resulting system as MILP problem.
std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("MinimalCommandSetCounterexample");
// (4.1) Create variables.
VariableInformation variableInformation = createVariables(*solver, labeledMdp, stateInformation, choiceInformation);
VariableInformation variableInformation = createVariables(*solver, mdp, stateInformation, choiceInformation);
// (4.2) Construct constraint system.
buildConstraintSystem(*solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation, probabilityThreshold, strictBound, includeSchedulerCuts);
buildConstraintSystem(*solver, mdp, prismChoiceOrigins, psiStates, stateInformation, choiceInformation, variableInformation, probabilityThreshold, strictBound, includeSchedulerCuts);
// (4.3) Optimize the model.
solver->optimize();
// (4.4) Read off result from variables.
boost::container::flat_set<uint_fast64_t> usedLabelSet = getUsedLabelsInSolution(*solver, variableInformation);
usedLabelSet.insert(choiceInformation.knownLabels.begin(), choiceInformation.knownLabels.end());
boost::container::flat_set<uint_fast64_t> usedCommandSet = getUsedCommandsInSolution(*solver, variableInformation);
usedCommandSet.insert(choiceInformation.knownCommands.begin(), choiceInformation.knownCommands.end());
// (5) Return result.
return usedLabelSet;
return usedCommandSet;
}
/*!
* Computes a (minimally labeled) counterexample for the given model and (safety) formula. If the model satisfies the property, an exception is thrown.
* Computes a (minimal) counterexample with respect to the number of prism commands for the given model and (safety) formula. If the model satisfies the property, an exception is thrown.
*
* @param labeledMdp A labeled MDP that is the model in which to generate the counterexample.
* @param mdp An MDP that is the model in which to generate the counterexample.
* @param choiceOrigins the choice origins generated for the mdp
* @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested
* formula can be either an unbounded until formula or an eventually formula.
*/
static void computeCounterexample(storm::prism::Program const& program, storm::models::sparse::Mdp<T> const& labeledMdp, std::shared_ptr<storm::logic::Formula const> const& formula) {
std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl;
static void computeCounterexample(storm::prism::Program const& program, storm::models::sparse::Mdp<T> const& mdp, std::shared_ptr<storm::storage::sparse::ChoiceOrigins> const& choiceOrigins, std::shared_ptr<storm::logic::Formula const> const& formula) {
std::cout << std::endl << "Generating minimal command set counterexample for formula " << *formula << std::endl;
STORM_LOG_THROW(formula->isProbabilityOperatorFormula(), storm::exceptions::InvalidPropertyException, "Counterexample generation does not support this kind of formula. Expecting a probability operator as the outermost formula element.");
storm::logic::ProbabilityOperatorFormula const& probabilityOperator = formula->asProbabilityOperatorFormula();
@ -983,7 +986,7 @@ namespace storm {
storm::storage::BitVector phiStates;
storm::storage::BitVector psiStates;
storm::modelchecker::SparsePropositionalModelChecker<storm::models::sparse::Mdp<T>> modelchecker(labeledMdp);
storm::modelchecker::SparsePropositionalModelChecker<storm::models::sparse::Mdp<T>> modelchecker(mdp);
if (probabilityOperator.getSubformula().isUntilFormula()) {
storm::logic::UntilFormula const& untilFormula = probabilityOperator.getSubformula().asUntilFormula();
@ -1003,18 +1006,18 @@ namespace storm {
storm::modelchecker::ExplicitQualitativeCheckResult const& subQualitativeResult = subResult->asExplicitQualitativeCheckResult();
phiStates = storm::storage::BitVector(labeledMdp.getNumberOfStates(), true);
phiStates = storm::storage::BitVector(mdp.getNumberOfStates(), true);
psiStates = subQualitativeResult.getTruthValuesVector();
}
// Delegate the actual computation work to the function of equal name.
auto startTime = std::chrono::high_resolution_clock::now();
boost::container::flat_set<uint_fast64_t> usedLabelSet = getMinimalLabelSet(labeledMdp, phiStates, psiStates, threshold, strictBound, true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseSchedulerCutsSet());
boost::container::flat_set<uint_fast64_t> usedCommandSet = getMinimalCommandSet(mdp, choiceOrigins, phiStates, psiStates, threshold, strictBound, true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseSchedulerCutsSet());
auto endTime = std::chrono::high_resolution_clock::now();
std::cout << std::endl << "Computed minimal label set of size " << usedLabelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl;
std::cout << std::endl << "Computed minimal command set of size " << usedCommandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl;
std::cout << "Resulting program:" << std::endl;
storm::prism::Program restrictedProgram = program.restrictCommands(usedLabelSet);
storm::prism::Program restrictedProgram = program.restrictCommands(usedCommandSet);
std::cout << restrictedProgram << std::endl;
std::cout << std::endl << "-------------------------------------------" << std::endl;
}

666
src/storm/counterexamples/SMTMinimalCommandSetGenerator.h
File diff suppressed because it is too large
View File

5
src/storm/generator/PrismNextStateGenerator.cpp

@ -617,7 +617,10 @@ namespace storm {
identifiers.reserve(dataForChoiceOrigins.size());
std::map<CommandSet, uint_fast64_t> commandSetToIdentifierMap;
uint_fast64_t currentIdentifier = 0;
// The empty commandset (i.e., the choices without origin) always has to get identifier getIdentifierForChoicesWithNoOrigin() -- which is assumed to be 0
STORM_LOG_ASSERT(storm::storage::sparse::ChoiceOrigins::getIdentifierForChoicesWithNoOrigin() == 0, "The no origin identifier is assumed to be zero");
commandSetToIdentifierMap.insert(std::make_pair(CommandSet(), 0));
uint_fast64_t currentIdentifier = 1;
for (boost::any& originData : dataForChoiceOrigins) {
STORM_LOG_ASSERT(originData.empty() || boost::any_cast<CommandSet>(&originData) != nullptr, "Origin data has unexpected type: " << originData.type().name() << ".");

6
src/storm/models/sparse/Ctmc.cpp

@ -10,7 +10,7 @@ namespace storm {
template <typename ValueType, typename RewardModelType>
Ctmc<ValueType, RewardModelType>::Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: DeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Ctmc, rateMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
exitRates = createExitRateVector(this->getTransitionMatrix());
}
@ -18,7 +18,7 @@ namespace storm {
template <typename ValueType, typename RewardModelType>
Ctmc<ValueType, RewardModelType>::Ctmc(storm::storage::SparseMatrix<ValueType>&& rateMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: DeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Ctmc, std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
// It is important to refer to the transition matrix here, because the given rate matrix has been move elsewhere.
exitRates = createExitRateVector(this->getTransitionMatrix());
@ -27,7 +27,7 @@ namespace storm {
template <typename ValueType, typename RewardModelType>
Ctmc<ValueType, RewardModelType>::Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRates, storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: DeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Ctmc, std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)), exitRates(exitRates) {
}

6
src/storm/models/sparse/Ctmc.h

@ -24,7 +24,7 @@ namespace storm {
*/
Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -36,7 +36,7 @@ namespace storm {
*/
Ctmc(storm::storage::SparseMatrix<ValueType>&& rateMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model from the given data.
@ -49,7 +49,7 @@ namespace storm {
*/
Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRates, storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
Ctmc(Ctmc<ValueType, RewardModelType> const& ctmc) = default;

4
src/storm/models/sparse/DeterministicModel.cpp

@ -11,7 +11,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: Model<ValueType, RewardModelType>(modelType, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
// Intentionally left empty.
}
@ -21,7 +21,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: Model<ValueType, RewardModelType>(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
// Intentionally left empty.
}

4
src/storm/models/sparse/DeterministicModel.h

@ -27,7 +27,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -42,7 +42,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
DeterministicModel(DeterministicModel<ValueType, RewardModelType> const& other) = default;
DeterministicModel& operator=(DeterministicModel<ValueType, RewardModelType> const& other) = default;

4
src/storm/models/sparse/Dtmc.cpp

@ -13,14 +13,14 @@ namespace storm {
Dtmc<ValueType, RewardModelType>::Dtmc(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: DeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Dtmc, probabilityMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
STORM_LOG_THROW(probabilityMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
}
template <typename ValueType, typename RewardModelType>
Dtmc<ValueType, RewardModelType>::Dtmc(storm::storage::SparseMatrix<ValueType>&& probabilityMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels, boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
std::unordered_map<std::string, RewardModelType>&& rewardModels, boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: DeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Dtmc, std::move(probabilityMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
STORM_LOG_THROW(probabilityMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
}

4
src/storm/models/sparse/Dtmc.h

@ -24,7 +24,7 @@ namespace storm {
Dtmc(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -36,7 +36,7 @@ namespace storm {
*/
Dtmc(storm::storage::SparseMatrix<ValueType>&& probabilityMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
Dtmc(Dtmc<ValueType, RewardModelType> const& dtmc) = default;
Dtmc& operator=(Dtmc<ValueType, RewardModelType> const& dtmc) = default;

22
src/storm/models/sparse/MarkovAutomaton.cpp

@ -20,7 +20,7 @@ namespace storm {
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::MarkovAutomaton, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling), markovianStates(markovianStates), exitRates(exitRates), closed(this->checkIsClosed()) {
this->turnRatesToProbabilities();
}
@ -31,7 +31,7 @@ namespace storm {
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::MarkovAutomaton, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)), markovianStates(markovianStates), exitRates(std::move(exitRates)), closed(this->checkIsClosed()) {
this->turnRatesToProbabilities();
}
@ -42,7 +42,7 @@ namespace storm {
storm::models::sparse::StateLabeling const& stateLabeling,
storm::storage::BitVector const& markovianStates,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::MarkovAutomaton, rateMatrix, stateLabeling, rewardModels, optionalChoiceLabeling), markovianStates(markovianStates) {
turnRatesToProbabilities();
this->closed = checkIsClosed();
@ -53,7 +53,7 @@ namespace storm {
storm::models::sparse::StateLabeling&& stateLabeling,
storm::storage::BitVector&& markovianStates,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::MarkovAutomaton, rateMatrix, stateLabeling, rewardModels, optionalChoiceLabeling), markovianStates(markovianStates) {
turnRatesToProbabilities();
this->closed = checkIsClosed();
@ -67,7 +67,7 @@ namespace storm {
std::vector<ValueType> const& exitRates,
bool probabilities,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::MarkovAutomaton, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)), markovianStates(markovianStates), exitRates(std::move(exitRates)), closed(this->checkIsClosed()) {
STORM_LOG_ASSERT(probabilities, "Matrix must be probabilistic.");
STORM_LOG_ASSERT(this->getTransitionMatrix().isProbabilistic(), "Matrix must be probabilistic.");
@ -147,7 +147,7 @@ namespace storm {
}
}
if(this->hasChoiceLabeling()) {
storm::utility::vector::filterVectorInPlace(this->getOptionalChoiceLabeling().get(), keptChoices);
this->getChoiceLabeling().getSubLabeling(keptChoices);
}
// Mark the automaton as closed.
@ -327,15 +327,13 @@ namespace storm {
STORM_LOG_TRACE("New CTMC matrix:" << std::endl << rateMatrix);
// Construct CTMC
storm::models::sparse::StateLabeling stateLabeling = this->getStateLabeling().getSubLabeling(keepStates);
boost::optional<std::vector<LabelSet>> optionalChoiceLabeling = this->getOptionalChoiceLabeling();
if (optionalChoiceLabeling) {
storm::utility::vector::filterVectorInPlace(optionalChoiceLabeling.get(), keepStates);
}
//TODO update reward models according to kept states
//TODO update reward models and choice labels according to kept states
STORM_LOG_WARN_COND(this->getRewardModels().empty(), "Conversion of MA to CTMC does not preserve rewards.");
std::unordered_map<std::string, RewardModelType> rewardModels = this->getRewardModels();
STORM_LOG_WARN_COND(!this->hasChoiceLabeling(), "Conversion of MA to CTMC does not preserve choice labels.");
return std::make_shared<storm::models::sparse::Ctmc<ValueType, RewardModelType>>(std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling));
return std::make_shared<storm::models::sparse::Ctmc<ValueType, RewardModelType>>(std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels));
}

10
src/storm/models/sparse/MarkovAutomaton.h

@ -30,7 +30,7 @@ namespace storm {
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model from the given data.
@ -48,7 +48,7 @@ namespace storm {
storm::models::sparse::StateLabeling const& stateLabeling,
storm::storage::BitVector const& markovianStates,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model from the given data.
@ -66,7 +66,7 @@ namespace storm {
storm::models::sparse::StateLabeling&& stateLabeling,
storm::storage::BitVector&& markovianStates,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -83,7 +83,7 @@ namespace storm {
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -102,7 +102,7 @@ namespace storm {
std::vector<ValueType> const& exitRates,
bool probabilities,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
MarkovAutomaton(MarkovAutomaton<ValueType, RewardModelType> const& other) = default;
MarkovAutomaton& operator=(MarkovAutomaton<ValueType, RewardModelType> const& other) = default;

55
src/storm/models/sparse/Mdp.cpp

@ -15,7 +15,7 @@ namespace storm {
Mdp<ValueType, RewardModelType>::Mdp(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Mdp, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
STORM_LOG_THROW(transitionMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
}
@ -25,56 +25,11 @@ namespace storm {
Mdp<ValueType, RewardModelType>::Mdp(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: NondeterministicModel<ValueType, RewardModelType>(storm::models::ModelType::Mdp, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
STORM_LOG_THROW(transitionMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
}
template <typename ValueType, typename RewardModelType>
Mdp<ValueType, RewardModelType> Mdp<ValueType, RewardModelType>::restrictChoiceLabels(LabelSet const& enabledChoiceLabels) const {
STORM_LOG_THROW(this->hasChoiceLabeling(), storm::exceptions::InvalidArgumentException, "Restriction to label set is impossible for unlabeled model.");
std::vector<LabelSet> const& choiceLabeling = this->getChoiceLabeling();
storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, this->getTransitionMatrix().getColumnCount(), 0, true, true);
std::vector<LabelSet> newChoiceLabeling;
// Check for each choice of each state, whether the choice labels are fully contained in the given label set.
uint_fast64_t currentRow = 0;
for(uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) {
bool stateHasValidChoice = false;
for (uint_fast64_t choice = this->getTransitionMatrix().getRowGroupIndices()[state]; choice < this->getTransitionMatrix().getRowGroupIndices()[state + 1]; ++choice) {
bool choiceValid = std::includes(enabledChoiceLabels.begin(), enabledChoiceLabels.end(), choiceLabeling[choice].begin(), choiceLabeling[choice].end());
// If the choice is valid, copy over all its elements.
if (choiceValid) {
if (!stateHasValidChoice) {
transitionMatrixBuilder.newRowGroup(currentRow);
}
stateHasValidChoice = true;
for (auto const& entry : this->getTransitionMatrix().getRow(choice)) {
transitionMatrixBuilder.addNextValue(currentRow, entry.getColumn(), entry.getValue());
}
newChoiceLabeling.emplace_back(choiceLabeling[choice]);
++currentRow;
}
}
// If no choice of the current state may be taken, we insert a self-loop to the state instead.
if (!stateHasValidChoice) {
transitionMatrixBuilder.newRowGroup(currentRow);
transitionMatrixBuilder.addNextValue(currentRow, state, storm::utility::one<ValueType>());
newChoiceLabeling.emplace_back();
++currentRow;
}
}
Mdp<ValueType, RewardModelType> restrictedMdp(transitionMatrixBuilder.build(), storm::models::sparse::StateLabeling(this->getStateLabeling()),
std::unordered_map<std::string, RewardModelType>(this->getRewardModels()), boost::optional<std::vector<LabelSet>>(newChoiceLabeling));
return restrictedMdp;
}
template <typename ValueType, typename RewardModelType>
Mdp<ValueType, RewardModelType> Mdp<ValueType, RewardModelType>::restrictChoices(storm::storage::BitVector const& enabledChoices) const {
storm::storage::SparseMatrix<ValueType> restrictedTransitions = this->getTransitionMatrix().restrictRows(enabledChoices);
@ -83,12 +38,10 @@ namespace storm {
newRewardModels.emplace(rewardModel.first, rewardModel.second.restrictActions(enabledChoices));
}
if(this->hasChoiceLabeling()) {
return Mdp<ValueType, RewardModelType>(restrictedTransitions, this->getStateLabeling(), newRewardModels, boost::optional<std::vector<LabelSet>>(storm::utility::vector::filterVector(this->getChoiceLabeling(), enabledChoices)));
return Mdp<ValueType, RewardModelType>(restrictedTransitions, this->getStateLabeling(), newRewardModels, this->getChoiceLabeling().getSubLabeling(enabledChoices));
} else {
return Mdp<ValueType, RewardModelType>(restrictedTransitions, this->getStateLabeling(), newRewardModels, boost::optional<std::vector<LabelSet>>());
return Mdp<ValueType, RewardModelType>(restrictedTransitions, this->getStateLabeling(), newRewardModels);
}
}
template<typename ValueType, typename RewardModelType>

15
src/storm/models/sparse/Mdp.h

@ -26,7 +26,7 @@ namespace storm {
Mdp(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -39,7 +39,7 @@ namespace storm {
Mdp(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
Mdp(Mdp<ValueType, RewardModelType> const& other) = default;
Mdp& operator=(Mdp<ValueType, RewardModelType> const& other) = default;
@ -47,17 +47,6 @@ namespace storm {
Mdp(Mdp<ValueType, RewardModelType>&& other) = default;
Mdp& operator=(Mdp<ValueType, RewardModelType>&& other) = default;
/*!
* Constructs an MDP by copying the current MDP and restricting the choices of each state to the ones
* whose label set is contained in the given label set. Note that is is only valid to call this method
* if the MDP has choice labels.
*
* @param enabledChoiceLabels A set of labels that determines which choices of the original model can be taken
* and which ones need to be ignored.
* @return A restricted version of the current MDP that only uses choice labels from the given set.
*/
Mdp<ValueType, RewardModelType> restrictChoiceLabels(LabelSet const& enabledChoiceLabels) const;
/*!
* Constructs an MDP by copying the current MDP and restricting the choices of each state to the ones given by the bitvector.
*

10
src/storm/models/sparse/Model.cpp

@ -19,7 +19,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: ModelBase(modelType), transitionMatrix(transitionMatrix), stateLabeling(stateLabeling),
rewardModels(rewardModels), choiceLabeling(optionalChoiceLabeling) {
for (auto const& rewardModel : this->getRewardModels()) {
@ -32,7 +32,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: ModelBase(modelType), transitionMatrix(std::move(transitionMatrix)), stateLabeling(std::move(stateLabeling)),
rewardModels(std::move(rewardModels)), choiceLabeling(std::move(optionalChoiceLabeling)) {
for (auto const& rewardModel : this->getRewardModels()) {
@ -160,17 +160,17 @@ namespace storm {
}
template<typename ValueType, typename RewardModelType>
std::vector<LabelSet> const& Model<ValueType, RewardModelType>::getChoiceLabeling() const {
storm::models::sparse::ChoiceLabeling const& Model<ValueType, RewardModelType>::getChoiceLabeling() const {
return choiceLabeling.get();
}
template<typename ValueType, typename RewardModelType>
boost::optional<std::vector<LabelSet>> const& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() const {
boost::optional<storm::models::sparse::ChoiceLabeling> const& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() const {
return choiceLabeling;
}
template<typename ValueType, typename RewardModelType>
boost::optional<std::vector<LabelSet>>& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() {
boost::optional<storm::models::sparse::ChoiceLabeling>& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() {
return choiceLabeling;
}

17
src/storm/models/sparse/Model.h

@ -3,11 +3,11 @@
#include <vector>
#include <unordered_map>
#include <boost/container/flat_set.hpp>
#include <boost/optional.hpp>
#include "storm/models/ModelBase.h"
#include "storm/models/sparse/StateLabeling.h"
#include "storm/models/sparse/ChoiceLabeling.h"
#include "storm/storage/sparse/StateType.h"
#include "storm/storage/SparseMatrix.h"
#include "storm/utility/OsDetection.h"
@ -25,9 +25,6 @@ namespace storm {
namespace models {
namespace sparse {
// The type used for storing a set of labels.
typedef boost::container::flat_set<uint_fast64_t> LabelSet;
template<typename ValueType>
class StandardRewardModel;
@ -60,7 +57,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -75,7 +72,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
/*!
* Retrieves the backward transition relation of the model, i.e. a set of transitions between states
@ -227,21 +224,21 @@ namespace storm {
*
* @return The labels for the choices of the model.
*/
std::vector<LabelSet> const& getChoiceLabeling() const;
storm::models::sparse::ChoiceLabeling const& getChoiceLabeling() const;
/*!
* Retrieves an optional value that contains the choice labeling if there is one.
*
* @return The labels for the choices, if they're saved.
*/
boost::optional<std::vector<LabelSet>> const& getOptionalChoiceLabeling() const;
boost::optional<storm::models::sparse::ChoiceLabeling> const& getOptionalChoiceLabeling() const;
/*!
* Retrieves an optional value that contains the choice labeling if there is one.
*
* @return The labels for the choices, if they're saved.
*/
boost::optional<std::vector<LabelSet>>& getOptionalChoiceLabeling();
boost::optional<storm::models::sparse::ChoiceLabeling>& getOptionalChoiceLabeling();
/*!
* Returns the state labeling associated with this model.
@ -365,7 +362,7 @@ namespace storm {
std::unordered_map<std::string, RewardModelType> rewardModels;
// If set, a vector representing the labels of choices.
boost::optional<std::vector<LabelSet>> choiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
};
#ifdef STORM_HAVE_CARL

44
src/storm/models/sparse/NondeterministicModel.cpp

@ -15,7 +15,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling)
: Model<ValueType, RewardModelType>(modelType, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
// Intentionally left empty.
}
@ -25,7 +25,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling)
: Model<ValueType, RewardModelType>(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels),
std::move(optionalChoiceLabeling)) {
// Intentionally left empty.
@ -46,43 +46,7 @@ namespace storm {
auto indices = this->getNondeterministicChoiceIndices();
return indices[state+1] - indices[state];
}
template<typename ValueType, typename RewardModelType>
void NondeterministicModel<ValueType, RewardModelType>::modifyStateActionRewards(RewardModelType& rewardModel, std::map<std::pair<uint_fast64_t, LabelSet>, typename RewardModelType::ValueType> const& modifications) const {
STORM_LOG_THROW(rewardModel.hasStateActionRewards(), storm::exceptions::InvalidOperationException, "Cannot modify state-action rewards, because the reward model does not have state-action rewards.");
STORM_LOG_THROW(this->hasChoiceLabeling(), storm::exceptions::InvalidOperationException, "Cannot modify state-action rewards, because the model does not have an action labeling.");
std::vector<LabelSet> const& choiceLabels = this->getChoiceLabeling();
for (auto const& modification : modifications) {
uint_fast64_t stateIndex = modification.first.first;
for (uint_fast64_t row = this->getNondeterministicChoiceIndices()[stateIndex]; row < this->getNondeterministicChoiceIndices()[stateIndex + 1]; ++row) {
// If the action label of the row matches the requested one, we set the reward value accordingly.
if (choiceLabels[row] == modification.first.second) {
rewardModel.setStateActionRewardValue(row, modification.second);
}
}
}
}
template<typename ValueType, typename RewardModelType>
template<typename T>
void NondeterministicModel<ValueType, RewardModelType>::modifyStateActionRewards(std::string const& modelName, std::map<uint_fast64_t, T> const& modifications) {
RewardModelType& rewardModel = this->rewardModel(modelName);
size_t i = 0;
for(auto const& mod : modifications) {
std::cout << i++ << "/" << modifications.size() << std::endl;
rewardModel.setStateActionReward(mod.first, mod.second);
}
}
template<typename ValueType, typename RewardModelType>
template<typename T>
void NondeterministicModel<ValueType, RewardModelType>::modifyStateRewards(std::string const& modelName, std::map<uint_fast64_t, T> const& modifications) {
RewardModelType& rewardModel = this->rewardModel(modelName);
for(auto const& mod : modifications) {
rewardModel.setStateReward(mod.first, mod.second);
}
}
template<typename ValueType, typename RewardModelType>
void NondeterministicModel<ValueType, RewardModelType>::reduceToStateBasedRewards() {
for (auto& rewardModel : this->getRewardModels()) {
@ -173,11 +137,7 @@ namespace storm {
#ifdef STORM_HAVE_CARL
template class NondeterministicModel<storm::RationalNumber>;
template class NondeterministicModel<double, storm::models::sparse::StandardRewardModel<storm::Interval>>;
template void NondeterministicModel<double, storm::models::sparse::StandardRewardModel<storm::Interval>>::modifyStateActionRewards(std::string const& modelName, std::map<uint_fast64_t, double> const& modifications);
template void NondeterministicModel<double, storm::models::sparse::StandardRewardModel<storm::Interval>>::modifyStateRewards(std::string const& modelName, std::map<uint_fast64_t, double> const& modifications);
template class NondeterministicModel<storm::RationalFunction>;
#endif
}

19
src/storm/models/sparse/NondeterministicModel.h

@ -27,7 +27,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -42,7 +42,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalChoiceLabeling = boost::none);
NondeterministicModel(NondeterministicModel<ValueType, RewardModelType> const& other) = default;
NondeterministicModel& operator=(NondeterministicModel<ValueType, RewardModelType> const& other) = default;
@ -71,21 +71,6 @@ namespace storm {
*/
uint_fast64_t getNumberOfChoices(uint_fast64_t state) const;
/*!
* Modifies the state-action reward vector of the given reward model by setting the value specified in
* the map for the corresponding state-action pairs.
*
* @param rewardModel The reward model whose state-action rewards to modify.
* @param modifications A mapping from state-action pairs to the their new reward values.
*/
void modifyStateActionRewards(RewardModelType& rewardModel, std::map<std::pair<uint_fast64_t, LabelSet>, typename RewardModelType::ValueType> const& modifications) const;
template<typename T>
void modifyStateActionRewards(std::string const& modelName, std::map<uint_fast64_t, T> const& modifications);
template<typename T>
void modifyStateRewards(std::string const& modelName, std::map<uint_fast64_t, T> const& modifications);
virtual void reduceToStateBasedRewards() override;
virtual void printModelInformationToStream(std::ostream& out) const override;

12
src/storm/models/sparse/StochasticTwoPlayerGame.cpp

@ -13,8 +13,8 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& player2Matrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalPlayer1ChoiceLabeling,
boost::optional<std::vector<LabelSet>> const& optionalPlayer2ChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalPlayer1ChoiceLabeling,
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalPlayer2ChoiceLabeling)
: NondeterministicModel<ValueType>(storm::models::ModelType::S2pg, player2Matrix, stateLabeling, rewardModels, optionalPlayer2ChoiceLabeling), player1Matrix(player1Matrix), player1ChoiceLabeling(optionalPlayer1ChoiceLabeling) {
// Intentionally left empty.
}
@ -25,8 +25,8 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& player2Matrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalPlayer1ChoiceLabeling,
boost::optional<std::vector<LabelSet>>&& optionalPlayer2ChoiceLabeling)
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalPlayer1ChoiceLabeling,
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalPlayer2ChoiceLabeling)
: NondeterministicModel<ValueType>(storm::models::ModelType::S2pg, std::move(player2Matrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalPlayer2ChoiceLabeling)), player1Matrix(std::move(player1Matrix)), player1ChoiceLabeling(std::move(optionalPlayer1ChoiceLabeling)) {
// Intentionally left empty.
}
@ -47,7 +47,7 @@ namespace storm {
}
template <typename ValueType, typename RewardModelType>
std::vector<LabelSet> const& StochasticTwoPlayerGame<ValueType, RewardModelType>::getPlayer1ChoiceLabeling() const {
storm::models::sparse::ChoiceLabeling const& StochasticTwoPlayerGame<ValueType, RewardModelType>::getPlayer1ChoiceLabeling() const {
return player1ChoiceLabeling.get();
}
@ -57,7 +57,7 @@ namespace storm {
}
template <typename ValueType, typename RewardModelType>
std::vector<LabelSet> const& StochasticTwoPlayerGame<ValueType, RewardModelType>::getPlayer2ChoiceLabeling() const {
storm::models::sparse::ChoiceLabeling const& StochasticTwoPlayerGame<ValueType, RewardModelType>::getPlayer2ChoiceLabeling() const {
return this->getChoiceLabeling();
}

14
src/storm/models/sparse/StochasticTwoPlayerGame.h

@ -29,8 +29,8 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& player2Matrix,
storm::models::sparse::StateLabeling const& stateLabeling,
std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalPlayer1ChoiceLabeling = boost::optional<std::vector<LabelSet>>(),
boost::optional<std::vector<LabelSet>> const& optionalPlayer2ChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalPlayer1ChoiceLabeling = boost::none,
boost::optional<storm::models::sparse::ChoiceLabeling> const& optionalPlayer2ChoiceLabeling = boost::none);
/*!
* Constructs a model by moving the given data.
@ -46,8 +46,8 @@ namespace storm {
storm::storage::SparseMatrix<ValueType>&& player2Matrix,
storm::models::sparse::StateLabeling&& stateLabeling,
std::unordered_map<std::string, RewardModelType>&& rewardModels = std::unordered_map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalPlayer1ChoiceLabeling = boost::optional<std::vector<LabelSet>>(),
boost::optional<std::vector<LabelSet>>&& optionalPlayer2ChoiceLabeling = boost::optional<std::vector<LabelSet>>());
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalPlayer1ChoiceLabeling = boost::none,
boost::optional<storm::models::sparse::ChoiceLabeling>&& optionalPlayer2ChoiceLabeling = boost::none);
StochasticTwoPlayerGame(StochasticTwoPlayerGame const& other) = default;
StochasticTwoPlayerGame& operator=(StochasticTwoPlayerGame const& other) = default;
@ -82,7 +82,7 @@ namespace storm {
*
* @return A vector containing the labels of each player 1 choice.
*/
std::vector<LabelSet> const& getPlayer1ChoiceLabeling() const;
storm::models::sparse::ChoiceLabeling const& getPlayer1ChoiceLabeling() const;
/*!
* Retrieves whether the game has labels attached to player 2 states.
@ -96,7 +96,7 @@ namespace storm {
*
* @return A vector containing the labels of each player 2 choice.
*/
std::vector<LabelSet> const& getPlayer2ChoiceLabeling() const;
storm::models::sparse::ChoiceLabeling const& getPlayer2ChoiceLabeling() const;
private:
// A matrix that stores the player 1 choices. This matrix contains a row group for each player 1 node. Every
@ -107,7 +107,7 @@ namespace storm {
// An (optional) vector of labels attached to the choices of player 1. Each row of the matrix can be equipped
// with a set of labels to tag certain choices.
boost::optional<std::vector<LabelSet>> player1ChoiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> player1ChoiceLabeling;
// The matrix and labels for player 2 are stored in the superclass.
};

2
src/storm/parser/DeterministicModelParser.cpp

@ -60,7 +60,7 @@ namespace storm {
if (!stateRewardFilename.empty() || !transitionRewardFilename.empty()) {
rewardModels.insert(std::make_pair("", storm::models::sparse::StandardRewardModel<RewardValueType>(parserResult.stateRewards, boost::optional<std::vector<RewardValueType>>(), parserResult.transitionRewards)));
}
return storm::models::sparse::Ctmc<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(rewardModels), boost::optional<std::vector<boost::container::flat_set < uint_fast64_t>>>());
return storm::models::sparse::Ctmc<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(rewardModels), boost::none);
}
template class DeterministicModelParser<double, double>;

2
src/storm/parser/DirectEncodingParser.h

@ -79,7 +79,7 @@ namespace storm {
std::unordered_map<std::string, RewardModelType> rewardModels;
// A vector that stores a labeling for each choice.
boost::optional<std::vector<storm::models::sparse::LabelSet>> choiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
// The exit rates for MAs.
std::vector<ValueType> exitRates;

5
src/storm/parser/NondeterministicModelParser.cpp

@ -40,9 +40,10 @@ namespace storm {
}
// Only parse choice labeling if a file is given.
boost::optional<std::vector < storm::models::sparse::LabelSet>> choiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
if (!choiceLabelingFilename.empty()) {
choiceLabeling = std::move(storm::parser::SparseChoiceLabelingParser::parseChoiceLabeling(transitions.getRowGroupIndices(), choiceLabelingFilename));
STORM_LOG_ERROR("Parsing choice labels is currently not implemented"); // TODO
//choiceLabeling = std::move(storm::parser::SparseChoiceLabelingParser::parseChoiceLabeling(transitions.getRowGroupIndices(), choiceLabelingFilename));
}
// Construct the result.

2
src/storm/parser/NondeterministicModelParser.h

@ -64,7 +64,7 @@ namespace storm {
/*!
* Optional choice labeling.
*/
boost::optional<std::vector<storm::models::sparse::LabelSet>> choiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
};
/*!

5
src/storm/parser/SparseChoiceLabelingParser.cpp

@ -1,5 +1,6 @@
#include "storm/parser/SparseChoiceLabelingParser.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/WrongFormatException.h"
#include "storm/exceptions/OutOfRangeException.h"
#include "storm/exceptions/FileIoException.h"
@ -11,7 +12,7 @@ namespace storm {
using namespace storm::utility::cstring;
std::vector<storm::models::sparse::LabelSet> SparseChoiceLabelingParser::parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename) {
std::vector<boost::container::flat_set<uint_fast64_t>> SparseChoiceLabelingParser::parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename) {
// Open file.
MappedFile file(filename.c_str());
char const* buf = file.getData();
@ -19,7 +20,7 @@ namespace storm {
uint_fast64_t totalNumberOfChoices = nondeterministicChoiceIndices.back();
// Create choice labeling vector with given choice count.
std::vector<storm::models::sparse::LabelSet> result(totalNumberOfChoices);
std::vector<boost::container::flat_set<uint_fast64_t>> result(totalNumberOfChoices);
// Now parse state reward assignments.
uint_fast64_t state = 0;

6
src/storm/parser/SparseChoiceLabelingParser.h

@ -1,7 +1,9 @@
#ifndef STORM_PARSER_SPARSECHOICELABELINGPARSER_H_
#define STORM_PARSER_SPARSECHOICELABELINGPARSER_H_
#include "storm/models/sparse/Model.h"
#include <boost/container/flat_set.hpp>
#include <vector>
#include <string>
namespace storm {
namespace parser {
@ -18,7 +20,7 @@ namespace storm {
* @param filename The name of the file to parse.
* @return The resulting choice labeling.
*/
static std::vector<storm::models::sparse::LabelSet> parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename);
static std::vector<boost::container::flat_set<uint_fast64_t>> parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename);
};
}
}

15
src/storm/storage/sparse/ChoiceOrigins.cpp

@ -45,6 +45,10 @@ namespace storm {
return indexToIdentifier[choiceIndex];
}
uint_fast64_t ChoiceOrigins::getIdentifierForChoicesWithNoOrigin() {
return 0;
}
std::string const& ChoiceOrigins::getIdentifierInfo(uint_fast64_t identifier) const {
return identifierToInfo[identifier];
}
@ -60,8 +64,15 @@ namespace storm {
}
std::shared_ptr<ChoiceOrigins> ChoiceOrigins::selectChoices(std::vector<uint_fast64_t> const& selectedChoices) const {
std::vector<uint_fast64_t> indexToIdentifierMapping(selectedChoices.size());
storm::utility::vector::selectVectorValues(indexToIdentifierMapping, selectedChoices, indexToIdentifier);
std::vector<uint_fast64_t> indexToIdentifierMapping;
indexToIdentifierMapping.reserve(selectedChoices.size());
for (auto const& selectedChoice : selectedChoices){
if (selectedChoice < this->indexToIdentifier.size()) {
indexToIdentifierMapping.push_back(indexToIdentifier[selectedChoice]);
} else {
indexToIdentifierMapping.push_back(getIdentifierForChoicesWithNoOrigin());
}
}
return cloneWithNewIndexToIdentifierMapping(std::move(indexToIdentifierMapping));
}
}

6
src/storm/storage/sparse/ChoiceOrigins.h

@ -34,6 +34,12 @@ namespace storm {
*/
uint_fast64_t getIdentifier(uint_fast64_t choiceIndex) const;
/*
* Returns the identifier that is used for choices without an origin in the input specification
* E.g., Selfloops introduced on deadlock states
*/
static uint_fast64_t getIdentifierForChoicesWithNoOrigin();
/*
* Returns the information for the given choice origin identifier as a (human readable) string
*/

6
src/storm/storage/sparse/PrismChoiceOrigins.cpp

@ -1,16 +1,18 @@
#include "storm/storage/sparse/PrismChoiceOrigins.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidArgumentException.h"
namespace storm {
namespace storage {
namespace sparse {
PrismChoiceOrigins::PrismChoiceOrigins(std::shared_ptr<storm::prism::Program const> const& prismProgram, std::vector<uint_fast64_t> const& indexToIdentifierMapping, std::vector<std::string> const& identifierToInfoMapping, std::vector<CommandSet> const& identifierToCommandSetMapping) : ChoiceOrigins(indexToIdentifierMapping, identifierToInfoMapping), program(prismProgram), identifierToCommandSet(identifierToCommandSetMapping) {
// Intentionally left empty
STORM_LOG_THROW(identifierToCommandSet[this->getIdentifierForChoicesWithNoOrigin()].empty(), storm::exceptions::InvalidArgumentException, "The given command set for the choices without origin is non-empty");
}
PrismChoiceOrigins::PrismChoiceOrigins(std::shared_ptr<storm::prism::Program const> const& prismProgram, std::vector<uint_fast64_t>&& indexToIdentifierMapping, std::vector<std::string>&& identifierToInfoMapping, std::vector<CommandSet>&& identifierToCommandSetMapping) : ChoiceOrigins(std::move(indexToIdentifierMapping), std::move(identifierToInfoMapping)), program(prismProgram), identifierToCommandSet(std::move(identifierToCommandSetMapping)) {
// Intentionally left empty
STORM_LOG_THROW(identifierToCommandSet[this->getIdentifierForChoicesWithNoOrigin()].empty(), storm::exceptions::InvalidArgumentException, "The given command set for the choices without origin is non-empty");
}
bool PrismChoiceOrigins::isPrismChoiceOrigins() const {

88
src/storm/transformer/StateDuplicator.h

@ -59,24 +59,29 @@ namespace storm {
// Transform the ingedients of the model
storm::storage::SparseMatrix<typename SparseModelType::ValueType> matrix = transformMatrix(originalModel.getTransitionMatrix(), result, gateStates);
storm::models::sparse::StateLabeling labeling(matrix.getRowGroupCount());
for(auto const& label : originalModel.getStateLabeling().getLabels()){
storm::models::sparse::StateLabeling stateLabeling(matrix.getRowGroupCount());
for (auto const& label : originalModel.getStateLabeling().getLabels()) {
storm::storage::BitVector newBitVectorForLabel = transformStateBitVector(originalModel.getStateLabeling().getStates(label), result);
if(label=="init"){
if (label=="init") {
newBitVectorForLabel &= (result.firstCopy | result.gateStates);
}
labeling.addLabel(label, std::move(newBitVectorForLabel));
stateLabeling.addLabel(label, std::move(newBitVectorForLabel));
}
std::unordered_map<std::string, typename SparseModelType::RewardModelType> rewardModels;
for(auto const& rewardModel : originalModel.getRewardModels()){
for (auto const& rewardModel : originalModel.getRewardModels()) {
rewardModels.insert(std::make_pair(rewardModel.first, transformRewardModel(rewardModel.second, originalModel.getTransitionMatrix().getRowGroupIndices(), result, gateStates)));
}
boost::optional<std::vector<storm::models::sparse::LabelSet>> choiceLabeling;
if(originalModel.hasChoiceLabeling()){
choiceLabeling = transformActionValueVector<storm::models::sparse::LabelSet>(originalModel.getChoiceLabeling(), originalModel.getTransitionMatrix().getRowGroupIndices(), result);
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
if (originalModel.hasChoiceLabeling()) {
for (auto const& label : originalModel.getChoiceLabeling().getLabels()) {
storm::storage::BitVector newBitVectorForLabel = transformActionBitVector(originalModel.getChoiceLabeling().getChoices(label), originalModel.getTransitionMatrix().getRowGroupIndices(), result);
choiceLabeling->addLabel(label, std::move(newBitVectorForLabel));
}
}
result.model = std::make_shared<SparseModelType>(createTransformedModel(originalModel, result, matrix, labeling, rewardModels, choiceLabeling));
result.model = std::make_shared<SparseModelType>(createTransformedModel(originalModel, result, matrix, stateLabeling, rewardModels, choiceLabeling));
STORM_LOG_DEBUG("State duplicator is done. Resulting model has " << result.model->getNumberOfStates() << " states, where " << result.firstCopy.getNumberOfSetBits() << " are in the first copy.");
return result;
}
@ -109,9 +114,9 @@ namespace storm {
result.firstCopyOldToNewStateIndexMapping = std::vector<uint_fast64_t>(originalModel.getNumberOfStates(), std::numeric_limits<uint_fast64_t>::max());
result.secondCopyOldToNewStateIndexMapping = std::vector<uint_fast64_t>(originalModel.getNumberOfStates(), std::numeric_limits<uint_fast64_t>::max());
uint_fast64_t newState = 0;
for(auto const& oldState : result.reachableStates){
for (auto const& oldState : result.reachableStates) {
result.newToOldStateIndexMapping[newState] = oldState;
if(statesForFirstCopy.get(oldState)){
if (statesForFirstCopy.get(oldState)) {
result.firstCopyOldToNewStateIndexMapping[oldState] = newState;
} else {
result.secondCopyOldToNewStateIndexMapping[oldState] = newState;
@ -120,7 +125,7 @@ namespace storm {
}
// The remaining states are duplicates. All these states belong to the second copy.
for(auto const& oldState : result.duplicatedStates) {
for (auto const& oldState : result.duplicatedStates) {
result.newToOldStateIndexMapping[newState] = oldState;
result.secondCopyOldToNewStateIndexMapping[oldState] = newState;
++newState;
@ -136,13 +141,13 @@ namespace storm {
boost::optional<std::vector<ValueType>> stateRewardVector;
boost::optional<std::vector<ValueType>> stateActionRewardVector;
boost::optional<storm::storage::SparseMatrix<ValueType>> transitionRewardMatrix;
if(originalRewardModel.hasStateRewards()){
if (originalRewardModel.hasStateRewards()) {
stateRewardVector = transformStateValueVector(originalRewardModel.getStateRewardVector(), result);
}
if(originalRewardModel.hasStateActionRewards()){
if (originalRewardModel.hasStateActionRewards()) {
stateActionRewardVector = transformActionValueVector(originalRewardModel.getStateActionRewardVector(), originalRowGroupIndices, result);
}
if(originalRewardModel.hasTransitionRewards()){
if (originalRewardModel.hasTransitionRewards()) {
transitionRewardMatrix = transformMatrix(originalRewardModel.getTransitionRewardMatrix(), result, gateStates);
}
return RewardModelType(std::move(stateRewardVector), std::move(stateActionRewardVector), std::move(transitionRewardMatrix));
@ -154,7 +159,7 @@ namespace storm {
uint_fast64_t numStates = result.newToOldStateIndexMapping.size();
uint_fast64_t numRows = 0;
uint_fast64_t numEntries = 0;
for(auto const& oldState : result.newToOldStateIndexMapping){
for (auto const& oldState : result.newToOldStateIndexMapping) {
numRows += originalMatrix.getRowGroupSize(oldState);
numEntries += originalMatrix.getRowGroupEntryCount(oldState);
}
@ -162,22 +167,22 @@ namespace storm {
// Fill in the data
uint_fast64_t newRow = 0;
for(uint_fast64_t newState = 0; newState < numStates; ++newState){
if(!originalMatrix.hasTrivialRowGrouping()){
for (uint_fast64_t newState = 0; newState < numStates; ++newState) {
if (!originalMatrix.hasTrivialRowGrouping()) {
builder.newRowGroup(newRow);
}
uint_fast64_t oldState = result.newToOldStateIndexMapping[newState];
for (uint_fast64_t oldRow = originalMatrix.getRowGroupIndices()[oldState]; oldRow < originalMatrix.getRowGroupIndices()[oldState+1]; ++oldRow){
for(auto const& entry : originalMatrix.getRow(oldRow)){
if(result.firstCopy.get(newState) && !gateStates.get(entry.getColumn())){
for (uint_fast64_t oldRow = originalMatrix.getRowGroupIndices()[oldState]; oldRow < originalMatrix.getRowGroupIndices()[oldState+1]; ++oldRow) {
for (auto const& entry : originalMatrix.getRow(oldRow)) {
if (result.firstCopy.get(newState) && !gateStates.get(entry.getColumn())) {
builder.addNextValue(newRow, result.firstCopyOldToNewStateIndexMapping[entry.getColumn()], entry.getValue());
} else if (!result.duplicatedStates.get(entry.getColumn())){
} else if (!result.duplicatedStates.get(entry.getColumn())) {
builder.addNextValue(newRow, result.secondCopyOldToNewStateIndexMapping[entry.getColumn()], entry.getValue());
}
}
//To add values in the right order, transitions to duplicated states have to be added in a second run.
for(auto const& entry : originalMatrix.getRow(oldRow)){
if (result.secondCopy.get(newState) && result.duplicatedStates.get(entry.getColumn())){
for (auto const& entry : originalMatrix.getRow(oldRow)) {
if (result.secondCopy.get(newState) && result.duplicatedStates.get(entry.getColumn())) {
builder.addNextValue(newRow, result.secondCopyOldToNewStateIndexMapping[entry.getColumn()], entry.getValue());
}
}
@ -192,13 +197,13 @@ namespace storm {
template<typename ValueType = typename SparseModelType::ValueType>
static std::vector<ValueType> transformActionValueVector(std::vector<ValueType>const& originalVector, std::vector<uint_fast64_t> const& originalRowGroupIndices, StateDuplicatorReturnType const& result) {
uint_fast64_t numActions = 0;
for(auto const& oldState : result.newToOldStateIndexMapping){
for (auto const& oldState : result.newToOldStateIndexMapping) {
numActions += originalRowGroupIndices[oldState+1] - originalRowGroupIndices[oldState];
}
std::vector<ValueType> v;
v.reserve(numActions);
for(auto const& oldState : result.newToOldStateIndexMapping){
for (uint_fast64_t oldAction = originalRowGroupIndices[oldState]; oldAction < originalRowGroupIndices[oldState+1]; ++oldAction){
for (auto const& oldState : result.newToOldStateIndexMapping) {
for (uint_fast64_t oldAction = originalRowGroupIndices[oldState]; oldAction < originalRowGroupIndices[oldState+1]; ++oldAction) {
v.push_back(originalVector[oldAction]);
}
}
@ -211,17 +216,36 @@ namespace storm {
uint_fast64_t numStates = result.newToOldStateIndexMapping.size();
std::vector<ValueType> v;
v.reserve(numStates);
for(auto const& oldState : result.newToOldStateIndexMapping){
for (auto const& oldState : result.newToOldStateIndexMapping) {
v.push_back(originalVector[oldState]);
}
STORM_LOG_ASSERT(v.size() == numStates, "Unexpected vector size.");
return v;
}
static storm::storage::BitVector transformStateBitVector(storm::storage::BitVector const& originalBitVector, StateDuplicatorReturnType const& result) {
static storm::storage::BitVector transformActionBitVector(storm::storage::BitVector const& originalBitVector, std::vector<uint_fast64_t> const& originalRowGroupIndices, StateDuplicatorReturnType const& result) {
uint_fast64_t numActions = 0;
for (auto const& oldState : result.newToOldStateIndexMapping) {
numActions += originalRowGroupIndices[oldState+1] - originalRowGroupIndices[oldState];
}
storm::storage::BitVector bv(numActions, false);
uint_fast64_t newAction = 0;
for (auto const& oldState : result.newToOldStateIndexMapping) {
for (uint_fast64_t oldAction = originalRowGroupIndices[oldState]; oldAction < originalRowGroupIndices[oldState+1]; ++oldAction) {
if (originalBitVector.get(oldAction)) {
bv.set(newAction, true);
}
++newAction;
}
}
STORM_LOG_ASSERT(newAction == numActions, "Unexpected vector size.");
return bv;
}
static storm::storage::BitVector transformStateBitVector(storm::storage::BitVector const& originalBitVector, StateDuplicatorReturnType const& result) {
uint_fast64_t numStates = result.newToOldStateIndexMapping.size();
storm::storage::BitVector bv(numStates);
for(uint_fast64_t newState = 0; newState < numStates; ++newState){
for (uint_fast64_t newState = 0; newState < numStates; ++newState) {
uint_fast64_t oldState = result.newToOldStateIndexMapping[newState];
bv.set(newState, originalBitVector.get(oldState));
}
@ -241,7 +265,7 @@ namespace storm {
storm::models::sparse::StateLabeling& stateLabeling,
std::unordered_map<std::string,
typename MT::RewardModelType>& rewardModels,
boost::optional<std::vector<typename storm::models::sparse::LabelSet>>& choiceLabeling ) {
boost::optional<storm::models::sparse::ChoiceLabeling>& choiceLabeling ) {
return MT(std::move(matrix), std::move(stateLabeling), std::move(rewardModels), std::move(choiceLabeling));
}
@ -255,7 +279,7 @@ namespace storm {
storm::models::sparse::StateLabeling& stateLabeling,
std::unordered_map<std::string,
typename MT::RewardModelType>& rewardModels,
boost::optional<std::vector<typename storm::models::sparse::LabelSet>>& choiceLabeling ) {
boost::optional<storm::models::sparse::ChoiceLabeling>& choiceLabeling ) {
storm::storage::BitVector markovianStates = transformStateBitVector(originalModel.getMarkovianStates(), result);
std::vector<typename MT::ValueType> exitRates = transformStateValueVector(originalModel.getExitRates(), result);
return MT(std::move(matrix), std::move(stateLabeling), std::move(markovianStates), std::move(exitRates), true, std::move(rewardModels), std::move(choiceLabeling));

78
src/storm/transformer/SubsystemBuilder.h

@ -58,7 +58,7 @@ namespace storm {
uint_fast64_t subsystemStateCount = subsystemStates.getNumberOfSetBits();
STORM_LOG_THROW(subsystemStateCount != 0, storm::exceptions::InvalidArgumentException, "Invoked SubsystemBuilder for an empty subsystem.");
if(subsystemStateCount == subsystemStates.size() && subsystemActions.full()) {
if (subsystemStateCount == subsystemStates.size() && subsystemActions.full()) {
result.model = std::make_shared<SparseModelType>(originalModel);
result.newToOldStateIndexMapping = storm::utility::vector::buildVectorForRange(0, result.model->getNumberOfStates());
result.keptActions = storm::storage::BitVector(result.model->getTransitionMatrix().getRowCount(), true);
@ -67,13 +67,13 @@ namespace storm {
result.newToOldStateIndexMapping.reserve(subsystemStateCount);
result.keptActions = storm::storage::BitVector(originalModel.getTransitionMatrix().getRowCount(), false);
for(auto subsysState : subsystemStates) {
for (auto subsysState : subsystemStates) {
result.newToOldStateIndexMapping.push_back(subsysState);
bool stateHasOneChoiceLeft = false;
for(uint_fast64_t row = subsystemActions.getNextSetIndex(originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState]); row < originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState+1]; row = subsystemActions.getNextSetIndex(row+1)) {
for (uint_fast64_t row = subsystemActions.getNextSetIndex(originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState]); row < originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState+1]; row = subsystemActions.getNextSetIndex(row+1)) {
bool allRowEntriesStayInSubsys = true;
for(auto const& entry : originalModel.getTransitionMatrix().getRow(row)) {
if(!subsystemStates.get(entry.getColumn())) {
for (auto const& entry : originalModel.getTransitionMatrix().getRow(row)) {
if (!subsystemStates.get(entry.getColumn())) {
allRowEntriesStayInSubsys = false;
break;
}
@ -85,19 +85,15 @@ namespace storm {
}
// Transform the ingedients of the model
storm::storage::SparseMatrix<typename SparseModelType::ValueType> matrix = transformMatrix(originalModel.getTransitionMatrix(), subsystemStates, result.keptActions);
storm::models::sparse::StateLabeling labeling(matrix.getRowGroupCount());
for(auto const& label : originalModel.getStateLabeling().getLabels()){
storm::storage::BitVector newBitVectorForLabel = transformStateBitVector(originalModel.getStateLabeling().getStates(label), subsystemStates);
labeling.addLabel(label, std::move(newBitVectorForLabel));
}
storm::storage::SparseMatrix<typename SparseModelType::ValueType> matrix = originalModel.getTransitionMatrix().getSubmatrix(false, result.keptActions, subsystemStates);
storm::models::sparse::StateLabeling labeling = originalModel.getStateLabeling().getSubLabeling(subsystemStates);
std::unordered_map<std::string, typename SparseModelType::RewardModelType> rewardModels;
for(auto const& rewardModel : originalModel.getRewardModels()){
for (auto const& rewardModel : originalModel.getRewardModels()){
rewardModels.insert(std::make_pair(rewardModel.first, transformRewardModel(rewardModel.second, subsystemStates, result.keptActions)));
}
boost::optional<std::vector<storm::models::sparse::LabelSet>> choiceLabeling;
if(originalModel.hasChoiceLabeling()){
choiceLabeling = transformActionValueVector<storm::models::sparse::LabelSet>(originalModel.getChoiceLabeling(), result.keptActions);
boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
if (originalModel.hasChoiceLabeling()) {
choiceLabeling = originalModel.getChoiceLabeling().getSubLabeling(result.keptActions);
}
result.model = std::make_shared<SparseModelType>(createTransformedModel(originalModel, subsystemStates, matrix, labeling, rewardModels, choiceLabeling));
STORM_LOG_DEBUG("Subsystem Builder is done. Resulting model has " << result.model->getNumberOfStates() << " states.");
@ -111,49 +107,18 @@ namespace storm {
boost::optional<std::vector<ValueType>> stateRewardVector;
boost::optional<std::vector<ValueType>> stateActionRewardVector;
boost::optional<storm::storage::SparseMatrix<ValueType>> transitionRewardMatrix;
if(originalRewardModel.hasStateRewards()){
stateRewardVector = transformStateValueVector(originalRewardModel.getStateRewardVector(), subsystem);
if (originalRewardModel.hasStateRewards()){
stateRewardVector = storm::utility::vector::filterVector(originalRewardModel.getStateRewardVector(), subsystem);
}
if(originalRewardModel.hasStateActionRewards()){
stateActionRewardVector = transformActionValueVector(originalRewardModel.getStateActionRewardVector(), subsystemActions);
if (originalRewardModel.hasStateActionRewards()){
stateActionRewardVector = storm::utility::vector::filterVector(originalRewardModel.getStateActionRewardVector(), subsystemActions);
}
if(originalRewardModel.hasTransitionRewards()){
transitionRewardMatrix = transformMatrix(originalRewardModel.getTransitionRewardMatrix(), subsystem, subsystemActions);
if (originalRewardModel.hasTransitionRewards()){
transitionRewardMatrix = originalRewardModel.getTransitionRewardMatrix().getSubmatrix(false, subsystemActions, subsystem);
}
return RewardModelType(std::move(stateRewardVector), std::move(stateActionRewardVector), std::move(transitionRewardMatrix));
}
template<typename ValueType = typename SparseModelType::ValueType>
static storm::storage::SparseMatrix<ValueType> transformMatrix(storm::storage::SparseMatrix<ValueType> const& originalMatrix, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& subsystemActions) {
return originalMatrix.getSubmatrix(false, subsystemActions, subsystem);
}
template<typename ValueType = typename SparseModelType::ValueType>
static std::vector<ValueType> transformActionValueVector(std::vector<ValueType> const& originalVector, storm::storage::BitVector const& subsystemActions) {
std::vector<ValueType> v;
v.reserve(subsystemActions.getNumberOfSetBits());
for(auto action : subsystemActions){
v.push_back(originalVector[action]);
}
return v;
}
template<typename ValueType = typename SparseModelType::ValueType>
static std::vector<ValueType> transformStateValueVector(std::vector<ValueType> const& originalVector, storm::storage::BitVector const& subsystem) {
std::vector<ValueType> v;
v.reserve(subsystem.getNumberOfSetBits());
for(auto state : subsystem){
v.push_back(originalVector[state]);
}
return v;
}
static storm::storage::BitVector transformStateBitVector(storm::storage::BitVector const& originalBitVector, storm::storage::BitVector const& subsystem) {
return originalBitVector % subsystem;
}
template<typename MT = SparseModelType>
static typename std::enable_if<
std::is_same<MT,storm::models::sparse::Dtmc<typename SparseModelType::ValueType>>::value ||
@ -165,7 +130,7 @@ namespace storm {
storm::storage::SparseMatrix<typename MT::ValueType>& matrix,
storm::models::sparse::StateLabeling& stateLabeling,
std::unordered_map<std::string, typename MT::RewardModelType>& rewardModels,
boost::optional<std::vector<typename storm::models::sparse::LabelSet>>& choiceLabeling ) {
boost::optional<storm::models::sparse::ChoiceLabeling>& choiceLabeling ) {
return MT(std::move(matrix), std::move(stateLabeling), std::move(rewardModels), std::move(choiceLabeling));
}
@ -179,13 +144,12 @@ namespace storm {
storm::models::sparse::StateLabeling& stateLabeling,
std::unordered_map<std::string,
typename MT::RewardModelType>& rewardModels,
boost::optional<std::vector<typename storm::models::sparse::LabelSet>>& choiceLabeling ) {
storm::storage::BitVector markovianStates = transformStateBitVector(originalModel.getMarkovianStates(), subsystem);
std::vector<typename MT::ValueType> exitRates = transformStateValueVector(originalModel.getExitRates(), subsystem);
boost::optional<storm::models::sparse::ChoiceLabeling>& choiceLabeling ) {
storm::storage::BitVector markovianStates = originalModel.getMarkovianStates() % subsystem;
std::vector<typename MT::ValueType> exitRates = storm::utility::vector::filterVector(originalModel.getExitRates(), subsystem);
return MT(std::move(matrix), std::move(stateLabeling), std::move(markovianStates), std::move(exitRates), true, std::move(rewardModels), std::move(choiceLabeling));
}
};
}
}

2
src/storm/utility/ModelInstantiator.h

@ -103,7 +103,7 @@ namespace storm {
initializeModelSpecificData(PMT const& parametricModel) {
auto player1MatrixCopy = parametricModel.getPlayer1Matrix();
auto stateLabelingCopy = parametricModel.getStateLabeling();
boost::optional<std::vector<typename storm::models::sparse::LabelSet>> player1ChoiceLabeling, player2ChoiceLabeling;
boost::optional<storm::models::sparse::ChoiceLabeling> player1ChoiceLabeling, player2ChoiceLabeling;
if(parametricModel.hasPlayer1ChoiceLabeling()) player1ChoiceLabeling = parametricModel.getPlayer1ChoiceLabeling();
if(parametricModel.hasPlayer2ChoiceLabeling()) player2ChoiceLabeling = parametricModel.getPlayer2ChoiceLabeling();
this->instantiatedModel = std::make_shared<ConstantSparseModelType>(std::move(player1MatrixCopy), buildDummyMatrix(parametricModel.getTransitionMatrix()), std::move(stateLabelingCopy), buildDummyRewardModels(parametricModel.getRewardModels()), std::move(player1ChoiceLabeling), std::move(player2ChoiceLabeling));

45
src/storm/utility/counterexamples.h

@ -4,29 +4,30 @@
#include <queue>
#include <utility>
#include "storm/storage/sparse/PrismChoiceOrigins.h"
namespace storm {
namespace utility {
namespace counterexamples {
/*!
* Computes a set of action labels that is visited along all paths from any state to a target state.
* Computes a set of Prism commands that is executed along all paths from any state to a target state.
*
* @return The set of action labels that is visited on all paths from any state to a target state.
* @return The set of Prism commands that is visited on all paths from any state to a target state.
*/
template <typename T>
std::vector<boost::container::flat_set<uint_fast64_t>> getGuaranteedLabelSets(storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
std::vector<boost::container::flat_set<uint_fast64_t>> getGuaranteedCommandSets(storm::models::sparse::Mdp<T> const& mdp, storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& relevantCommands) {
// Get some data from the MDP for convenient access.
storm::storage::SparseMatrix<T> const& transitionMatrix = labeledMdp.getTransitionMatrix();
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = labeledMdp.getNondeterministicChoiceIndices();
std::vector<boost::container::flat_set<uint_fast64_t>> const& choiceLabeling = labeledMdp.getChoiceLabeling();
storm::storage::SparseMatrix<T> backwardTransitions = labeledMdp.getBackwardTransitions();
storm::storage::SparseMatrix<T> const& transitionMatrix = mdp.getTransitionMatrix();
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = mdp.getNondeterministicChoiceIndices();
storm::storage::SparseMatrix<T> backwardTransitions = mdp.getBackwardTransitions();
// Now we compute the set of labels that is present on all paths from the initial to the target states.
std::vector<boost::container::flat_set<uint_fast64_t>> analysisInformation(labeledMdp.getNumberOfStates(), relevantLabels);
// Now we compute the set of commands that is present on all paths from the initial to the target states.
std::vector<boost::container::flat_set<uint_fast64_t>> analysisInformation(mdp.getNumberOfStates(), relevantCommands);
std::queue<uint_fast64_t> worklist;
storm::storage::BitVector statesInWorkList(labeledMdp.getNumberOfStates());
storm::storage::BitVector markedStates(labeledMdp.getNumberOfStates());
storm::storage::BitVector statesInWorkList(mdp.getNumberOfStates());
storm::storage::BitVector markedStates(mdp.getNumberOfStates());
// Initially, put all predecessors of target states in the worklist and empty the analysis information them.
for (auto state : psiStates) {
@ -60,13 +61,13 @@ namespace storm {
// If we can reach the target state with this choice, we need to intersect the current
// analysis information with the union of the new analysis information of the target state
// and the choice labels.
// and the choice commands.
if (modifiedChoice) {
for (auto const& entry : transitionMatrix.getRow(currentChoice)) {
if (markedStates.get(entry.getColumn())) {
boost::container::flat_set<uint_fast64_t> tmpIntersection;
std::set_intersection(analysisInformation[currentState].begin(), analysisInformation[currentState].end(), analysisInformation[entry.getColumn()].begin(), analysisInformation[entry.getColumn()].end(), std::inserter(tmpIntersection, tmpIntersection.begin()));
std::set_intersection(analysisInformation[currentState].begin(), analysisInformation[currentState].end(), choiceLabeling[currentChoice].begin(), choiceLabeling[currentChoice].end(), std::inserter(tmpIntersection, tmpIntersection.begin()));
std::set_intersection(analysisInformation[currentState].begin(), analysisInformation[currentState].end(), choiceOrigins.getCommandSet(currentChoice).begin(), choiceOrigins.getCommandSet(currentChoice).end(), std::inserter(tmpIntersection, tmpIntersection.begin()));
analysisInformation[currentState] = std::move(tmpIntersection);
}
}
@ -96,22 +97,22 @@ namespace storm {
}
/*!
* Computes a set of action labels that is visited along all paths from an initial state to a target state.
* Computes a set of prism commands that is executed along all paths from an initial state to a target state.
*
* @return The set of action labels that is visited on all paths from an initial state to a target state.
* @return The set of prism commands that is executed on all paths from an initial state to a target state.
*/
template <typename T>
boost::container::flat_set<uint_fast64_t> getGuaranteedLabelSet(storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
std::vector<boost::container::flat_set<uint_fast64_t>> guaranteedLabels = getGuaranteedLabelSets(labeledMdp, psiStates, relevantLabels);
boost::container::flat_set<uint_fast64_t> getGuaranteedCommandSet(storm::models::sparse::Mdp<T> const& mdp, storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& relevantCommands) {
std::vector<boost::container::flat_set<uint_fast64_t>> guaranteedCommands = getGuaranteedCommandSets(mdp, choiceOrigins, psiStates, relevantCommands);
boost::container::flat_set<uint_fast64_t> knownLabels(relevantLabels);
boost::container::flat_set<uint_fast64_t> knownCommands(relevantCommands);
boost::container::flat_set<uint_fast64_t> tempIntersection;
for (auto initialState : labeledMdp.getInitialStates()) {
std::set_intersection(knownLabels.begin(), knownLabels.end(), guaranteedLabels[initialState].begin(), guaranteedLabels[initialState].end(), std::inserter(tempIntersection, tempIntersection.end()));
std::swap(knownLabels, tempIntersection);
for (auto initialState : mdp.getInitialStates()) {
std::set_intersection(knownCommands.begin(), knownCommands.end(), guaranteedCommands[initialState].begin(), guaranteedCommands[initialState].end(), std::inserter(tempIntersection, tempIntersection.end()));
std::swap(knownCommands, tempIntersection);
}
return knownLabels;
return knownCommands;
}
} // namespace counterexample

24
src/storm/utility/storm.h

@ -86,7 +86,7 @@
#include "storm/transformer/ContinuousToDiscreteTimeModelTransformer.h"
// Headers for counterexample generation.
#include "storm/counterexamples/MILPMinimalLabelSetGenerator.h"
#include "storm/counterexamples/MILPMinimalCommandSetGenerator.h"
#include "storm/counterexamples/SMTMinimalCommandSetGenerator.h"
// Headers related to model building.
@ -135,18 +135,19 @@ namespace storm {
std::vector<storm::jani::Property> filterProperties(std::vector<storm::jani::Property> const& properties, boost::optional<std::set<std::string>> const& propertyFilter);
template<typename ValueType>
std::shared_ptr<storm::models::sparse::Model<ValueType>> buildSparseModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
storm::builder::ExplicitModelBuilderResult<ValueType> buildSparseModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
storm::builder::BuilderOptions options(formulas);
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isBuildFullModelSet()) {
options.setBuildAllLabels();
options.setBuildAllRewardModels();
options.setBuildChoiceLabels(true);
options.clearTerminalStates();
}
// Generate command labels if we are going to build a counterexample later.
if (storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isMinimalCommandSetGenerationSet()) {
options.setBuildChoiceLabels(true);
options.setBuildChoiceOrigins(true);
}
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isJitSet()) {
@ -171,7 +172,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot build sparse model from this symbolic model description.");
}
storm::builder::ExplicitModelBuilder<ValueType> builder(generator);
return builder.build().getModel();
return builder.build();
}
}
@ -259,6 +260,7 @@ namespace storm {
ma->close();
if (ma->hasOnlyTrivialNondeterminism()) {
// Markov automaton can be converted into CTMC.
STORM_PRINT_AND_LOG(std::endl << "Converting deterministic MA to a CTMC..." << std::endl);
model = ma->convertToCTMC();
}
}
@ -285,7 +287,7 @@ namespace storm {
}
template<typename ValueType>
void generateCounterexample(storm::storage::SymbolicModelDescription const& model, std::shared_ptr<storm::models::sparse::Model<ValueType>> markovModel, std::shared_ptr<storm::logic::Formula const> const& formula) {
void generateCounterexample(storm::storage::SymbolicModelDescription const& model, std::shared_ptr<storm::models::sparse::Model<ValueType>> markovModel, std::shared_ptr<storm::storage::sparse::ChoiceOrigins> choiceOrigins, std::shared_ptr<storm::logic::Formula const> const& formula) {
if (storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isMinimalCommandSetGenerationSet()) {
STORM_LOG_THROW(model.isPrismProgram(), storm::exceptions::InvalidTypeException, "Minimal command set generation is only available for PRISM models.");
STORM_LOG_THROW(markovModel->getType() == storm::models::ModelType::Mdp, storm::exceptions::InvalidTypeException, "Minimal command set generation is only available for MDPs.");
@ -297,9 +299,9 @@ namespace storm {
bool useMILP = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseMilpBasedMinimalCommandSetGenerationSet();
if (useMILP) {
storm::counterexamples::MILPMinimalLabelSetGenerator<ValueType>::computeCounterexample(program, *mdp, formula);
storm::counterexamples::MILPMinimalCommandSetGenerator<ValueType>::computeCounterexample(program, *mdp, choiceOrigins, formula);
} else {
storm::counterexamples::SMTMinimalCommandSetGenerator<ValueType>::computeCounterexample(program, storm::settings::getModule<storm::settings::modules::IOSettings>().getConstantDefinitionString(), *mdp, formula);
storm::counterexamples::SMTMinimalCommandSetGenerator<ValueType>::computeCounterexample(program, storm::settings::getModule<storm::settings::modules::IOSettings>().getConstantDefinitionString(), *mdp, choiceOrigins, formula);
}
} else {
@ -309,20 +311,20 @@ namespace storm {
#ifdef STORM_HAVE_CARL
template<>
inline void generateCounterexample(storm::storage::SymbolicModelDescription const&, std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> , std::shared_ptr<storm::logic::Formula const> const& ) {
inline void generateCounterexample(storm::storage::SymbolicModelDescription const&, std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> , std::shared_ptr<storm::storage::sparse::ChoiceOrigins>, std::shared_ptr<storm::logic::Formula const> const& ) {
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unable to generate counterexample for exact arithmetic model.");
}
template<>
inline void generateCounterexample(storm::storage::SymbolicModelDescription const&, std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> , std::shared_ptr<storm::logic::Formula const> const& ) {
inline void generateCounterexample(storm::storage::SymbolicModelDescription const&, std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> , std::shared_ptr<storm::storage::sparse::ChoiceOrigins>, std::shared_ptr<storm::logic::Formula const> const& ) {
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unable to generate counterexample for parametric model.");
}
#endif
template<typename ValueType>
void generateCounterexamples(storm::storage::SymbolicModelDescription const& model, std::shared_ptr<storm::models::sparse::Model<ValueType>> markovModel, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
void generateCounterexamples(storm::storage::SymbolicModelDescription const& model, std::shared_ptr<storm::models::sparse::Model<ValueType>> markovModel, std::shared_ptr<storm::storage::sparse::ChoiceOrigins> choiceOrigins, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
for (auto const& formula : formulas) {
generateCounterexample(model, markovModel, formula);
generateCounterexample(model, markovModel, choiceOrigins, formula);
}
}

40
src/test/builder/ExplicitJitJaniModelBuilderTest.cpp

@ -14,31 +14,31 @@ TEST(ExplicitJitJaniModelBuilderTest, Dtmc) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm");
storm::jani::Model janiModel = program.toJani();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(13ul, model->getNumberOfStates());
EXPECT_EQ(20ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/brp-16-2.pm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(677ul, model->getNumberOfStates());
EXPECT_EQ(867ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/crowds-5-5.pm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(8607ul, model->getNumberOfStates());
EXPECT_EQ(15113ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/leader-3-5.pm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(273ul, model->getNumberOfStates());
EXPECT_EQ(397ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/nand-5-2.pm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(1728ul, model->getNumberOfStates());
EXPECT_EQ(2505ul, model->getNumberOfTransitions());
}
@ -50,31 +50,31 @@ TEST(ExplicitJitJaniModelBuilderTest, Ctmc) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ctmc/cluster2.sm");
storm::jani::Model janiModel = program.toJani();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(276ul, model->getNumberOfStates());
EXPECT_EQ(1120ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ctmc/embedded2.sm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(3478ul, model->getNumberOfStates());
EXPECT_EQ(14639ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ctmc/polling2.sm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(12ul, model->getNumberOfStates());
EXPECT_EQ(22ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ctmc/fms2.sm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(810ul, model->getNumberOfStates());
EXPECT_EQ(3699ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ctmc/tandem5.sm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(66ul, model->getNumberOfStates());
EXPECT_EQ(189ul, model->getNumberOfTransitions());
}
@ -83,37 +83,37 @@ TEST(ExplicitJitJaniModelBuilderTest, Mdp) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/two_dice.nm");
storm::jani::Model janiModel = program.toJani();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(169ul, model->getNumberOfStates());
EXPECT_EQ(436ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/leader3.nm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(364ul, model->getNumberOfStates());
EXPECT_EQ(654ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/coin2-2.nm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(272ul, model->getNumberOfStates());
EXPECT_EQ(492ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/csma2-2.nm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(1038ul, model->getNumberOfStates());
EXPECT_EQ(1282ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/firewire3-0.5.nm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(4093ul, model->getNumberOfStates());
EXPECT_EQ(5585ul, model->getNumberOfTransitions());
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/wlan0-2-2.nm");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(37ul, model->getNumberOfStates());
EXPECT_EQ(59ul, model->getNumberOfTransitions());
}
@ -122,7 +122,7 @@ TEST(ExplicitJitJaniModelBuilderTest, Ma) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ma/simple.ma");
storm::jani::Model janiModel = program.toJani();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(5ul, model->getNumberOfStates());
EXPECT_EQ(8ul, model->getNumberOfTransitions());
ASSERT_TRUE(model->isOfType(storm::models::ModelType::MarkovAutomaton));
@ -130,7 +130,7 @@ TEST(ExplicitJitJaniModelBuilderTest, Ma) {
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ma/hybrid_states.ma");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(5ul, model->getNumberOfStates());
EXPECT_EQ(13ul, model->getNumberOfTransitions());
ASSERT_TRUE(model->isOfType(storm::models::ModelType::MarkovAutomaton));
@ -138,7 +138,7 @@ TEST(ExplicitJitJaniModelBuilderTest, Ma) {
program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/ma/stream2.ma");
janiModel = program.toJani();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build();
model = storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();;
EXPECT_EQ(12ul, model->getNumberOfStates());
EXPECT_EQ(14ul, model->getNumberOfTransitions());
ASSERT_TRUE(model->isOfType(storm::models::ModelType::MarkovAutomaton));
@ -149,7 +149,7 @@ TEST(ExplicitJitJaniModelBuilderTest, FailComposition) {
storm::prism::Program program = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/mdp/system_composition.nm");
storm::jani::Model janiModel = program.toJani();
ASSERT_THROW(storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build(), storm::exceptions::WrongFormatException);
ASSERT_THROW(storm::builder::jit::ExplicitJitJaniModelBuilder<double>(janiModel).build().getModel();, storm::exceptions::WrongFormatException);
}
TEST(ExplicitJitJaniModelBuilderTest, IllegalSynchronizingWrites) {

24
src/test/modelchecker/SparseDtmcParameterLiftingTest.cpp

@ -17,7 +17,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Prob) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -47,7 +47,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Rew) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -77,7 +77,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Rew_Bounded) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -108,7 +108,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Prob_exactValidation) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -141,7 +141,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Rew_exactValidation) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -174,7 +174,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Rew_Bounded_exactValidation) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -207,7 +207,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Rew_Infty) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -233,7 +233,7 @@ TEST(SparseDtmcParameterLiftingTest, Brp_Rew_4Par) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -264,7 +264,7 @@ TEST(SparseDtmcParameterLiftingTest, Crowds_Prob) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -297,7 +297,7 @@ TEST(SparseDtmcParameterLiftingTest, Crowds_Prob_stepBounded) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -331,7 +331,7 @@ TEST(SparseDtmcParameterLiftingTest, Crowds_Prob_1Par) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -362,7 +362,7 @@ TEST(SparseDtmcParameterLiftingTest, Crowds_Prob_Const) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Dtmc<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);

10
src/test/modelchecker/SparseMaPcaaModelCheckerTest.cpp

@ -56,7 +56,7 @@ TEST(SparseMaPcaaModelCheckerTest, server) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::MarkovAutomaton<double>>();
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::MarkovAutomaton<double>>();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*ma, formulas[0]->asMultiObjectiveFormula());
ASSERT_TRUE(result->isExplicitParetoCurveCheckResult());
@ -85,7 +85,7 @@ TEST(SparseMaPcaaModelCheckerTest, jobscheduler_pareto_3Obj) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::MarkovAutomaton<double>>();
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::MarkovAutomaton<double>>();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*ma, formulas[0]->asMultiObjectiveFormula());
ASSERT_TRUE(result->isExplicitParetoCurveCheckResult());
@ -116,7 +116,7 @@ TEST(SparseMaPcaaModelCheckerTest, jobscheduler_achievability_3Obj) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::MarkovAutomaton<double>>();
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::MarkovAutomaton<double>>();
uint_fast64_t const initState = *ma->getInitialStates().begin();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*ma, formulas[0]->asMultiObjectiveFormula());
@ -137,7 +137,7 @@ TEST(SparseMaPcaaModelCheckerTest, jobscheduler_quantitative_3Obj) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::MarkovAutomaton<double>>();
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::MarkovAutomaton<double>>();
uint_fast64_t const initState = *ma->getInitialStates().begin();
@ -158,7 +158,7 @@ TEST(SparseMaPcaaModelCheckerTest, jobscheduler_pareto_2Obj) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::MarkovAutomaton<double>>();
std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::MarkovAutomaton<double>>();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*ma, formulas[0]->asMultiObjectiveFormula());
ASSERT_TRUE(result->isExplicitParetoCurveCheckResult());

20
src/test/modelchecker/SparseMdpParameterLiftingTest.cpp

@ -16,7 +16,7 @@ TEST(SparseMdpParameterLiftingTest, two_dice_Prob) {
storm::prism::Program program = storm::parseProgram(programFile);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaFile, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -46,7 +46,7 @@ TEST(SparseMdpParameterLiftingTest, two_dice_Prob_bounded) {
storm::prism::Program program = storm::parseProgram(programFile);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaFile, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -76,7 +76,7 @@ TEST(SparseMdpParameterLiftingTest, two_dice_Prob_exactValidation) {
storm::prism::Program program = storm::parseProgram(programFile);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaFile, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -106,7 +106,7 @@ TEST(SparseMdpParameterLiftingTest, two_dice_Prob_bounded_exactValidation) {
storm::prism::Program program = storm::parseProgram(programFile);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaFile, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -134,7 +134,7 @@ TEST(SparseMdpParameterLiftingTest, coin_Prob) {
storm::prism::Program program = storm::parseProgram(programFile);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -164,7 +164,7 @@ TEST(SparseMdpParameterLiftingTest, brp_Prop) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -195,7 +195,7 @@ TEST(SparseMdpParameterLiftingTest, brp_Rew) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -225,7 +225,7 @@ TEST(SparseMdpParameterLiftingTest, brp_Rew_bounded) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -256,7 +256,7 @@ TEST(SparseMdpParameterLiftingTest, Brp_Rew_Infty) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);
@ -282,7 +282,7 @@ TEST(SparseMdpParameterLiftingTest, Brp_Rew_4Par) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, constantsAsString);
std::vector<std::shared_ptr<const storm::logic::Formula>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas)->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> model = storm::buildSparseModel<storm::RationalFunction>(program, formulas).getModel()->as<storm::models::sparse::Mdp<storm::RationalFunction>>();
auto modelParameters = storm::models::sparse::getProbabilityParameters(*model);
auto rewParameters = storm::models::sparse::getRewardParameters(*model);

10
src/test/modelchecker/SparseMdpPcaaModelCheckerTest.cpp

@ -23,7 +23,7 @@ TEST(SparseMdpPcaaModelCheckerTest, consensus) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::Mdp<double>>();
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::Mdp<double>>();
uint_fast64_t const initState = *mdp->getInitialStates().begin();;
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*mdp, formulas[0]->asMultiObjectiveFormula());
@ -49,7 +49,7 @@ TEST(SparseMdpPcaaModelCheckerTest, zeroconf) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::Mdp<double>>();
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::Mdp<double>>();
uint_fast64_t const initState = *mdp->getInitialStates().begin();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*mdp, formulas[0]->asMultiObjectiveFormula());
@ -66,7 +66,7 @@ TEST(SparseMdpPcaaModelCheckerTest, team3with3objectives) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::Mdp<double>>();
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::Mdp<double>>();
uint_fast64_t const initState = *mdp->getInitialStates().begin();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*mdp, formulas[0]->asMultiObjectiveFormula());
@ -83,7 +83,7 @@ TEST(SparseMdpPcaaModelCheckerTest, scheduler) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::Mdp<double>>();
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::Mdp<double>>();
uint_fast64_t const initState = *mdp->getInitialStates().begin();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*mdp, formulas[0]->asMultiObjectiveFormula());
@ -99,7 +99,7 @@ TEST(SparseMdpPcaaModelCheckerTest, dpm) {
storm::prism::Program program = storm::parseProgram(programFile);
program = storm::utility::prism::preprocess(program, "");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulasAsString, program));
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas)->as<storm::models::sparse::Mdp<double>>();
std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = storm::buildSparseModel<double>(program, formulas).getModel()->as<storm::models::sparse::Mdp<double>>();
uint_fast64_t const initState = *mdp->getInitialStates().begin();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::modelchecker::multiobjective::performPcaa(*mdp, formulas[0]->asMultiObjectiveFormula());

Loading…
Cancel
Save