From f3fa90cc37c6fac5b8f2397a04591269b95ef005 Mon Sep 17 00:00:00 2001 From: dehnert <dehnert@cs.rwth-aachen.de> Date: Tue, 21 Jun 2016 17:02:15 +0200 Subject: [PATCH] more work towards exact solving Former-commit-id: 38edbcf2ca25e0eeeeb880ca2ded6cd920eada6e --- src/adapters/CarlAdapter.h | 6 +- src/builder/ExplicitModelBuilder.cpp | 5 +- src/cli/entrypoints.h | 26 ++- src/generator/Choice.cpp | 1 + src/generator/CompressedState.cpp | 1 + src/generator/JaniNextStateGenerator.cpp | 1 + src/generator/NextStateGenerator.cpp | 6 + src/generator/NextStateGenerator.h | 6 + src/generator/PrismNextStateGenerator.cpp | 29 +++- src/generator/PrismNextStateGenerator.h | 2 + src/generator/StateBehavior.cpp | 1 + .../csl/SparseCtmcCslModelChecker.cpp | 2 + .../csl/helper/SparseCtmcCslHelper.cpp | 5 +- .../prctl/SparseDtmcPrctlModelChecker.cpp | 1 + .../prctl/helper/SparseDtmcPrctlHelper.cpp | 5 +- .../SparsePropositionalModelChecker.cpp | 8 +- .../SparseDtmcEliminationModelChecker.cpp | 4 +- .../ExplicitQuantitativeCheckResult.cpp | 20 +-- src/models/sparse/Ctmc.cpp | 4 +- src/models/sparse/DeterministicModel.cpp | 4 +- src/models/sparse/Dtmc.cpp | 158 +----------------- src/models/sparse/Dtmc.h | 7 - src/models/sparse/MarkovAutomaton.cpp | 4 +- src/models/sparse/Mdp.cpp | 4 +- src/models/sparse/Model.cpp | 7 +- src/models/sparse/NondeterministicModel.cpp | 3 +- src/models/sparse/StandardRewardModel.cpp | 11 +- .../ConditionalStateEliminator.cpp | 4 +- .../DynamicStatePriorityQueue.cpp | 4 +- .../LongRunAverageEliminator.cpp | 4 +- .../PrioritizedStateEliminator.cpp | 3 - .../stateelimination/StateEliminator.cpp | 3 - src/storage/Distribution.cpp | 7 +- ...tronglyConnectedComponentDecomposition.cpp | 7 +- .../BisimulationDecomposition.cpp | 8 +- ...ministicModelBisimulationDecomposition.cpp | 7 +- ...ministicModelBisimulationDecomposition.cpp | 4 +- .../expressions/ExpressionEvaluator.cpp | 38 +++-- src/storage/expressions/ExpressionEvaluator.h | 36 +++- .../expressions/ExpressionEvaluatorBase.cpp | 3 +- .../expressions/ExprtkExpressionEvaluator.cpp | 3 +- .../expressions/ToRationalFunctionVisitor.cpp | 4 - .../expressions/ToRationalFunctionVisitor.h | 2 - .../expressions/ToRationalNumberVisitor.cpp | 91 ++++++++++ .../expressions/ToRationalNumberVisitor.h | 31 ++++ src/utility/constants.cpp | 22 ++- src/utility/graph.cpp | 58 ++++++- src/utility/solver.cpp | 15 +- src/utility/solver.h | 14 +- src/utility/stateelimination.cpp | 7 +- src/utility/storm.h | 72 ++++++-- .../EigenDtmcPrctlModelCheckerTest.cpp | 8 +- 52 files changed, 477 insertions(+), 309 deletions(-) create mode 100644 src/storage/expressions/ToRationalNumberVisitor.cpp create mode 100644 src/storage/expressions/ToRationalNumberVisitor.h diff --git a/src/adapters/CarlAdapter.h b/src/adapters/CarlAdapter.h index 5b7225a15..fb0a45749 100644 --- a/src/adapters/CarlAdapter.h +++ b/src/adapters/CarlAdapter.h @@ -30,8 +30,8 @@ namespace carl { return h(p); } - template<typename Pol> - inline size_t hash_value(carl::RationalFunction<Pol> const& f) { + template<typename Pol, bool AutoSimplify> + inline size_t hash_value(carl::RationalFunction<Pol, AutoSimplify> const& f) { std::hash<Pol> h; return h(f.nominator()) ^ h(f.denominator()); } @@ -62,7 +62,7 @@ namespace storm { typedef carl::FactorizedPolynomial<RawPolynomial> Polynomial; typedef carl::Relation CompareRelation; - typedef carl::RationalFunction<Polynomial> RationalFunction; + typedef carl::RationalFunction<Polynomial, true> RationalFunction; typedef carl::Interval<double> Interval; template<typename T> using ArithConstraint = carl::SimpleConstraint<T>; } diff --git a/src/builder/ExplicitModelBuilder.cpp b/src/builder/ExplicitModelBuilder.cpp index 352694187..f5cb33aca 100644 --- a/src/builder/ExplicitModelBuilder.cpp +++ b/src/builder/ExplicitModelBuilder.cpp @@ -134,7 +134,7 @@ namespace storm { result = std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>>(new storm::models::sparse::Mdp<ValueType, RewardModelType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), std::move(modelComponents.rewardModels), std::move(modelComponents.choiceLabeling))); break; default: - STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Error while creating model from probabilistic program: cannot handle this model type."); + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Error while creating model: cannot handle this model type."); break; } @@ -352,10 +352,9 @@ namespace storm { // Explicitly instantiate the class. template class ExplicitModelBuilder<double, storm::models::sparse::StandardRewardModel<double>, uint32_t>; + template class ExplicitModelBuilder<RationalNumber, storm::models::sparse::StandardRewardModel<RationalNumber>, uint32_t>; -#ifdef STORM_HAVE_CARL template class ExplicitModelBuilder<double, storm::models::sparse::StandardRewardModel<storm::Interval>, uint32_t>; template class ExplicitModelBuilder<RationalFunction, storm::models::sparse::StandardRewardModel<RationalFunction>, uint32_t>; -#endif } } diff --git a/src/cli/entrypoints.h b/src/cli/entrypoints.h index 41dfd2ab1..84b7fb753 100644 --- a/src/cli/entrypoints.h +++ b/src/cli/entrypoints.h @@ -146,7 +146,7 @@ namespace storm { } #define BRANCH_ON_SPARSE_MODELTYPE(result, model, value_type, function, ...) \ - STORM_LOG_ASSERT(model->isSparseModel(), "Unknown model type."); \ + STORM_LOG_ASSERT(model->isSparseModel(), "Illegal model type."); \ if (model->isOfType(storm::models::ModelType::Dtmc)) { \ result = function<storm::models::sparse::Dtmc<value_type>>(model->template as<storm::models::sparse::Dtmc<value_type>>(), __VA_ARGS__); \ } else if (model->isOfType(storm::models::ModelType::Ctmc)) { \ @@ -178,19 +178,21 @@ namespace storm { template<typename ValueType> void buildAndCheckSymbolicModelWithSparseEngine(storm::prism::Program const& program, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool onlyInitialStatesRelevant = false) { // Start by building the model. - auto model = buildSparseModel<ValueType>(program, formulas); + std::shared_ptr<storm::models::ModelBase> model = buildSparseModel<ValueType>(program, formulas); // Print some information about the model. model->printModelInformationToStream(std::cout); - + // Preprocess the model. BRANCH_ON_SPARSE_MODELTYPE(model, model, ValueType, preprocessModel, formulas); + std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel = model->template as<storm::models::sparse::Model<ValueType>>(); + // Finally, treat the formulas. if (storm::settings::getModule<storm::settings::modules::MarkovChainSettings>().isCounterexampleSet()) { - generateCounterexamples<ValueType>(program, formulas); + generateCounterexamples<ValueType>(program, sparseModel, formulas); } else { - verifySparseModel<ValueType>(model, formulas, onlyInitialStatesRelevant); + verifySparseModel<ValueType>(sparseModel, formulas, onlyInitialStatesRelevant); } } @@ -221,7 +223,19 @@ namespace storm { } } } - + + template<> + void buildAndCheckSymbolicModel<storm::RationalNumber>(storm::prism::Program const& program, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool onlyInitialStatesRelevant) { + STORM_LOG_THROW(storm::settings::getModule<storm::settings::modules::MarkovChainSettings>().getEngine() == storm::settings::modules::MarkovChainSettings::Engine::Sparse, storm::exceptions::InvalidSettingsException, "Cannot use this data type with an engine different than the sparse one."); + buildAndCheckSymbolicModelWithSparseEngine<storm::RationalNumber>(program, formulas, onlyInitialStatesRelevant); + } + + template<> + void buildAndCheckSymbolicModel<storm::RationalFunction>(storm::prism::Program const& program, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool onlyInitialStatesRelevant) { + STORM_LOG_THROW(storm::settings::getModule<storm::settings::modules::MarkovChainSettings>().getEngine() == storm::settings::modules::MarkovChainSettings::Engine::Sparse, storm::exceptions::InvalidSettingsException, "Cannot use this data type with an engine different than the sparse one."); + buildAndCheckSymbolicModelWithSparseEngine<storm::RationalFunction>(program, formulas, onlyInitialStatesRelevant); + } + template<typename ValueType> void buildAndCheckExplicitModel(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool onlyInitialStatesRelevant = false) { storm::settings::modules::IOSettings const& settings = storm::settings::getModule<storm::settings::modules::IOSettings>(); diff --git a/src/generator/Choice.cpp b/src/generator/Choice.cpp index 9202f2c5e..7a209ccc4 100644 --- a/src/generator/Choice.cpp +++ b/src/generator/Choice.cpp @@ -100,6 +100,7 @@ namespace storm { } template class Choice<double>; + template class Choice<storm::RationalNumber>; template class Choice<storm::RationalFunction>; } } \ No newline at end of file diff --git a/src/generator/CompressedState.cpp b/src/generator/CompressedState.cpp index 03ba3d4c7..3a229112f 100644 --- a/src/generator/CompressedState.cpp +++ b/src/generator/CompressedState.cpp @@ -30,6 +30,7 @@ namespace storm { } template void unpackStateIntoEvaluator<double>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<double>& evaluator); + template void unpackStateIntoEvaluator<storm::RationalNumber>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<storm::RationalNumber>& evaluator); template void unpackStateIntoEvaluator<storm::RationalFunction>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<storm::RationalFunction>& evaluator); storm::expressions::SimpleValuation unpackStateIntoValuation(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionManager const& manager); } diff --git a/src/generator/JaniNextStateGenerator.cpp b/src/generator/JaniNextStateGenerator.cpp index 7202ebcc7..9e0f10b7f 100644 --- a/src/generator/JaniNextStateGenerator.cpp +++ b/src/generator/JaniNextStateGenerator.cpp @@ -492,6 +492,7 @@ namespace storm { } template class JaniNextStateGenerator<double>; + template class JaniNextStateGenerator<storm::RationalNumber>; template class JaniNextStateGenerator<storm::RationalFunction>; } diff --git a/src/generator/NextStateGenerator.cpp b/src/generator/NextStateGenerator.cpp index 00b8d794c..a99f0dcea 100644 --- a/src/generator/NextStateGenerator.cpp +++ b/src/generator/NextStateGenerator.cpp @@ -216,6 +216,11 @@ namespace storm { // Intentionally left empty. } + template<typename ValueType, typename StateType> + NextStateGenerator<ValueType, StateType>::NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, NextStateGeneratorOptions const& options) : options(options), expressionManager(expressionManager.getSharedPointer()), variableInformation(), evaluator(expressionManager), state(nullptr) { + // Intentionally left empty. + } + template<typename ValueType, typename StateType> NextStateGeneratorOptions const& NextStateGenerator<ValueType, StateType>::getOptions() const { return options; @@ -297,6 +302,7 @@ namespace storm { } template class NextStateGenerator<double>; + template class NextStateGenerator<storm::RationalNumber>; template class NextStateGenerator<storm::RationalFunction>; } diff --git a/src/generator/NextStateGenerator.h b/src/generator/NextStateGenerator.h index 2e6214c70..30a4157cd 100644 --- a/src/generator/NextStateGenerator.h +++ b/src/generator/NextStateGenerator.h @@ -162,6 +162,12 @@ namespace storm { NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, VariableInformation const& variableInformation, NextStateGeneratorOptions const& options); + /*! + * Creates a new next state generator. This version of the constructor default-constructs the variable information. + * Hence, the subclass is responsible for suitably initializing it in its constructor. + */ + NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, NextStateGeneratorOptions const& options); + uint64_t getStateSize() const; virtual ModelType getModelType() const = 0; virtual bool isDeterministicModel() const = 0; diff --git a/src/generator/PrismNextStateGenerator.cpp b/src/generator/PrismNextStateGenerator.cpp index 77b547969..5de59feb0 100644 --- a/src/generator/PrismNextStateGenerator.cpp +++ b/src/generator/PrismNextStateGenerator.cpp @@ -22,9 +22,13 @@ namespace storm { } template<typename ValueType, typename StateType> - PrismNextStateGenerator<ValueType, StateType>::PrismNextStateGenerator(storm::prism::Program const& program, NextStateGeneratorOptions const& options, bool flag) : NextStateGenerator<ValueType, StateType>(program.getManager(), VariableInformation(program), options), program(program), rewardModels() { + PrismNextStateGenerator<ValueType, StateType>::PrismNextStateGenerator(storm::prism::Program const& program, NextStateGeneratorOptions const& options, bool flag) : NextStateGenerator<ValueType, StateType>(program.getManager(), options), program(program), rewardModels() { STORM_LOG_THROW(!this->program.specifiesSystemComposition(), storm::exceptions::WrongFormatException, "The explicit next-state generator currently does not support custom system compositions."); + // Only after checking validity of the program, we initialize the variable information. + this->checkValid(program); + this->variableInformation = VariableInformation(program); + if (this->options.isBuildAllRewardModelsSet()) { for (auto const& rewardModel : this->program.getRewardModels()) { rewardModels.push_back(rewardModel); @@ -70,6 +74,28 @@ namespace storm { } } + template<typename ValueType, typename StateType> + void PrismNextStateGenerator<ValueType, StateType>::checkValid(storm::prism::Program const& program) { + // If the program still contains undefined constants and we are not in a parametric setting, assemble an appropriate error message. + if (!std::is_same<ValueType, storm::RationalFunction>::value && program.hasUndefinedConstants()) { + std::vector<std::reference_wrapper<storm::prism::Constant const>> undefinedConstants = program.getUndefinedConstants(); + std::stringstream stream; + bool printComma = false; + for (auto const& constant : undefinedConstants) { + if (printComma) { + stream << ", "; + } else { + printComma = true; + } + stream << constant.get().getName() << " (" << constant.get().getType() << ")"; + } + stream << "."; + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Program still contains these undefined constants: " + stream.str()); + } else if (std::is_same<ValueType, storm::RationalFunction>::value && !program.hasUndefinedConstantsOnlyInUpdateProbabilitiesAndRewards()) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The program contains undefined constants that appear in some places other than update probabilities and reward value expressions, which is not admitted."); + } + } + template<typename ValueType, typename StateType> ModelType PrismNextStateGenerator<ValueType, StateType>::getModelType() const { switch (program.getModelType()) { @@ -535,6 +561,7 @@ namespace storm { } template class PrismNextStateGenerator<double>; + template class PrismNextStateGenerator<storm::RationalNumber>; template class PrismNextStateGenerator<storm::RationalFunction>; } } \ No newline at end of file diff --git a/src/generator/PrismNextStateGenerator.h b/src/generator/PrismNextStateGenerator.h index 652903c98..d2004b9d3 100644 --- a/src/generator/PrismNextStateGenerator.h +++ b/src/generator/PrismNextStateGenerator.h @@ -27,6 +27,8 @@ namespace storm { virtual storm::models::sparse::StateLabeling label(storm::storage::BitVectorHashMap<StateType> const& states, std::vector<StateType> const& initialStateIndices = {}, std::vector<StateType> const& deadlockStateIndices = {}) override; + static void checkValid(storm::prism::Program const& program); + private: /*! * A delegate constructor that is used to preprocess the program before the constructor of the superclass is diff --git a/src/generator/StateBehavior.cpp b/src/generator/StateBehavior.cpp index 6ae1f6de0..28e256c18 100644 --- a/src/generator/StateBehavior.cpp +++ b/src/generator/StateBehavior.cpp @@ -56,6 +56,7 @@ namespace storm { } template class StateBehavior<double>; + template class StateBehavior<storm::RationalNumber>; template class StateBehavior<storm::RationalFunction>; } diff --git a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp index 8356620c1..bf70ca586 100644 --- a/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -15,6 +15,8 @@ #include "src/logic/FragmentSpecification.h" +#include "src/adapters/CarlAdapter.h" + #include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/NotImplementedException.h" diff --git a/src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index c9ee33622..12bb227b9 100644 --- a/src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -701,12 +701,13 @@ namespace storm { template std::vector<double> SparseCtmcCslHelper<double>::computeInstantaneousRewards(storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); template std::vector<double> SparseCtmcCslHelper<double>::computeCumulativeRewards(storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); template std::vector<double> SparseCtmcCslHelper<double>::computeReachabilityRewards(storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + + template std::vector<storm::RationalNumber> SparseCtmcCslHelper<storm::RationalNumber>::computeLongRunAverageProbabilities(storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const* exitRateVector, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); + -#ifdef STORM_HAVE_CARL template std::vector<storm::RationalFunction> SparseCtmcCslHelper<storm::RationalFunction>::computeUntilProbabilitiesElimination(storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); template std::vector<storm::RationalFunction> SparseCtmcCslHelper<storm::RationalFunction>::computeReachabilityTimesElimination(storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& targetStates, bool qualitative); template std::vector<storm::RationalFunction> SparseCtmcCslHelper<storm::RationalFunction>::computeLongRunAverageProbabilities(storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const* exitRateVector, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); -#endif } } } diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp index bf8ea19ff..ee9195b6e 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp @@ -146,6 +146,7 @@ namespace storm { } template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>; + template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<storm::RationalNumber>>; template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>>; } } \ No newline at end of file diff --git a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index 22d80d46a..857da9a6f 100644 --- a/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -67,7 +67,7 @@ namespace storm { // Check whether we need to compute exact probabilities for some states. if (qualitative) { // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1. - storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, ValueType(0.5)); + storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::convertNumber<ValueType>(0.5)); } else { if (!maybeStates.empty()) { // In this case we have have to compute the probabilities. @@ -82,7 +82,7 @@ namespace storm { // Initialize the x vector with 0.5 for each element. This is the initial guess for // the iterative solvers. It should be safe as for all 'maybe' states we know that the // probability is strictly larger than 0. - std::vector<ValueType> x(maybeStates.getNumberOfSetBits(), ValueType(0.5)); + std::vector<ValueType> x(maybeStates.getNumberOfSetBits(), storm::utility::convertNumber<ValueType>(0.5)); // Prepare the right-hand side of the equation system. For entry i this corresponds to // the accumulated probability of going from state i to some 'yes' state. @@ -401,6 +401,7 @@ namespace storm { } template class SparseDtmcPrctlHelper<double>; + template class SparseDtmcPrctlHelper<storm::RationalNumber>; template class SparseDtmcPrctlHelper<storm::RationalFunction>; } } diff --git a/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp b/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp index aa947c8cb..5ffc50140 100644 --- a/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp +++ b/src/modelchecker/propositional/SparsePropositionalModelChecker.cpp @@ -57,14 +57,18 @@ namespace storm { template class SparsePropositionalModelChecker<storm::models::sparse::Mdp<double>>; template class SparsePropositionalModelChecker<storm::models::sparse::MarkovAutomaton<double>>; -#ifdef STORM_HAVE_CARL template class SparsePropositionalModelChecker<storm::models::sparse::Mdp<double, storm::models::sparse::StandardRewardModel<storm::Interval>>>; + template class SparsePropositionalModelChecker<storm::models::sparse::Model<storm::RationalNumber>>; + template class SparsePropositionalModelChecker<storm::models::sparse::Dtmc<storm::RationalNumber>>; + template class SparsePropositionalModelChecker<storm::models::sparse::Ctmc<storm::RationalNumber>>; + template class SparsePropositionalModelChecker<storm::models::sparse::Mdp<storm::RationalNumber>>; + template class SparsePropositionalModelChecker<storm::models::sparse::MarkovAutomaton<storm::RationalNumber>>; + template class SparsePropositionalModelChecker<storm::models::sparse::Model<storm::RationalFunction>>; template class SparsePropositionalModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>>; template class SparsePropositionalModelChecker<storm::models::sparse::Ctmc<storm::RationalFunction>>; template class SparsePropositionalModelChecker<storm::models::sparse::Mdp<storm::RationalFunction>>; template class SparsePropositionalModelChecker<storm::models::sparse::MarkovAutomaton<storm::RationalFunction>>; -#endif } } \ No newline at end of file diff --git a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp index 02cf81343..662881ed0 100644 --- a/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp +++ b/src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp @@ -1032,9 +1032,7 @@ namespace storm { } template class SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<double>>; - -#ifdef STORM_HAVE_CARL + template class SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<storm::RationalNumber>>; template class SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>>; -#endif } // namespace modelchecker } // namespace storm diff --git a/src/modelchecker/results/ExplicitQuantitativeCheckResult.cpp b/src/modelchecker/results/ExplicitQuantitativeCheckResult.cpp index 08ca016fd..218af9179 100644 --- a/src/modelchecker/results/ExplicitQuantitativeCheckResult.cpp +++ b/src/modelchecker/results/ExplicitQuantitativeCheckResult.cpp @@ -133,28 +133,28 @@ namespace storm { switch (comparisonType) { case logic::ComparisonType::Less: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { - if (valuesAsVector[index] < bound) { + if (valuesAsVector[index] < storm::utility::convertNumber<ValueType, double>(bound)) { result.set(index); } } break; case logic::ComparisonType::LessEqual: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { - if (valuesAsVector[index] <= bound) { + if (valuesAsVector[index] <= storm::utility::convertNumber<ValueType, double>(bound)) { result.set(index); } } break; case logic::ComparisonType::Greater: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { - if (valuesAsVector[index] > bound) { + if (valuesAsVector[index] > storm::utility::convertNumber<ValueType, double>(bound)) { result.set(index); } } break; case logic::ComparisonType::GreaterEqual: for (uint_fast64_t index = 0; index < valuesAsVector.size(); ++index) { - if (valuesAsVector[index] >= bound) { + if (valuesAsVector[index] >= storm::utility::convertNumber<ValueType, double>(bound)) { result.set(index); } } @@ -167,22 +167,22 @@ namespace storm { switch (comparisonType) { case logic::ComparisonType::Less: for (auto const& element : valuesAsMap) { - result[element.first] = element.second < bound; + result[element.first] = element.second < storm::utility::convertNumber<ValueType, double>(bound); } break; case logic::ComparisonType::LessEqual: for (auto const& element : valuesAsMap) { - result[element.first] = element.second <= bound; + result[element.first] = element.second <= storm::utility::convertNumber<ValueType, double>(bound); } break; case logic::ComparisonType::Greater: for (auto const& element : valuesAsMap) { - result[element.first] = element.second > bound; + result[element.first] = element.second > storm::utility::convertNumber<ValueType, double>(bound); } break; case logic::ComparisonType::GreaterEqual: for (auto const& element : valuesAsMap) { - result[element.first] = element.second >= bound; + result[element.first] = element.second >= storm::utility::convertNumber<ValueType, double>(bound); } break; } @@ -248,9 +248,7 @@ namespace storm { } template class ExplicitQuantitativeCheckResult<double>; - -#ifdef STORM_HAVE_CARL + template class ExplicitQuantitativeCheckResult<storm::RationalNumber>; template class ExplicitQuantitativeCheckResult<storm::RationalFunction>; -#endif } } \ No newline at end of file diff --git a/src/models/sparse/Ctmc.cpp b/src/models/sparse/Ctmc.cpp index 1d07c48a9..e48f4590f 100644 --- a/src/models/sparse/Ctmc.cpp +++ b/src/models/sparse/Ctmc.cpp @@ -46,12 +46,10 @@ namespace storm { } template class Ctmc<double>; + template class Ctmc<storm::RationalNumber>; -#ifdef STORM_HAVE_CARL template class Ctmc<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; - template class Ctmc<storm::RationalFunction>; -#endif } // namespace sparse } // namespace models diff --git a/src/models/sparse/DeterministicModel.cpp b/src/models/sparse/DeterministicModel.cpp index 0fb6de34a..c2bd35b16 100644 --- a/src/models/sparse/DeterministicModel.cpp +++ b/src/models/sparse/DeterministicModel.cpp @@ -57,12 +57,10 @@ namespace storm { template class DeterministicModel<double>; template class DeterministicModel<float>; + template class DeterministicModel<storm::RationalNumber>; -#ifdef STORM_HAVE_CARL template class DeterministicModel<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; - template class DeterministicModel<storm::RationalFunction>; -#endif } // namespace sparse } // namespace models diff --git a/src/models/sparse/Dtmc.cpp b/src/models/sparse/Dtmc.cpp index cbfeed391..7997a1494 100644 --- a/src/models/sparse/Dtmc.cpp +++ b/src/models/sparse/Dtmc.cpp @@ -25,160 +25,6 @@ namespace storm { STORM_LOG_THROW(probabilityMatrix.isProbabilistic(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid."); } - template <typename ValueType, typename RewardModelType> - Dtmc<ValueType> Dtmc<ValueType, RewardModelType>::getSubDtmc(storm::storage::BitVector const& states) const { - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This function is not yet implemented."); - // FIXME: repair this - // - // - // // Is there any state in the subsystem? - // if(subSysStates.getNumberOfSetBits() == 0) { - // STORM_LOG_ERROR("No states in subsystem!"); - // return storm::models::Dtmc<ValueType>(storm::storage::SparseMatrix<ValueType>(), - // storm::models::sparse::StateLabeling(this->getStateLabeling(), subSysStates), - // boost::optional<std::vector<ValueType>>(), - // boost::optional<storm::storage::SparseMatrix<ValueType>>(), - // boost::optional<std::vector<LabelSet>>()); - // } - // - // // Does the vector have the right size? - // if(subSysStates.size() != this->getNumberOfStates()) { - // STORM_LOG_INFO("BitVector has wrong size. Resizing it..."); - // subSysStates.resize(this->getNumberOfStates()); - // } - // - // // Test if it is a proper subsystem of this Dtmc, i.e. if there is at least one state to be left out. - // if(subSysStates.getNumberOfSetBits() == subSysStates.size()) { - // STORM_LOG_INFO("All states are kept. This is no proper subsystem."); - // return storm::models::Dtmc<ValueType>(*this); - // } - // - // // 1. Get all necessary information from the old transition matrix - // storm::storage::SparseMatrix<ValueType> const & origMat = this->getTransitionMatrix(); - // - // // Iterate over all rows. Count the number of all transitions from the old system to be - // // transfered to the new one. Also build a mapping from the state number of the old system - // // to the state number of the new system. - // uint_fast64_t subSysTransitionCount = 0; - // uint_fast64_t newRow = 0; - // std::vector<uint_fast64_t> stateMapping; - // for(uint_fast64_t row = 0; row < origMat.getRowCount(); ++row) { - // if(subSysStates.get(row)){ - // for(auto const& entry : origMat.getRow(row)) { - // if(subSysStates.get(entry.getColumn())) { - // subSysTransitionCount++; - // } - // } - // stateMapping.push_back(newRow); - // newRow++; - // } else { - // stateMapping.push_back((uint_fast64_t) -1); - // } - // } - // - // // 2. Construct transition matrix - // - // // Take all states indicated by the vector as well as one additional state s_b as target of - // // all transitions that target a state that is not kept. - // uint_fast64_t const newStateCount = subSysStates.getNumberOfSetBits() + 1; - // - // // The number of transitions of the new Dtmc is the number of transitions transfered - // // from the old one plus one transition for each state to s_b. - // storm::storage::SparseMatrixBuilder<ValueType> newMatBuilder(newStateCount,newStateCount,subSysTransitionCount + newStateCount); - // - // // Now fill the matrix. - // newRow = 0; - // T rest = storm::utility::zero<ValueType>(); - // for(uint_fast64_t row = 0; row < origMat.getRowCount(); ++row) { - // if(subSysStates.get(row)){ - // // Transfer transitions - // for(auto& entry : origMat.getRow(row)) { - // if(subSysStates.get(entry.getColumn())) { - // newMatBuilder.addNextValue(newRow, stateMapping[entry.getColumn()], entry.getValue()); - // } else { - // rest += entry.getValue(); - // } - // } - // - // // Insert the transition taking care of the remaining outgoing probability. - // newMatBuilder.addNextValue(newRow, newStateCount - 1, rest); - // rest = storm::utility::zero<ValueType>(); - // - // newRow++; - // } - // } - // - // // Insert last transition: self loop on s_b - // newMatBuilder.addNextValue(newStateCount - 1, newStateCount - 1, storm::utility::one<ValueType>()); - // - // // 3. Take care of the labeling. - // storm::models::sparse::StateLabeling newLabeling = storm::models::sparse::StateLabeling(this->getStateLabeling(), subSysStates); - // newLabeling.addState(); - // if(!newLabeling.containsLabel("s_b")) { - // newLabeling.addLabel("s_b"); - // } - // newLabeling.addLabelToState("s_b", newStateCount - 1); - // - // // 4. Handle the optionals - // - // boost::optional<std::vector<ValueType>> newStateRewards; - // if(this->hasStateRewards()) { - // - // // Get the rewards and move the needed values to the front. - // std::vector<ValueType> newRewards(this->getStateRewardVector()); - // storm::utility::vector::selectVectorValues(newRewards, subSysStates, newRewards); - // - // // Throw away all values after the last state and set the reward for s_b to 0. - // newRewards.resize(newStateCount); - // newRewards[newStateCount - 1] = (T) 0; - // - // newStateRewards = newRewards; - // } - // - // boost::optional<storm::storage::SparseMatrix<ValueType>> newTransitionRewards; - // if(this->hasTransitionRewards()) { - // - // storm::storage::SparseMatrixBuilder<ValueType> newTransRewardsBuilder(newStateCount, subSysTransitionCount + newStateCount); - // - // // Copy the rewards for the kept states - // newRow = 0; - // for(uint_fast64_t row = 0; row < this->getTransitionRewardMatrix().getRowCount(); ++row) { - // if(subSysStates.get(row)){ - // // Transfer transition rewards - // for(auto& entry : this->getTransitionRewardMatrix().getRow(row)) { - // if(subSysStates.get(entry.getColumn())) { - // newTransRewardsBuilder.addNextValue(newRow, stateMapping[entry.getColumn()], entry.getValue()); - // } - // } - // - // // Insert the reward (e.g. 0) for the transition taking care of the remaining outgoing probability. - // newTransRewardsBuilder.addNextValue(newRow, newStateCount - 1, storm::utility::zero<ValueType>()); - // - // newRow++; - // } - // } - // - // newTransitionRewards = newTransRewardsBuilder.build(); - // } - // - // boost::optional<std::vector<LabelSet>> newChoiceLabels; - // if(this->hasChoiceLabeling()) { - // - // // Get the choice label sets and move the needed values to the front. - // std::vector<LabelSet> newChoice(this->getChoiceLabeling()); - // storm::utility::vector::selectVectorValues(newChoice, subSysStates, this->getChoiceLabeling()); - // - // // Throw away all values after the last state and set the choice label set for s_b as empty. - // newChoice.resize(newStateCount); - // newChoice[newStateCount - 1] = LabelSet(); - // - // newChoiceLabels = newChoice; - // } - // - // // 5. Make Dtmc from its parts and return it - // return storm::models::Dtmc<ValueType>(newMatBuilder.build(), newLabeling, newStateRewards, std::move(newTransitionRewards), newChoiceLabels); - } - #ifdef STORM_HAVE_CARL template <typename ValueType, typename RewardModelType> Dtmc<ValueType, RewardModelType>::ConstraintCollector::ConstraintCollector(Dtmc<ValueType> const& dtmc) { @@ -223,12 +69,10 @@ namespace storm { template class Dtmc<double>; template class Dtmc<float>; + template class Dtmc<storm::RationalNumber>; -#ifdef STORM_HAVE_CARL template class Dtmc<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; - template class Dtmc<storm::RationalFunction>; -#endif } // namespace sparse } // namespace models diff --git a/src/models/sparse/Dtmc.h b/src/models/sparse/Dtmc.h index bf1b5c3e4..5e6846b76 100644 --- a/src/models/sparse/Dtmc.h +++ b/src/models/sparse/Dtmc.h @@ -49,13 +49,6 @@ namespace storm { Dtmc& operator=(Dtmc<ValueType, RewardModelType>&& dtmc) = default; #endif - /*! - * Retrieves the sub-DTMC that only contains the given set of states. - * - * @param states The states of the sub-DTMC. - * @return The resulting sub-DTMC. - */ - Dtmc<ValueType> getSubDtmc(storm::storage::BitVector const& states) const; #ifdef STORM_HAVE_CARL class ConstraintCollector { diff --git a/src/models/sparse/MarkovAutomaton.cpp b/src/models/sparse/MarkovAutomaton.cpp index b9739203f..81f3bc5c9 100644 --- a/src/models/sparse/MarkovAutomaton.cpp +++ b/src/models/sparse/MarkovAutomaton.cpp @@ -322,12 +322,10 @@ namespace storm { template class MarkovAutomaton<double>; // template class MarkovAutomaton<float>; + template class MarkovAutomaton<storm::RationalNumber>; -#ifdef STORM_HAVE_CARL template class MarkovAutomaton<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; - template class MarkovAutomaton<storm::RationalFunction>; -#endif } // namespace sparse } // namespace models diff --git a/src/models/sparse/Mdp.cpp b/src/models/sparse/Mdp.cpp index 4a4b37d60..cf436c7e1 100644 --- a/src/models/sparse/Mdp.cpp +++ b/src/models/sparse/Mdp.cpp @@ -98,12 +98,10 @@ namespace storm { template class Mdp<double>; template class Mdp<float>; + template class Mdp<storm::RationalNumber>; -#ifdef STORM_HAVE_CARL template class Mdp<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; - template class Mdp<storm::RationalFunction>; -#endif } // namespace sparse } // namespace models diff --git a/src/models/sparse/Model.cpp b/src/models/sparse/Model.cpp index 265f0d8b0..83d0c8aa2 100644 --- a/src/models/sparse/Model.cpp +++ b/src/models/sparse/Model.cpp @@ -354,12 +354,11 @@ namespace storm { template class Model<double>; template class Model<float>; - -#ifdef STORM_HAVE_CARL - template class Model<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; + template class Model<storm::RationalNumber>; + + template class Model<double, storm::models::sparse::StandardRewardModel<storm::Interval>>; template class Model<storm::RationalFunction>; -#endif } } diff --git a/src/models/sparse/NondeterministicModel.cpp b/src/models/sparse/NondeterministicModel.cpp index 29662f6cf..3a4af6664 100644 --- a/src/models/sparse/NondeterministicModel.cpp +++ b/src/models/sparse/NondeterministicModel.cpp @@ -169,14 +169,13 @@ namespace storm { template class NondeterministicModel<double>; template class NondeterministicModel<float>; + template class NondeterministicModel<storm::RationalNumber>; -#ifdef STORM_HAVE_CARL 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 } } diff --git a/src/models/sparse/StandardRewardModel.cpp b/src/models/sparse/StandardRewardModel.cpp index 88b88915e..3bd624d3d 100644 --- a/src/models/sparse/StandardRewardModel.cpp +++ b/src/models/sparse/StandardRewardModel.cpp @@ -303,8 +303,16 @@ namespace storm { template void StandardRewardModel<float>::setStateReward(uint_fast64_t state, float const & newValue); template class StandardRewardModel<float>; template std::ostream& operator<<<float>(std::ostream& out, StandardRewardModel<float> const& rewardModel); + + template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::BitVector const& filter) const; + template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix) const; + template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& weights) const; + template void StandardRewardModel<storm::RationalNumber>::reduceToStateBasedRewards(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, bool reduceToStateRewards); + template void StandardRewardModel<storm::RationalNumber>::setStateActionReward(uint_fast64_t choiceIndex, storm::RationalNumber const & newValue); + template void StandardRewardModel<storm::RationalNumber>::setStateReward(uint_fast64_t state, storm::RationalNumber const & newValue); + template class StandardRewardModel<storm::RationalNumber>; + template std::ostream& operator<<<storm::RationalNumber>(std::ostream& out, StandardRewardModel<storm::RationalNumber> const& rewardModel); -#ifdef STORM_HAVE_CARL template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::BitVector const& filter) const; template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& weights) const; @@ -324,7 +332,6 @@ namespace storm { template void StandardRewardModel<storm::Interval>::reduceToStateBasedRewards(storm::storage::SparseMatrix<double> const& transitionMatrix, bool reduceToStateRewards); template class StandardRewardModel<storm::Interval>; template std::ostream& operator<<<storm::Interval>(std::ostream& out, StandardRewardModel<storm::Interval> const& rewardModel); -#endif } } diff --git a/src/solver/stateelimination/ConditionalStateEliminator.cpp b/src/solver/stateelimination/ConditionalStateEliminator.cpp index f15b3342b..0a86894bc 100644 --- a/src/solver/stateelimination/ConditionalStateEliminator.cpp +++ b/src/solver/stateelimination/ConditionalStateEliminator.cpp @@ -61,10 +61,8 @@ namespace storm { } template class ConditionalStateEliminator<double>; - -#ifdef STORM_HAVE_CARL + template class ConditionalStateEliminator<storm::RationalNumber>; template class ConditionalStateEliminator<storm::RationalFunction>; -#endif } // namespace stateelimination } // namespace storage diff --git a/src/solver/stateelimination/DynamicStatePriorityQueue.cpp b/src/solver/stateelimination/DynamicStatePriorityQueue.cpp index 8c4d0a83d..afff0b7a3 100644 --- a/src/solver/stateelimination/DynamicStatePriorityQueue.cpp +++ b/src/solver/stateelimination/DynamicStatePriorityQueue.cpp @@ -66,10 +66,8 @@ namespace storm { } template class DynamicStatePriorityQueue<double>; - -#ifdef STORM_HAVE_CARL + template class DynamicStatePriorityQueue<storm::RationalNumber>; template class DynamicStatePriorityQueue<storm::RationalFunction>; -#endif } } } diff --git a/src/solver/stateelimination/LongRunAverageEliminator.cpp b/src/solver/stateelimination/LongRunAverageEliminator.cpp index c06fed5bb..758f71a14 100644 --- a/src/solver/stateelimination/LongRunAverageEliminator.cpp +++ b/src/solver/stateelimination/LongRunAverageEliminator.cpp @@ -23,10 +23,8 @@ namespace storm { } template class LongRunAverageEliminator<double>; - -#ifdef STORM_HAVE_CARL + template class LongRunAverageEliminator<storm::RationalNumber>; template class LongRunAverageEliminator<storm::RationalFunction>; -#endif } // namespace stateelimination } // namespace storage diff --git a/src/solver/stateelimination/PrioritizedStateEliminator.cpp b/src/solver/stateelimination/PrioritizedStateEliminator.cpp index 5fa1cfc8a..134cb3264 100644 --- a/src/solver/stateelimination/PrioritizedStateEliminator.cpp +++ b/src/solver/stateelimination/PrioritizedStateEliminator.cpp @@ -30,10 +30,7 @@ namespace storm { template class PrioritizedStateEliminator<double>; template class PrioritizedStateEliminator<storm::RationalNumber>; - -#ifdef STORM_HAVE_CARL template class PrioritizedStateEliminator<storm::RationalFunction>; -#endif } // namespace stateelimination } // namespace storage diff --git a/src/solver/stateelimination/StateEliminator.cpp b/src/solver/stateelimination/StateEliminator.cpp index ef4bb355e..41d3ef2d9 100644 --- a/src/solver/stateelimination/StateEliminator.cpp +++ b/src/solver/stateelimination/StateEliminator.cpp @@ -265,10 +265,7 @@ namespace storm { template class StateEliminator<double>; template class StateEliminator<storm::RationalNumber>; - -#ifdef STORM_HAVE_CARL template class StateEliminator<storm::RationalFunction>; -#endif } // namespace stateelimination } // namespace storage diff --git a/src/storage/Distribution.cpp b/src/storage/Distribution.cpp index 5843e964b..7c3b5d99f 100644 --- a/src/storage/Distribution.cpp +++ b/src/storage/Distribution.cpp @@ -151,10 +151,11 @@ namespace storm { template class Distribution<double>; template std::ostream& operator<<(std::ostream& out, Distribution<double> const& distribution); - -#ifdef STORM_HAVE_CARL + + template class Distribution<storm::RationalNumber>; + template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalNumber> const& distribution); + template class Distribution<storm::RationalFunction>; template std::ostream& operator<<(std::ostream& out, Distribution<storm::RationalFunction> const& distribution); -#endif } } diff --git a/src/storage/StronglyConnectedComponentDecomposition.cpp b/src/storage/StronglyConnectedComponentDecomposition.cpp index fe2c60e4e..e129c8b85 100644 --- a/src/storage/StronglyConnectedComponentDecomposition.cpp +++ b/src/storage/StronglyConnectedComponentDecomposition.cpp @@ -237,11 +237,14 @@ namespace storm { template StronglyConnectedComponentDecomposition<float>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<float> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs); template StronglyConnectedComponentDecomposition<float>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<float> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs); -#ifdef STORM_HAVE_CARL + template class StronglyConnectedComponentDecomposition<storm::RationalNumber>; + template StronglyConnectedComponentDecomposition<storm::RationalNumber>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<storm::RationalNumber> const& model, bool dropNaiveSccs, bool onlyBottomSccs); + template StronglyConnectedComponentDecomposition<storm::RationalNumber>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<storm::RationalNumber> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs); + template StronglyConnectedComponentDecomposition<storm::RationalNumber>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<storm::RationalNumber> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs); + template class StronglyConnectedComponentDecomposition<storm::RationalFunction>; template StronglyConnectedComponentDecomposition<storm::RationalFunction>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<storm::RationalFunction> const& model, bool dropNaiveSccs, bool onlyBottomSccs); template StronglyConnectedComponentDecomposition<storm::RationalFunction>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<storm::RationalFunction> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs); template StronglyConnectedComponentDecomposition<storm::RationalFunction>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<storm::RationalFunction> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs); -#endif } // namespace storage } // namespace storm \ No newline at end of file diff --git a/src/storage/bisimulation/BisimulationDecomposition.cpp b/src/storage/bisimulation/BisimulationDecomposition.cpp index 4b31551f9..751708e24 100644 --- a/src/storage/bisimulation/BisimulationDecomposition.cpp +++ b/src/storage/bisimulation/BisimulationDecomposition.cpp @@ -322,11 +322,13 @@ namespace storm { template class BisimulationDecomposition<storm::models::sparse::Dtmc<double>, bisimulation::DeterministicBlockData>; template class BisimulationDecomposition<storm::models::sparse::Ctmc<double>, bisimulation::DeterministicBlockData>; template class BisimulationDecomposition<storm::models::sparse::Mdp<double>, bisimulation::DeterministicBlockData>; - -#ifdef STORM_HAVE_CARL + + template class BisimulationDecomposition<storm::models::sparse::Dtmc<storm::RationalNumber>, bisimulation::DeterministicBlockData>; + template class BisimulationDecomposition<storm::models::sparse::Ctmc<storm::RationalNumber>, bisimulation::DeterministicBlockData>; + template class BisimulationDecomposition<storm::models::sparse::Mdp<storm::RationalNumber>, bisimulation::DeterministicBlockData>; + template class BisimulationDecomposition<storm::models::sparse::Dtmc<storm::RationalFunction>, bisimulation::DeterministicBlockData>; template class BisimulationDecomposition<storm::models::sparse::Ctmc<storm::RationalFunction>, bisimulation::DeterministicBlockData>; template class BisimulationDecomposition<storm::models::sparse::Mdp<storm::RationalFunction>, bisimulation::DeterministicBlockData>; -#endif } } diff --git a/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp b/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp index e968c98cd..89408e620 100644 --- a/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp +++ b/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp @@ -651,10 +651,11 @@ namespace storm { template class DeterministicModelBisimulationDecomposition<storm::models::sparse::Dtmc<double>>; template class DeterministicModelBisimulationDecomposition<storm::models::sparse::Ctmc<double>>; - -#ifdef STORM_HAVE_CARL + + template class DeterministicModelBisimulationDecomposition<storm::models::sparse::Dtmc<storm::RationalNumber>>; + template class DeterministicModelBisimulationDecomposition<storm::models::sparse::Ctmc<storm::RationalNumber>>; + template class DeterministicModelBisimulationDecomposition<storm::models::sparse::Dtmc<storm::RationalFunction>>; template class DeterministicModelBisimulationDecomposition<storm::models::sparse::Ctmc<storm::RationalFunction>>; -#endif } } diff --git a/src/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp b/src/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp index 2e7d54113..c117b0628 100644 --- a/src/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp +++ b/src/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp @@ -416,10 +416,8 @@ namespace storm { } template class NondeterministicModelBisimulationDecomposition<storm::models::sparse::Mdp<double>>; - -#ifdef STORM_HAVE_CARL + template class NondeterministicModelBisimulationDecomposition<storm::models::sparse::Mdp<storm::RationalNumber>>; template class NondeterministicModelBisimulationDecomposition<storm::models::sparse::Mdp<storm::RationalFunction>>; -#endif } } diff --git a/src/storage/expressions/ExpressionEvaluator.cpp b/src/storage/expressions/ExpressionEvaluator.cpp index 46ef54c24..6d44d680a 100644 --- a/src/storage/expressions/ExpressionEvaluator.cpp +++ b/src/storage/expressions/ExpressionEvaluator.cpp @@ -7,30 +7,48 @@ namespace storm { // Intentionally left empty. } -#ifdef STORM_HAVE_CARL - ExpressionEvaluator<RationalFunction>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluatorBase<RationalFunction>(manager) { + template<typename RationalType> + ExpressionEvaluatorWithVariableToExpressionMap<RationalType>::ExpressionEvaluatorWithVariableToExpressionMap(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluatorBase<RationalType>(manager) { // Intentionally left empty. } - void ExpressionEvaluator<RationalFunction>::setBooleanValue(storm::expressions::Variable const& variable, bool value) { - ExprtkExpressionEvaluatorBase::setBooleanValue(variable, value); + template<typename RationalType> + void ExpressionEvaluatorWithVariableToExpressionMap<RationalType>::setBooleanValue(storm::expressions::Variable const& variable, bool value) { + ExprtkExpressionEvaluatorBase<RationalType>::setBooleanValue(variable, value); this->variableToExpressionMap[variable] = this->getManager().boolean(value); } - void ExpressionEvaluator<RationalFunction>::setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) { - ExprtkExpressionEvaluatorBase::setIntegerValue(variable, value); + template<typename RationalType> + void ExpressionEvaluatorWithVariableToExpressionMap<RationalType>::setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) { + ExprtkExpressionEvaluatorBase<RationalType>::setIntegerValue(variable, value); this->variableToExpressionMap[variable] = this->getManager().integer(value); } - void ExpressionEvaluator<RationalFunction>::setRationalValue(storm::expressions::Variable const& variable, double value) { - ExprtkExpressionEvaluatorBase::setRationalValue(variable, value); + template<typename RationalType> + void ExpressionEvaluatorWithVariableToExpressionMap<RationalType>::setRationalValue(storm::expressions::Variable const& variable, double value) { + ExprtkExpressionEvaluatorBase<RationalType>::setRationalValue(variable, value); this->variableToExpressionMap[variable] = this->getManager().rational(value); } + + ExpressionEvaluator<RationalNumber>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExpressionEvaluatorWithVariableToExpressionMap<RationalNumber>(manager) { + // Intentionally left empty. + } + + RationalNumber ExpressionEvaluator<RationalNumber>::asRational(Expression const& expression) const { + Expression substitutedExpression = expression.substitute(this->variableToExpressionMap); + return this->rationalNumberVisitor.toRationalNumber(substitutedExpression); + } + + ExpressionEvaluator<RationalFunction>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExpressionEvaluatorWithVariableToExpressionMap<RationalFunction>(manager) { + // Intentionally left empty. + } RationalFunction ExpressionEvaluator<RationalFunction>::asRational(Expression const& expression) const { - Expression substitutedExpression = expression.substitute(variableToExpressionMap); + Expression substitutedExpression = expression.substitute(this->variableToExpressionMap); return this->rationalFunctionVisitor.toRationalFunction(substitutedExpression); } -#endif + + template class ExpressionEvaluatorWithVariableToExpressionMap<RationalNumber>; + template class ExpressionEvaluatorWithVariableToExpressionMap<RationalFunction>; } } \ No newline at end of file diff --git a/src/storage/expressions/ExpressionEvaluator.h b/src/storage/expressions/ExpressionEvaluator.h index d9fa1653b..2480af12d 100644 --- a/src/storage/expressions/ExpressionEvaluator.h +++ b/src/storage/expressions/ExpressionEvaluator.h @@ -8,6 +8,7 @@ #include "src/storage/expressions/Expression.h" #include "src/storage/expressions/ExprtkExpressionEvaluator.h" #include "src/storage/expressions/ToRationalFunctionVisitor.h" +#include "src/storage/expressions/ToRationalNumberVisitor.h" namespace storm { namespace expressions { @@ -20,26 +21,43 @@ namespace storm { ExpressionEvaluator(storm::expressions::ExpressionManager const& manager); }; -#ifdef STORM_HAVE_CARL - template<> - class ExpressionEvaluator<RationalFunction> : public ExprtkExpressionEvaluatorBase<RationalFunction> { + template<typename RationalType> + class ExpressionEvaluatorWithVariableToExpressionMap : public ExprtkExpressionEvaluatorBase<RationalType> { public: - ExpressionEvaluator(storm::expressions::ExpressionManager const& manager); - + ExpressionEvaluatorWithVariableToExpressionMap(storm::expressions::ExpressionManager const& manager); + void setBooleanValue(storm::expressions::Variable const& variable, bool value) override; void setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) override; void setRationalValue(storm::expressions::Variable const& variable, double value) override; + + protected: + // A mapping of variables to their expressions. + std::unordered_map<storm::expressions::Variable, storm::expressions::Expression> variableToExpressionMap; + }; + + template<> + class ExpressionEvaluator<RationalNumber> : public ExpressionEvaluatorWithVariableToExpressionMap<RationalNumber> { + public: + ExpressionEvaluator(storm::expressions::ExpressionManager const& manager); - RationalFunction asRational(Expression const& expression) const override; + RationalNumber asRational(Expression const& expression) const override; private: - // A mapping of variables to their expressions. - std::unordered_map<storm::expressions::Variable, storm::expressions::Expression> variableToExpressionMap; + // A visitor that can be used to translate expressions to rational numbers. + mutable ToRationalNumberVisitor<RationalNumber> rationalNumberVisitor; + }; + + template<> + class ExpressionEvaluator<RationalFunction> : public ExpressionEvaluatorWithVariableToExpressionMap<RationalFunction> { + public: + ExpressionEvaluator(storm::expressions::ExpressionManager const& manager); + RationalFunction asRational(Expression const& expression) const override; + + private: // A visitor that can be used to translate expressions to rational functions. mutable ToRationalFunctionVisitor<RationalFunction> rationalFunctionVisitor; }; -#endif } } diff --git a/src/storage/expressions/ExpressionEvaluatorBase.cpp b/src/storage/expressions/ExpressionEvaluatorBase.cpp index e707a48ca..d98810886 100644 --- a/src/storage/expressions/ExpressionEvaluatorBase.cpp +++ b/src/storage/expressions/ExpressionEvaluatorBase.cpp @@ -16,8 +16,7 @@ namespace storm { } template class ExpressionEvaluatorBase<double>; -#ifdef STORM_HAVE_CARL + template class ExpressionEvaluatorBase<storm::RationalNumber>; template class ExpressionEvaluatorBase<storm::RationalFunction>; -#endif } } \ No newline at end of file diff --git a/src/storage/expressions/ExprtkExpressionEvaluator.cpp b/src/storage/expressions/ExprtkExpressionEvaluator.cpp index 1d225ec12..942c17172 100755 --- a/src/storage/expressions/ExprtkExpressionEvaluator.cpp +++ b/src/storage/expressions/ExprtkExpressionEvaluator.cpp @@ -83,8 +83,7 @@ namespace storm { } template class ExprtkExpressionEvaluatorBase<double>; -#ifdef STORM_HAVE_CARL + template class ExprtkExpressionEvaluatorBase<RationalNumber>; template class ExprtkExpressionEvaluatorBase<RationalFunction>; -#endif } } \ No newline at end of file diff --git a/src/storage/expressions/ToRationalFunctionVisitor.cpp b/src/storage/expressions/ToRationalFunctionVisitor.cpp index b42f23aa4..71e052bee 100644 --- a/src/storage/expressions/ToRationalFunctionVisitor.cpp +++ b/src/storage/expressions/ToRationalFunctionVisitor.cpp @@ -5,8 +5,6 @@ #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" -#ifdef STORM_HAVE_CARL - namespace storm { namespace expressions { template<typename RationalFunctionType> @@ -100,5 +98,3 @@ namespace storm { } } - -#endif diff --git a/src/storage/expressions/ToRationalFunctionVisitor.h b/src/storage/expressions/ToRationalFunctionVisitor.h index 4ad74acc9..6bd3a205b 100644 --- a/src/storage/expressions/ToRationalFunctionVisitor.h +++ b/src/storage/expressions/ToRationalFunctionVisitor.h @@ -7,7 +7,6 @@ #include "src/storage/expressions/ExpressionVisitor.h" #include "src/storage/expressions/Variable.h" -#ifdef STORM_HAVE_CARL namespace storm { namespace expressions { @@ -48,6 +47,5 @@ namespace storm { }; } } -#endif #endif /* STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_ */ \ No newline at end of file diff --git a/src/storage/expressions/ToRationalNumberVisitor.cpp b/src/storage/expressions/ToRationalNumberVisitor.cpp new file mode 100644 index 000000000..b17ec335a --- /dev/null +++ b/src/storage/expressions/ToRationalNumberVisitor.cpp @@ -0,0 +1,91 @@ +#include "src/storage/expressions/ToRationalNumberVisitor.h" + +#include "src/utility/macros.h" +#include "src/exceptions/InvalidArgumentException.h" + +namespace storm { + namespace expressions { + template<typename RationalNumberType> + ToRationalNumberVisitor<RationalNumberType>::ToRationalNumberVisitor() : ExpressionVisitor() { + // Intentionally left empty. + } + + template<typename RationalNumberType> + RationalNumberType ToRationalNumberVisitor<RationalNumberType>::toRationalNumber(Expression const& expression) { + return boost::any_cast<RationalNumberType>(expression.accept(*this)); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(IfThenElseExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational number."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(BinaryBooleanFunctionExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational number."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(BinaryNumericalFunctionExpression const& expression) { + RationalNumberType firstOperandAsRationalFunction = boost::any_cast<RationalNumberType>(expression.getFirstOperand()->accept(*this)); + RationalNumberType secondOperandAsRationalFunction = boost::any_cast<RationalNumberType>(expression.getSecondOperand()->accept(*this)); + switch(expression.getOperatorType()) { + case BinaryNumericalFunctionExpression::OperatorType::Plus: + return firstOperandAsRationalFunction + secondOperandAsRationalFunction; + break; + case BinaryNumericalFunctionExpression::OperatorType::Minus: + return firstOperandAsRationalFunction - secondOperandAsRationalFunction; + break; + case BinaryNumericalFunctionExpression::OperatorType::Times: + return firstOperandAsRationalFunction * secondOperandAsRationalFunction; + break; + case BinaryNumericalFunctionExpression::OperatorType::Divide: + return firstOperandAsRationalFunction / secondOperandAsRationalFunction; + break; + default: + STORM_LOG_ASSERT(false, "Illegal operator type."); + } + + // Return a dummy. This point must, however, never be reached. + return boost::any(); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(BinaryRelationExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(VariableExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot transform expressions containing variables to a rational number."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(UnaryBooleanFunctionExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(UnaryNumericalFunctionExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(BooleanLiteralExpression const& expression) { + STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(IntegerLiteralExpression const& expression) { + return RationalNumberType(carl::rationalize<storm::RationalNumber>(static_cast<size_t>(expression.getValue()))); + } + + template<typename RationalNumberType> + boost::any ToRationalNumberVisitor<RationalNumberType>::visit(DoubleLiteralExpression const& expression) { + return RationalNumberType(carl::rationalize<storm::RationalNumber>(expression.getValue())); + } + + template class ToRationalNumberVisitor<storm::RationalNumber>; + + } +} diff --git a/src/storage/expressions/ToRationalNumberVisitor.h b/src/storage/expressions/ToRationalNumberVisitor.h new file mode 100644 index 000000000..2254931f6 --- /dev/null +++ b/src/storage/expressions/ToRationalNumberVisitor.h @@ -0,0 +1,31 @@ +#pragma once + +#include "src/adapters/CarlAdapter.h" +#include "src/storage/expressions/Expression.h" +#include "src/storage/expressions/Expressions.h" +#include "src/storage/expressions/ExpressionVisitor.h" +#include "src/storage/expressions/Variable.h" + +namespace storm { + namespace expressions { + + template<typename RationalNumberType> + class ToRationalNumberVisitor : public ExpressionVisitor { + public: + ToRationalNumberVisitor(); + + RationalNumberType toRationalNumber(Expression const& expression); + + virtual boost::any visit(IfThenElseExpression const& expression) override; + virtual boost::any visit(BinaryBooleanFunctionExpression const& expression) override; + virtual boost::any visit(BinaryNumericalFunctionExpression const& expression) override; + virtual boost::any visit(BinaryRelationExpression const& expression) override; + virtual boost::any visit(VariableExpression const& expression) override; + virtual boost::any visit(UnaryBooleanFunctionExpression const& expression) override; + virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override; + virtual boost::any visit(BooleanLiteralExpression const& expression) override; + virtual boost::any visit(IntegerLiteralExpression const& expression) override; + virtual boost::any visit(DoubleLiteralExpression const& expression) override; + }; + } +} diff --git a/src/utility/constants.cpp b/src/utility/constants.cpp index b2b182247..dfe0101ad 100644 --- a/src/utility/constants.cpp +++ b/src/utility/constants.cpp @@ -40,8 +40,12 @@ namespace storm { return true; } + template<> + storm::RationalNumber infinity() { + // FIXME: this should be treated more properly. + return storm::RationalNumber(-1); + } -#ifdef STORM_HAVE_CARL template<> bool isOne(storm::RationalFunction const& a) { return a.isOne(); @@ -88,8 +92,6 @@ namespace storm { return carl::isZero(a); } -#endif - template<typename ValueType> ValueType pow(ValueType const& value, uint_fast64_t exponent) { return std::pow(value, exponent); @@ -102,7 +104,11 @@ namespace storm { return value; } -#ifdef STORM_HAVE_CARL + template<> + double convertNumber(double const& number){ + return number; + } + template<> RationalFunction& simplify(RationalFunction& value); @@ -142,7 +148,10 @@ namespace storm { return carl::rationalize<RationalNumber>(number); } -#endif + template<> + RationalFunction convertNumber(double const& number){ + return RationalFunction(carl::rationalize<RationalNumber>(number)); + } template<typename IndexType, typename ValueType> storm::storage::MatrixEntry<IndexType, ValueType> simplify(storm::storage::MatrixEntry<IndexType, ValueType> matrixEntry) { @@ -238,7 +247,8 @@ namespace storm { template storm::RationalNumber one(); template storm::RationalNumber zero(); - + template storm::RationalNumber infinity(); + template double convertNumber(storm::RationalNumber const& number); template storm::RationalNumber convertNumber(double const& number); diff --git a/src/utility/graph.cpp b/src/utility/graph.cpp index b188872cf..05541ae01 100644 --- a/src/utility/graph.cpp +++ b/src/utility/graph.cpp @@ -1116,8 +1116,62 @@ namespace storm { template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<float> const& matrix) ; -#ifdef STORM_HAVE_CARL + // Instantiations for storm::RationalNumber. + template storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps); + + template std::vector<std::size_t> getDistances(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem); + + + template storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0); + + template storm::storage::BitVector performProb1(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0); + + + template storm::storage::BitVector performProb1(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + + template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<storm::RationalNumber> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + + template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + + + template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ; + + template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + template storm::storage::BitVector performProb0A(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ; + + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ; + + + template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ; + + template storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0); + + + template storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb0E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ; + + + template storm::storage::BitVector performProb1A( storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ; + + + template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + + + template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalNumber> const& matrix); + // End of instantiations for storm::RationalNumber. + +#ifdef STORM_HAVE_CARL template storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, bool useStepBound, uint_fast64_t maximalSteps); template std::vector<std::size_t> getDistances(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::BitVector const& initialStates, boost::optional<storm::storage::BitVector> const& subsystem); @@ -1169,7 +1223,7 @@ namespace storm { template std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::models::sparse::NondeterministicModel<storm::RationalFunction> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalFunction> const& matrix) ; + template std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<storm::RationalFunction> const& matrix); #endif diff --git a/src/utility/solver.cpp b/src/utility/solver.cpp index 92f2b8e94..43fadb20b 100644 --- a/src/utility/solver.cpp +++ b/src/utility/solver.cpp @@ -57,9 +57,21 @@ namespace storm { default: return std::make_unique<storm::solver::GmmxxLinearEquationSolver<ValueType>>(matrix); } } + + std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalNumber>> LinearEquationSolverFactory<storm::RationalNumber>::create(storm::storage::SparseMatrix<storm::RationalNumber> const& matrix) const { + storm::solver::EquationSolverType equationSolver = storm::settings::getModule<storm::settings::modules::MarkovChainSettings>().getEquationSolver(); + switch (equationSolver) { + case storm::solver::EquationSolverType::Elimination: return std::make_unique<storm::solver::EliminationLinearEquationSolver<storm::RationalNumber>>(matrix); + default: return std::make_unique<storm::solver::EigenLinearEquationSolver<storm::RationalNumber>>(matrix); + } + } std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> LinearEquationSolverFactory<storm::RationalFunction>::create(storm::storage::SparseMatrix<storm::RationalFunction> const& matrix) const { - return std::make_unique<storm::solver::EigenLinearEquationSolver<storm::RationalFunction>>(matrix); + storm::solver::EquationSolverType equationSolver = storm::settings::getModule<storm::settings::modules::MarkovChainSettings>().getEquationSolver(); + switch (equationSolver) { + case storm::solver::EquationSolverType::Elimination: return std::make_unique<storm::solver::EliminationLinearEquationSolver<storm::RationalFunction>>(matrix); + default: return std::make_unique<storm::solver::EigenLinearEquationSolver<storm::RationalFunction>>(matrix); + } } template<typename ValueType> @@ -216,6 +228,7 @@ namespace storm { template class MinMaxLinearEquationSolverFactory<double>; template class GameSolverFactory<double>; + template class LinearEquationSolverFactory<storm::RationalNumber>; template class EigenLinearEquationSolverFactory<storm::RationalFunction>; } } diff --git a/src/utility/solver.h b/src/utility/solver.h index 201cfccb1..4791737a8 100644 --- a/src/utility/solver.h +++ b/src/utility/solver.h @@ -88,7 +88,19 @@ namespace storm { */ virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix) const; }; - + + template<> + class LinearEquationSolverFactory<storm::RationalNumber> { + public: + /*! + * Creates a new linear equation solver instance with the given matrix. + * + * @param matrix The matrix that defines the equation system. + * @return A pointer to the newly created solver. + */ + virtual std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalNumber>> create(storm::storage::SparseMatrix<storm::RationalNumber> const& matrix) const; + }; + template<> class LinearEquationSolverFactory<storm::RationalFunction> { public: diff --git a/src/utility/stateelimination.cpp b/src/utility/stateelimination.cpp index bfb967da2..c2882dcde 100644 --- a/src/utility/stateelimination.cpp +++ b/src/utility/stateelimination.cpp @@ -153,13 +153,14 @@ namespace storm { template uint_fast64_t computeStatePenaltyRegularExpression(storm::storage::sparse::state_type const& state, storm::storage::FlexibleSparseMatrix<double> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<double> const& backwardTransitions, std::vector<double> const& oneStepProbabilities); template uint_fast64_t estimateComplexity(storm::RationalNumber const& value); - -#ifdef STORM_HAVE_CARL + template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities, storm::storage::FlexibleSparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber>& oneStepProbabilities, storm::storage::BitVector const& states); + template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state, storm::storage::FlexibleSparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& oneStepProbabilities); + template uint_fast64_t computeStatePenaltyRegularExpression(storm::storage::sparse::state_type const& state, storm::storage::FlexibleSparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& oneStepProbabilities); + template uint_fast64_t estimateComplexity(storm::RationalFunction const& value); template std::shared_ptr<StatePriorityQueue> createStatePriorityQueue(boost::optional<std::vector<uint_fast64_t>> const& distanceBasedStatePriorities, storm::storage::FlexibleSparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction>& oneStepProbabilities, storm::storage::BitVector const& states); template uint_fast64_t computeStatePenalty(storm::storage::sparse::state_type const& state, storm::storage::FlexibleSparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& oneStepProbabilities); template uint_fast64_t computeStatePenaltyRegularExpression(storm::storage::sparse::state_type const& state, storm::storage::FlexibleSparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::FlexibleSparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& oneStepProbabilities); -#endif } } } \ No newline at end of file diff --git a/src/utility/storm.h b/src/utility/storm.h index 8f0f5b79f..d590aa033 100644 --- a/src/utility/storm.h +++ b/src/utility/storm.h @@ -198,14 +198,6 @@ namespace storm { return model; } - - template<typename ValueType> - void generateCounterexamples(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<ValueType>> model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) { - for (auto const& formula : formulas) { - generateCounterexample(program, model, formula); - } - } - template<typename ValueType> void generateCounterexample(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<ValueType>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { if (storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isMinimalCommandSetGenerationSet()) { @@ -227,13 +219,23 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No suitable counterexample representation selected."); } } - -#ifdef STORM_HAVE_CARL + + template<> + inline void generateCounterexample(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { + STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unable to generate counterexample for parametric model."); + } + template<> inline void generateCounterexample(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unable to generate counterexample for parametric model."); } -#endif + + template<typename ValueType> + void generateCounterexamples(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<ValueType>> model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) { + for (auto const& formula : formulas) { + generateCounterexample(program, model, formula); + } + } template<typename ValueType, storm::dd::DdType DdType> std::unique_ptr<storm::modelchecker::CheckResult> verifyModel(std::shared_ptr<storm::models::ModelBase> model, std::shared_ptr<storm::logic::Formula const> const& formula, bool onlyInitialStatesRelevant) { @@ -310,7 +312,32 @@ namespace storm { return result; } - + + template<> + inline std::unique_ptr<storm::modelchecker::CheckResult> verifySparseModel(std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> model, std::shared_ptr<storm::logic::Formula const> const& formula, bool onlyInitialStatesRelevant) { + storm::modelchecker::CheckTask<storm::logic::Formula> task(*formula, onlyInitialStatesRelevant); + + std::unique_ptr<storm::modelchecker::CheckResult> result; + if (model->getType() == storm::models::ModelType::Dtmc) { + std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalNumber>> dtmc = model->template as<storm::models::sparse::Dtmc<storm::RationalNumber>>(); + storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<storm::RationalNumber>> modelchecker(*dtmc); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); + } else { + storm::modelchecker::SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<storm::RationalNumber>> modelchecker(*dtmc); + storm::modelchecker::CheckTask<storm::logic::Formula> task(*formula, onlyInitialStatesRelevant); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The exact engine currently does not support this property on DTMCs."); + } + } + } else { + STORM_LOG_ASSERT(false, "Illegal model type."); + } + return result; + } + #ifdef STORM_HAVE_CARL inline void exportParametricResultToFile(storm::RationalFunction const& result, storm::models::sparse::Dtmc<storm::RationalFunction>::ConstraintCollector const& constraintCollector, std::string const& path) { std::ofstream filestream; @@ -330,15 +357,26 @@ namespace storm { template<> inline std::unique_ptr<storm::modelchecker::CheckResult> verifySparseModel(std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model, std::shared_ptr<storm::logic::Formula const> const& formula, bool onlyInitialStatesRelevant) { + storm::modelchecker::CheckTask<storm::logic::Formula> task(*formula, onlyInitialStatesRelevant); + std::unique_ptr<storm::modelchecker::CheckResult> result; if (model->getType() == storm::models::ModelType::Dtmc) { std::shared_ptr<storm::models::sparse::Dtmc<storm::RationalFunction>> dtmc = model->template as<storm::models::sparse::Dtmc<storm::RationalFunction>>(); - storm::modelchecker::SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>> modelchecker(*dtmc); - storm::modelchecker::CheckTask<storm::logic::Formula> task(*formula, onlyInitialStatesRelevant); - if (modelchecker.canHandle(task)) { - result = modelchecker.check(task); + if (storm::settings::getModule<storm::settings::modules::MarkovChainSettings>().getEquationSolver() == storm::solver::EquationSolverType::Elimination) { + storm::modelchecker::SparseDtmcEliminationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>> modelchecker(*dtmc); + storm::modelchecker::CheckTask<storm::logic::Formula> task(*formula, onlyInitialStatesRelevant); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The parametric engine currently does not support this property on DTMCs."); + } } else { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The parametric engine currently does not support this property on DTMCs."); + storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>> modelchecker(*dtmc); + if (modelchecker.canHandle(task)) { + result = modelchecker.check(task); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The parametric engine currently does not support this property on DTMCs."); + } } } else if (model->getType() == storm::models::ModelType::Mdp) { std::shared_ptr<storm::models::sparse::Mdp<storm::RationalFunction>> mdp = model->template as<storm::models::sparse::Mdp<storm::RationalFunction>>(); diff --git a/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp index f8b262e2d..8462fa8e6 100644 --- a/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp +++ b/test/functional/modelchecker/EigenDtmcPrctlModelCheckerTest.cpp @@ -14,7 +14,7 @@ #include "src/settings/SettingMemento.h" #include "src/parser/AutoParser.h" #include "src/parser/PrismParser.h" -#include "src/builder/ExplicitPrismModelBuilder.h" +#include "src/builder/ExplicitModelBuilder.h" TEST(EigenDtmcPrctlModelCheckerTest, Die) { std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_CPP_BASE_PATH "/examples/dtmc/die/die.tra", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.lab", "", STORM_CPP_BASE_PATH "/examples/dtmc/die/die.coin_flips.trans.rew"); @@ -63,7 +63,7 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die) { TEST(EigenDtmcPrctlModelCheckerTest, Die_RationalNumber) { // FIXME: this should use rational numbers not functions. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/die.pm"); - std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>(program).translate(); + std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model = storm::builder::ExplicitModelBuilder<storm::RationalFunction>(program).build(); // A parser that we use for conveniently constructing the formulas. storm::parser::FormulaParser formulaParser; @@ -109,7 +109,7 @@ TEST(EigenDtmcPrctlModelCheckerTest, Die_RationalNumber) { TEST(EigenDtmcPrctlModelCheckerTest, Die_RationalFunction) { // FIXME: this should use rational numbers not functions. storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/builder/parametric_die.pm"); - std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model = storm::builder::ExplicitPrismModelBuilder<storm::RationalFunction>(program).translate(); + std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> model = storm::builder::ExplicitModelBuilder<storm::RationalFunction>(program).build(); // A parser that we use for conveniently constructing the formulas. storm::parser::FormulaParser formulaParser; @@ -378,7 +378,7 @@ TEST(EigenDtmcPrctlModelCheckerTest, LRA) { TEST(EigenDtmcPrctlModelCheckerTest, Conditional) { storm::prism::Program program = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/modelchecker/test_conditional.pm"); - std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitPrismModelBuilder<double>(program).translate(); + std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program).build(); ASSERT_TRUE(model->getType() == storm::models::ModelType::Dtmc); ASSERT_EQ(4ul, model->getNumberOfStates()); ASSERT_EQ(5ul, model->getNumberOfTransitions());