Browse Source

started reworking reward models

Former-commit-id: 49d9106451
main
dehnert 10 years ago
parent
commit
dcd42d5653
  1. 25
      src/logic/RewardOperatorFormula.cpp
  2. 36
      src/logic/RewardOperatorFormula.h
  3. 22
      src/modelchecker/AbstractModelChecker.cpp
  4. 8
      src/modelchecker/AbstractModelChecker.h
  5. 151
      src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
  6. 30
      src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
  7. 103
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
  8. 30
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
  9. 42
      src/modelchecker/propositional/SparsePropositionalModelChecker.cpp
  10. 16
      src/modelchecker/propositional/SparsePropositionalModelChecker.h
  11. 2
      src/models/ModelBase.h
  12. 26
      src/models/sparse/Ctmc.cpp
  13. 16
      src/models/sparse/Ctmc.h
  14. 22
      src/models/sparse/DeterministicModel.cpp
  15. 16
      src/models/sparse/DeterministicModel.h
  16. 49
      src/models/sparse/Dtmc.cpp
  17. 16
      src/models/sparse/Dtmc.h
  18. 68
      src/models/sparse/MarkovAutomaton.cpp
  19. 14
      src/models/sparse/MarkovAutomaton.h
  20. 45
      src/models/sparse/Mdp.cpp
  21. 16
      src/models/sparse/Mdp.h
  22. 204
      src/models/sparse/Model.cpp
  23. 117
      src/models/sparse/Model.h
  24. 47
      src/models/sparse/NondeterministicModel.cpp
  25. 16
      src/models/sparse/NondeterministicModel.h
  26. 122
      src/models/sparse/StandardRewardModel.cpp
  27. 159
      src/models/sparse/StandardRewardModel.h
  28. 9
      src/parser/FormulaParser.cpp
  29. 3
      src/parser/FormulaParser.h
  30. 48
      src/storage/StronglyConnectedComponentDecomposition.cpp
  31. 12
      src/storage/StronglyConnectedComponentDecomposition.h
  32. 12
      src/storage/prism/Update.cpp
  33. 18
      src/utility/vector.h

25
src/logic/RewardOperatorFormula.cpp

@ -2,19 +2,19 @@
namespace storm {
namespace logic {
RewardOperatorFormula::RewardOperatorFormula(std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(boost::optional<OptimalityType>(), boost::optional<ComparisonType>(), boost::optional<double>(), subformula) {
RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::optional<OptimalityType>(), boost::optional<ComparisonType>(), boost::optional<double>(), subformula) {
// Intentionally left empty.
}
RewardOperatorFormula::RewardOperatorFormula(ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(boost::optional<OptimalityType>(), boost::optional<ComparisonType>(comparisonType), boost::optional<double>(bound), subformula) {
RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::optional<OptimalityType>(), boost::optional<ComparisonType>(comparisonType), boost::optional<double>(bound), subformula) {
// Intentionally left empty.
}
RewardOperatorFormula::RewardOperatorFormula(OptimalityType optimalityType, ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(boost::optional<OptimalityType>(optimalityType), boost::optional<ComparisonType>(comparisonType), boost::optional<double>(bound), subformula) {
RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, OptimalityType optimalityType, ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::optional<OptimalityType>(optimalityType), boost::optional<ComparisonType>(comparisonType), boost::optional<double>(bound), subformula) {
// Intentionally left empty.
}
RewardOperatorFormula::RewardOperatorFormula(OptimalityType optimalityType, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(boost::optional<OptimalityType>(optimalityType), boost::optional<ComparisonType>(), boost::optional<double>(), subformula) {
RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, OptimalityType optimalityType, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::optional<OptimalityType>(optimalityType), boost::optional<ComparisonType>(), boost::optional<double>(), subformula) {
// Intentionally left empty.
}
@ -34,12 +34,27 @@ namespace storm {
return this->getSubformula().containsRewardOperator();
}
RewardOperatorFormula::RewardOperatorFormula(boost::optional<OptimalityType> optimalityType, boost::optional<ComparisonType> comparisonType, boost::optional<double> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, comparisonType, bound, subformula) {
bool RewardOperatorFormula::hasRewardModelName() const {
return static_cast<bool>(this->rewardModelName);
}
std::string const& RewardOperatorFormula::getRewardModelName() const {
return this->rewardModelName.get();
}
boost::optional<std::string> const& RewardOperatorFormula::getOptionalRewardModelName() const {
return this->rewardModelName;
}
RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, boost::optional<OptimalityType> optimalityType, boost::optional<ComparisonType> comparisonType, boost::optional<double> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, comparisonType, bound, subformula), rewardModelName(rewardModelName) {
// Intentionally left empty.
}
std::ostream& RewardOperatorFormula::writeToStream(std::ostream& out) const {
out << "R";
if (this->hasRewardModelName()) {
out << "{\"" << this->getRewardModelName() << "\"}";
}
OperatorFormula::writeToStream(out);
return out;
}

36
src/logic/RewardOperatorFormula.h

@ -7,11 +7,11 @@ namespace storm {
namespace logic {
class RewardOperatorFormula : public OperatorFormula {
public:
RewardOperatorFormula(std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(OptimalityType optimalityType, ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(OptimalityType optimalityType, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(boost::optional<OptimalityType> optimalityType, boost::optional<ComparisonType> comparisonType, boost::optional<double> bound, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, OptimalityType optimalityType, ComparisonType comparisonType, double bound, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, OptimalityType optimalityType, std::shared_ptr<Formula const> const& subformula);
RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, boost::optional<OptimalityType> optimalityType, boost::optional<ComparisonType> comparisonType, boost::optional<double> bound, std::shared_ptr<Formula const> const& subformula);
virtual ~RewardOperatorFormula() {
// Intentionally left empty.
@ -24,6 +24,32 @@ namespace storm {
virtual bool containsNestedRewardOperators() const override;
virtual std::ostream& writeToStream(std::ostream& out) const override;
/*!
* Retrieves whether the reward model refers to a specific reward model.
*
* @return True iff the reward model refers to a specific reward model.
*/
bool hasRewardModelName() const;
/*!
* Retrieves the optional representing the reward model name this property refers to.
*
* @return The reward model name this property refers to (if any).
*/
boost::optional<std::string> const& getOptionalRewardModelName() const;
/*!
* Retrieves the name of the reward model this property refers to (if any). Note that it is illegal to call
* this function if the operator does not have a specific reward model it is referring to.
*
* @return The name of the reward model this propertye refers to.
*/
std::string const& getRewardModelName() const;
private:
// The (optional) name of the reward model this property refers to.
boost::optional<std::string> rewardModelName;
};
}
}

22
src/modelchecker/AbstractModelChecker.cpp

@ -63,26 +63,26 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << pathFormula << ".");
}
std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(storm::logic::RewardPathFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(storm::logic::RewardPathFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
if (rewardPathFormula.isCumulativeRewardFormula()) {
return this->computeCumulativeRewards(rewardPathFormula.asCumulativeRewardFormula(), qualitative, optimalityType);
return this->computeCumulativeRewards(rewardPathFormula.asCumulativeRewardFormula(), rewardModelName, qualitative, optimalityType);
} else if (rewardPathFormula.isInstantaneousRewardFormula()) {
return this->computeInstantaneousRewards(rewardPathFormula.asInstantaneousRewardFormula(), qualitative, optimalityType);
return this->computeInstantaneousRewards(rewardPathFormula.asInstantaneousRewardFormula(), rewardModelName, qualitative, optimalityType);
} else if (rewardPathFormula.isReachabilityRewardFormula()) {
return this->computeReachabilityRewards(rewardPathFormula.asReachabilityRewardFormula(), qualitative, optimalityType);
return this->computeReachabilityRewards(rewardPathFormula.asReachabilityRewardFormula(), rewardModelName, qualitative, optimalityType);
}
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid.");
}
std::unique_ptr<CheckResult> AbstractModelChecker::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> AbstractModelChecker::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << rewardPathFormula << ".");
}
std::unique_ptr<CheckResult> AbstractModelChecker::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> AbstractModelChecker::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << rewardPathFormula << ".");
}
std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << rewardPathFormula << ".");
}
@ -197,15 +197,15 @@ namespace storm {
std::unique_ptr<CheckResult> result;
if (stateFormula.hasOptimalityType()) {
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), qualitative, stateFormula.getOptimalityType());
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), stateFormula.getOptionalRewardModelName(), qualitative, stateFormula.getOptimalityType());
} else if (stateFormula.hasBound()) {
if (stateFormula.getComparisonType() == storm::logic::ComparisonType::Less || stateFormula.getComparisonType() == storm::logic::ComparisonType::LessEqual) {
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), qualitative, storm::logic::OptimalityType::Maximize);
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), stateFormula.getOptionalRewardModelName(), qualitative, storm::logic::OptimalityType::Maximize);
} else {
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), qualitative, storm::logic::OptimalityType::Minimize);
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), stateFormula.getOptionalRewardModelName(), qualitative, storm::logic::OptimalityType::Minimize);
}
} else {
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), qualitative);
result = this->computeRewards(stateFormula.getSubformula().asRewardPathFormula(), stateFormula.getOptionalRewardModelName(), qualitative);
}
if (stateFormula.hasBound()) {

8
src/modelchecker/AbstractModelChecker.h

@ -40,10 +40,10 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
// The methods to compute the rewards for path formulas.
virtual std::unique_ptr<CheckResult> computeRewards(storm::logic::RewardPathFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeRewards(storm::logic::RewardPathFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
// The methods to compute the long-run average and expected time.
virtual std::unique_ptr<CheckResult> computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());

151
src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp

@ -18,23 +18,23 @@
namespace storm {
namespace modelchecker {
template<typename ValueType>
SparseDtmcPrctlModelChecker<ValueType>::SparseDtmcPrctlModelChecker(storm::models::sparse::Dtmc<ValueType> const& model, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SparsePropositionalModelChecker<ValueType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) {
template<typename SparseDtmcModelType>
SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SparsePropositionalModelChecker<SparseDtmcModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) {
// Intentionally left empty.
}
template<typename ValueType>
SparseDtmcPrctlModelChecker<ValueType>::SparseDtmcPrctlModelChecker(storm::models::sparse::Dtmc<ValueType> const& model) : SparsePropositionalModelChecker<ValueType>(model), linearEquationSolverFactory(new storm::utility::solver::LinearEquationSolverFactory<ValueType>()) {
template<typename SparseDtmcModelType>
SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model) : SparsePropositionalModelChecker<SparseDtmcModelType>(model), linearEquationSolverFactory(new storm::utility::solver::LinearEquationSolverFactory<ValueType>()) {
// Intentionally left empty.
}
template<typename ValueType>
bool SparseDtmcPrctlModelChecker<ValueType>::canHandle(storm::logic::Formula const& formula) const {
template<typename SparseDtmcModelType>
bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(storm::logic::Formula const& formula) const {
return formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula();
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeBoundedUntilProbabilitiesHelper(storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound) const {
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeBoundedUntilProbabilitiesHelper(storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound) const {
std::vector<ValueType> result(this->getModel().getNumberOfStates(), storm::utility::zero<ValueType>());
// If we identify the states that have probability 0 of reaching the target states, we can exclude them in the further analysis.
@ -65,8 +65,8 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(pathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
@ -76,8 +76,8 @@ namespace storm {
return result;
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeNextProbabilitiesHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeNextProbabilitiesHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// Create the vector with which to multiply and initialize it correctly.
std::vector<ValueType> result(transitionMatrix.getRowCount());
storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>());
@ -88,15 +88,15 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeNextProbabilities(storm::logic::NextFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeNextProbabilities(storm::logic::NextFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> subResultPointer = this->check(pathFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeNextProbabilitiesHelper(this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory)));
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeUntilProbabilitiesHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeUntilProbabilitiesHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// We need to identify the states which have to be taken out of the matrix, i.e.
// all states that have probability 0 and 1 of satisfying the until-formula.
std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 = storm::utility::graph::performProb01(backwardTransitions, phiStates, psiStates);
@ -152,8 +152,8 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();;
@ -161,26 +161,36 @@ namespace storm {
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeUntilProbabilitiesHelper(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), qualitative, *this->linearEquationSolverFactory)));
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeCumulativeRewardsHelper(uint_fast64_t stepBound) const {
// Only compute the result if the model has at least one reward model.
STORM_LOG_THROW(this->getModel().hasStateRewards() || this->getModel().hasTransitionRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeCumulativeRewardsHelper(RewardModelType const& rewardModel, uint_fast64_t stepBound) const {
// Compute the reward vector to add in each step based on the available reward models.
std::vector<ValueType> totalRewardVector;
if (this->getModel().hasTransitionRewards()) {
totalRewardVector = this->getModel().getTransitionMatrix().getPointwiseProductRowSumVector(this->getModel().getTransitionRewardMatrix());
if (this->getModel().hasStateRewards()) {
storm::utility::vector::addVectors(totalRewardVector, this->getModel().getStateRewardVector(), totalRewardVector);
if (rewardModel.hasTransitionRewards()) {
totalRewardVector = this->getModel().getTransitionMatrix().getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
if (rewardModel.hasStateRewards()) {
storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateRewardVector(), totalRewardVector);
}
if (rewardModel.hasStateActionRewards()) {
storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
}
} else if (rewardModel.hasStateRewards()) {
totalRewardVector = std::vector<ValueType>(rewardModel.getStateRewardVector());
if (rewardModel.hasStateActionRewards()) {
storm::utility::vector::addVectors(totalRewardVector, rewardModel.getStateActionRewardVector(), totalRewardVector);
}
} else {
totalRewardVector = std::vector<ValueType>(this->getModel().getStateRewardVector());
totalRewardVector = std::vector<ValueType>(rewardModel.getStateActionRewardVector());
}
// Initialize result to either the state rewards of the model or the null vector.
std::vector<ValueType> result;
if (this->getModel().hasStateRewards()) {
result = std::vector<ValueType>(this->getModel().getStateRewardVector());
if (rewardModel.hasStateRewards()) {
result = std::vector<ValueType>(rewardModel.getStateRewardVector());
if (rewardModel.hasStateActionRewards()) {
storm::utility::vector::addVectors(result, rewardModel.getStateActionRewardVector(), result);
}
} else if (rewardModel.hasStateActionRewards()) {
result = std::vector<ValueType>(rewardModel.getStateRewardVector());
} else {
result.resize(this->getModel().getNumberOfStates());
}
@ -193,19 +203,27 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeCumulativeRewardsHelper(rewardPathFormula.getDiscreteTimeBound())));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeCumulativeRewardsHelper(rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound())));
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeInstantaneousRewardsHelper(uint_fast64_t stepCount) const {
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeInstantaneousRewardsHelper(RewardModelType const& rewardModel, uint_fast64_t stepCount) const {
// Only compute the result if the model has a state-based reward this->getModel().
STORM_LOG_THROW(this->getModel().hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
STORM_LOG_THROW(rewardModel.hasStateRewards() || rewardModel.hasStateActionRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
// Initialize result to state rewards of the model.
std::vector<ValueType> result(this->getModel().getStateRewardVector());
std::vector<ValueType> result(this->getModel().getNumberOfStates());
if (rewardModel.hasStateRewards()) {
if (rewardModel.hasStateRewards()) {
storm::utility::vector::addVectors(result, rewardModel.getStateRewardVector(), result);
}
if (rewardModel.hasStateActionRewards()) {
storm::utility::vector::addVectors(result, rewardModel.getStateActionRewardVector(), result);
}
}
// Perform the matrix vector multiplication as often as required by the formula bound.
STORM_LOG_THROW(linearEquationSolverFactory != nullptr, storm::exceptions::InvalidStateException, "No valid linear equation solver available.");
@ -215,16 +233,14 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeInstantaneousRewardsHelper(rewardPathFormula.getDiscreteTimeBound())));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeInstantaneousRewardsHelper(rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound())));
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeReachabilityRewardsHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, boost::optional<std::vector<ValueType>> const& stateRewardVector, boost::optional<storm::storage::SparseMatrix<ValueType>> const& transitionRewardMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, bool qualitative) {
// Only compute the result if the model has at least one reward model.
STORM_LOG_THROW(stateRewardVector || transitionRewardMatrix, storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewardsHelper(RewardModelType const& rewardModel, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, bool qualitative) {
// Determine which states have a reward of infinity by definition.
storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true);
@ -258,28 +274,42 @@ namespace storm {
// Prepare the right-hand side of the equation system.
std::vector<ValueType> b(submatrix.getRowCount());
if (transitionRewardMatrix) {
if (rewardModel.hasTransitionRewards()) {
// If a transition-based reward model is available, we initialize the right-hand
// side to the vector resulting from summing the rows of the pointwise product
// of the transition probability matrix and the transition reward matrix.
std::vector<ValueType> pointwiseProductRowSumVector = transitionMatrix.getPointwiseProductRowSumVector(transitionRewardMatrix.get());
std::vector<ValueType> pointwiseProductRowSumVector = transitionMatrix.getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
storm::utility::vector::selectVectorValues(b, maybeStates, pointwiseProductRowSumVector);
if (stateRewardVector) {
if (rewardModel.hasStateRewards() || rewardModel.hasStateActionRewards()) {
// If a state-based reward model is also available, we need to add this vector
// as well. As the state reward vector contains entries not just for the states
// that we still consider (i.e. maybeStates), we need to extract these values
// first.
std::vector<ValueType> subStateRewards(b.size());
storm::utility::vector::selectVectorValues(subStateRewards, maybeStates, stateRewardVector.get());
storm::utility::vector::addVectors(b, subStateRewards, b);
if (rewardModel.hasStateRewards()) {
storm::utility::vector::selectVectorValues(subStateRewards, maybeStates, rewardModel.getStateRewardVector());
storm::utility::vector::addVectors(b, subStateRewards, b);
}
if (rewardModel.hasStateActionRewards()) {
storm::utility::vector::selectVectorValues(subStateRewards, maybeStates, rewardModel.getStateActionRewardVector());
storm::utility::vector::addVectors(b, subStateRewards, b);
}
}
} else {
// If only a state-based reward model is available, we take this vector as the
// right-hand side. As the state reward vector contains entries not just for the
// states that we still consider (i.e. maybeStates), we need to extract these values
// first.
storm::utility::vector::selectVectorValues(b, maybeStates, stateRewardVector.get());
std::vector<ValueType> subStateRewards(b.size());
if (rewardModel.hasStateRewards()) {
storm::utility::vector::selectVectorValues(subStateRewards, maybeStates, rewardModel.getStateRewardVector());
storm::utility::vector::addVectors(b, subStateRewards, b);
}
if (rewardModel.hasStateActionRewards()) {
storm::utility::vector::selectVectorValues(subStateRewards, maybeStates, rewardModel.getStateActionRewardVector());
storm::utility::vector::addVectors(b, subStateRewards, b);
}
}
// Now solve the resulting equation system.
@ -296,31 +326,26 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeReachabilityRewardsHelper(this->getModel().getTransitionMatrix(), this->getModel().getOptionalStateRewardVector(), this->getModel().getOptionalTransitionRewardMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory, qualitative)));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeReachabilityRewardsHelper(rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory, qualitative)));
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<ValueType>::computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
std::unique_ptr<CheckResult> subResultPointer = this->check(stateFormula);
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(computeLongRunAverageHelper(this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), qualitative, *linearEquationSolverFactory)));
}
template<typename ValueType>
std::vector<ValueType> SparseDtmcPrctlModelChecker<ValueType>::computeLongRunAverageHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template<typename SparseDtmcModelType>
std::vector<typename SparseDtmcPrctlModelChecker<SparseDtmcModelType>::ValueType> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeLongRunAverageHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseCtmcCslModelChecker<ValueType>::computeLongRunAverageHelper(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory);
}
template<typename ValueType>
storm::models::sparse::Dtmc<ValueType> const& SparseDtmcPrctlModelChecker<ValueType>::getModel() const {
return this->template getModelAs<storm::models::sparse::Dtmc<ValueType>>();
}
template class SparseDtmcPrctlModelChecker<double>;
template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>;
}
}

30
src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h

@ -13,38 +13,38 @@ namespace storm {
class HybridDtmcPrctlModelChecker;
// Forward-declare CTMC model checker so we can make it a friend.
template<typename ValueType> class SparseCtmcCslModelChecker;
template<typename SparseModelType> class SparseCtmcCslModelChecker;
template<class ValueType>
class SparseDtmcPrctlModelChecker : public SparsePropositionalModelChecker<ValueType> {
template<class SparseDtmcModelType>
class SparseDtmcPrctlModelChecker : public SparsePropositionalModelChecker<SparseDtmcModelType> {
public:
typedef typename SparseDtmcModelType::ValueType ValueType;
typedef typename SparseDtmcModelType::RewardModelType RewardModelType;
friend class HybridDtmcPrctlModelChecker<storm::dd::DdType::CUDD, ValueType>;
friend class SparseCtmcCslModelChecker<ValueType>;
explicit SparseDtmcPrctlModelChecker(storm::models::sparse::Dtmc<ValueType> const& model);
explicit SparseDtmcPrctlModelChecker(storm::models::sparse::Dtmc<ValueType> const& model, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory);
explicit SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model);
explicit SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory);
// The implemented methods of the AbstractModelChecker interface.
virtual bool canHandle(storm::logic::Formula const& formula) const override;
virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeNextProbabilities(storm::logic::NextFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
protected:
storm::models::sparse::Dtmc<ValueType> const& getModel() const override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>());
virtual std::unique_ptr<CheckResult> computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
private:
// The methods that perform the actual checking.
std::vector<ValueType> computeBoundedUntilProbabilitiesHelper(storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound) const;
static std::vector<ValueType> computeNextProbabilitiesHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
static std::vector<ValueType> computeUntilProbabilitiesHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
std::vector<ValueType> computeInstantaneousRewardsHelper(uint_fast64_t stepCount) const;
std::vector<ValueType> computeCumulativeRewardsHelper(uint_fast64_t stepBound) const;
static std::vector<ValueType> computeReachabilityRewardsHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, boost::optional<std::vector<ValueType>> const& stateRewardVector, boost::optional<storm::storage::SparseMatrix<ValueType>> const& transitionRewardMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, bool qualitative);
std::vector<ValueType> computeInstantaneousRewardsHelper(RewardModelType const& rewardModel, uint_fast64_t stepCount) const;
std::vector<ValueType> computeCumulativeRewardsHelper(RewardModelType const& rewardModel, uint_fast64_t stepBound) const;
static std::vector<ValueType> computeReachabilityRewardsHelper(RewardModelType const& rewardModel, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, bool qualitative);
static std::vector<ValueType> computeLongRunAverageHelper(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
// An object that is used for retrieving linear equation solvers.

103
src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp

@ -21,23 +21,23 @@
namespace storm {
namespace modelchecker {
template<typename ValueType>
SparseMdpPrctlModelChecker<ValueType>::SparseMdpPrctlModelChecker(storm::models::sparse::Mdp<ValueType> const& model) : SparsePropositionalModelChecker<ValueType>(model), MinMaxLinearEquationSolverFactory(new storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType>()) {
template<typename SparseMdpModelType>
SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model) : SparsePropositionalModelChecker<SparseMdpModelType>(model), MinMaxLinearEquationSolverFactory(new storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType>()) {
// Intentionally left empty.
}
template<typename ValueType>
SparseMdpPrctlModelChecker<ValueType>::SparseMdpPrctlModelChecker(storm::models::sparse::Mdp<ValueType> const& model, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& MinMaxLinearEquationSolverFactory) : SparsePropositionalModelChecker<ValueType>(model), MinMaxLinearEquationSolverFactory(std::move(MinMaxLinearEquationSolverFactory)) {
template<typename SparseMdpModelType>
SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& MinMaxLinearEquationSolverFactory) : SparsePropositionalModelChecker<SparseMdpModelType>(model), MinMaxLinearEquationSolverFactory(std::move(MinMaxLinearEquationSolverFactory)) {
// Intentionally left empty.
}
template<typename ValueType>
bool SparseMdpPrctlModelChecker<ValueType>::canHandle(storm::logic::Formula const& formula) const {
template<typename SparseMdpModelType>
bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(storm::logic::Formula const& formula) const {
return formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula();
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeBoundedUntilProbabilitiesHelper(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound) const {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeBoundedUntilProbabilitiesHelper(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound) const {
std::vector<ValueType> result(this->getModel().getNumberOfStates(), storm::utility::zero<ValueType>());
// Determine the states that have 0 probability of reaching the target states.
@ -70,8 +70,8 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
@ -81,8 +81,8 @@ namespace storm {
return result;
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeNextProbabilitiesHelper(bool minimize, storm::storage::BitVector const& nextStates) {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeNextProbabilitiesHelper(bool minimize, storm::storage::BitVector const& nextStates) {
// Create the vector with which to multiply and initialize it correctly.
std::vector<ValueType> result(this->getModel().getNumberOfStates());
storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>());
@ -94,21 +94,21 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeNextProbabilities(storm::logic::NextFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeNextProbabilities(storm::logic::NextFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(pathFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeNextProbabilitiesHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, subResult.getTruthValuesVector())));
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeUntilProbabilitiesHelper(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) const {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeUntilProbabilitiesHelper(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) const {
return computeUntilProbabilitiesHelper(minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), phiStates, psiStates, *MinMaxLinearEquationSolverFactory, qualitative);
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeUntilProbabilitiesHelper(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative) {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeUntilProbabilitiesHelper(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative) {
size_t numberOfStates = phiStates.size();
// We need to identify the states which have to be taken out of the matrix, i.e.
@ -164,28 +164,32 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(SparseMdpPrctlModelChecker<ValueType>::computeUntilProbabilitiesHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), *MinMaxLinearEquationSolverFactory, qualitative)));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(SparseMdpPrctlModelChecker<SparseMdpModelType>::computeUntilProbabilitiesHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), *MinMaxLinearEquationSolverFactory, qualitative)));
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeCumulativeRewardsHelper(bool minimize, uint_fast64_t stepBound) const {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeCumulativeRewardsHelper(RewardModelType const& rewardModel, bool minimize, uint_fast64_t stepBound) const {
// Only compute the result if the model has at least one reward this->getModel().
STORM_LOG_THROW(this->getModel().hasStateRewards() || this->getModel().hasTransitionRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
// Compute the reward vector to add in each step based on the available reward models.
std::vector<ValueType> totalRewardVector;
if (this->getModel().hasTransitionRewards()) {
totalRewardVector = this->getModel().getTransitionMatrix().getPointwiseProductRowSumVector(this->getModel().getTransitionRewardMatrix());
if (this->getModel().hasStateRewards()) {
if (rewardModel.hasTransitionRewards()) {
totalRewardVector = this->getModel().getTransitionMatrix().getPointwiseProductRowSumVector(rewardModel.getTransitionRewardMatrix());
std::vector<ValueType>
if (rewardModel.hasStateRewards()) {
storm::utility::vector::addVectors(totalRewardVector, this->getModel().getStateRewardVector(), totalRewardVector);
}
if (rewardModel.hasStateActionRewards()) {
}
} else {
totalRewardVector = std::vector<ValueType>(this->getModel().getStateRewardVector());
}
@ -204,15 +208,15 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeCumulativeRewardsHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, rewardPathFormula.getDiscreteTimeBound())));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeCumulativeRewardsHelper(rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), optimalityType.get() == storm::logic::OptimalityType::Minimize, rewardPathFormula.getDiscreteTimeBound())));
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeInstantaneousRewardsHelper(bool minimize, uint_fast64_t stepCount) const {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeInstantaneousRewardsHelper(RewardModelType const& rewardModel, bool minimize, uint_fast64_t stepCount) const {
// Only compute the result if the model has a state-based reward this->getModel().
STORM_LOG_THROW(this->getModel().hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
@ -226,15 +230,15 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeInstantaneousRewardsHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, rewardPathFormula.getDiscreteTimeBound())));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeInstantaneousRewardsHelper(rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), optimalityType.get() == storm::logic::OptimalityType::Minimize, rewardPathFormula.getDiscreteTimeBound())));
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeReachabilityRewardsHelper(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, boost::optional<std::vector<ValueType>> const& stateRewardVector, boost::optional<storm::storage::SparseMatrix<ValueType>> const& transitionRewardMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative) const {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewardsHelper(RewardModelType const& rewardModel, bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, boost::optional<std::vector<ValueType>> const& stateRewardVector, boost::optional<storm::storage::SparseMatrix<ValueType>> const& transitionRewardMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative) const {
// Only compute the result if the model has at least one reward this->getModel().
STORM_LOG_THROW(stateRewardVector || transitionRewardMatrix, storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
@ -315,17 +319,17 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeReachabilityRewardsHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getOptionalStateRewardVector(), this->getModel().getOptionalTransitionRewardMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *this->MinMaxLinearEquationSolverFactory, qualitative)));
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeReachabilityRewardsHelper(rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *this->MinMaxLinearEquationSolverFactory, qualitative)));
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlModelChecker<ValueType>::computeLongRunAverageHelper(bool minimize, storm::storage::BitVector const& psiStates, bool qualitative) const {
template<typename SparseMdpModelType>
std::vector<typename SparseMdpModelType::ValueType> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeLongRunAverageHelper(bool minimize, storm::storage::BitVector const& psiStates, bool qualitative) const {
// If there are no goal states, we avoid the computation and directly return zero.
auto numOfStates = this->getModel().getNumberOfStates();
if (psiStates.empty()) {
@ -475,8 +479,8 @@ namespace storm {
return result;
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<ValueType>::computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative, boost::optional<storm::logic::OptimalityType> const& optimalityType) {
STORM_LOG_THROW(optimalityType, storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(stateFormula);
@ -485,8 +489,8 @@ namespace storm {
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(this->computeLongRunAverageHelper(optimalityType.get() == storm::logic::OptimalityType::Minimize, subResult.getTruthValuesVector(), qualitative)));
}
template<typename ValueType>
ValueType SparseMdpPrctlModelChecker<ValueType>::computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::storage::MaximalEndComponent const& mec) {
template<typename SparseMdpModelType>
typename SparseMdpModelType::ValueType SparseMdpPrctlModelChecker<SparseMdpModelType>::computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::storage::MaximalEndComponent const& mec) {
std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC");
solver->setModelSense(minimize ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
@ -528,12 +532,7 @@ namespace storm {
solver->optimize();
return solver->getContinuousValue(lambda);
}
template<typename ValueType>
storm::models::sparse::Mdp<ValueType> const& SparseMdpPrctlModelChecker<ValueType>::getModel() const {
return this->template getModelAs<storm::models::sparse::Mdp<ValueType>>();
}
template class SparseMdpPrctlModelChecker<double>;
template class SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>>;
}
}

30
src/modelchecker/prctl/SparseMdpPrctlModelChecker.h

@ -20,41 +20,41 @@ namespace storm {
namespace modelchecker {
// Forward-declare other model checkers to make them friend classes.
template<typename ValueType>
template<typename SparseMarkovAutomatonModelType>
class SparseMarkovAutomatonCslModelChecker;
template<class ValueType>
class SparseMdpPrctlModelChecker : public SparsePropositionalModelChecker<ValueType> {
template<class SparseMdpModelType>
class SparseMdpPrctlModelChecker : public SparsePropositionalModelChecker<SparseMdpModelType> {
public:
friend class SparseMarkovAutomatonCslModelChecker<ValueType>;
typedef typename SparseMdpModelType::ValueType ValueType;
typedef typename SparseMdpModelType::RewardModelType RewardModelType;
friend class SparseMarkovAutomatonCslModelChecker<SparseMdpModelType>;
friend class storm::counterexamples::SMTMinimalCommandSetGenerator<ValueType>;
friend class storm::counterexamples::MILPMinimalLabelSetGenerator<ValueType>;
explicit SparseMdpPrctlModelChecker(storm::models::sparse::Mdp<ValueType> const& model);
explicit SparseMdpPrctlModelChecker(storm::models::sparse::Mdp<ValueType> const& model, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& MinMaxLinearEquationSolverFactory);
explicit SparseMdpPrctlModelChecker(SparseMdpModelType const& model);
explicit SparseMdpPrctlModelChecker(SparseMdpModelType const& model, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& MinMaxLinearEquationSolverFactory);
// The implemented methods of the AbstractModelChecker interface.
virtual bool canHandle(storm::logic::Formula const& formula) const override;
virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(storm::logic::BoundedUntilFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeNextProbabilities(storm::logic::NextFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(storm::logic::UntilFormula const& pathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(storm::logic::CumulativeRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(storm::logic::InstantaneousRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(storm::logic::ReachabilityRewardFormula const& rewardPathFormula, boost::optional<std::string> const& rewardModelName = boost::optional<std::string>(), bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverage(storm::logic::StateFormula const& stateFormula, bool qualitative = false, boost::optional<storm::logic::OptimalityType> const& optimalityType = boost::optional<storm::logic::OptimalityType>()) override;
protected:
storm::models::sparse::Mdp<ValueType> const& getModel() const override;
private:
// The methods that perform the actual checking.
std::vector<ValueType> computeBoundedUntilProbabilitiesHelper(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound) const;
std::vector<ValueType> computeNextProbabilitiesHelper(bool minimize, storm::storage::BitVector const& nextStates);
std::vector<ValueType> computeUntilProbabilitiesHelper(bool minimize, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) const;
static std::vector<ValueType> computeUntilProbabilitiesHelper(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative);
std::vector<ValueType> computeInstantaneousRewardsHelper(bool minimize, uint_fast64_t stepCount) const;
std::vector<ValueType> computeCumulativeRewardsHelper(bool minimize, uint_fast64_t stepBound) const;
std::vector<ValueType> computeReachabilityRewardsHelper(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, boost::optional<std::vector<ValueType>> const& stateRewardVector, boost::optional<storm::storage::SparseMatrix<ValueType>> const& transitionRewardMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative) const;
std::vector<ValueType> computeInstantaneousRewardsHelper(RewardModelType const& rewardModel, bool minimize, uint_fast64_t stepCount) const;
std::vector<ValueType> computeCumulativeRewardsHelper(RewardModelType const& rewardModel, bool minimize, uint_fast64_t stepBound) const;
std::vector<ValueType> computeReachabilityRewardsHelper(RewardModelType const& rewardModel, bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& MinMaxLinearEquationSolverFactory, bool qualitative) const;
std::vector<ValueType> computeLongRunAverageHelper(bool minimize, storm::storage::BitVector const& psiStates, bool qualitative) const;
static ValueType computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec);

42
src/modelchecker/propositional/SparsePropositionalModelChecker.cpp

@ -5,6 +5,7 @@
#include "src/models/sparse/Dtmc.h"
#include "src/models/sparse/Ctmc.h"
#include "src/models/sparse/Mdp.h"
#include "src/models/sparse/MarkovAutomaton.h"
#include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
@ -13,18 +14,18 @@
namespace storm {
namespace modelchecker {
template<typename ValueType>
SparsePropositionalModelChecker<ValueType>::SparsePropositionalModelChecker(storm::models::sparse::Model<ValueType> const& model) : model(model) {
template<typename SparseModelType>
SparsePropositionalModelChecker<SparseModelType>::SparsePropositionalModelChecker(SparseModelType const& model) : model(model) {
// Intentionally left empty.
}
template<typename ValueType>
bool SparsePropositionalModelChecker<ValueType>::canHandle(storm::logic::Formula const& formula) const {
template<typename SparseModelType>
bool SparsePropositionalModelChecker<SparseModelType>::canHandle(storm::logic::Formula const& formula) const {
return formula.isPropositionalFormula();
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparsePropositionalModelChecker<ValueType>::checkBooleanLiteralFormula(storm::logic::BooleanLiteralFormula const& stateFormula) {
template<typename SparseModelType>
std::unique_ptr<CheckResult> SparsePropositionalModelChecker<SparseModelType>::checkBooleanLiteralFormula(storm::logic::BooleanLiteralFormula const& stateFormula) {
if (stateFormula.isTrueFormula()) {
return std::unique_ptr<CheckResult>(new ExplicitQualitativeCheckResult(storm::storage::BitVector(model.getNumberOfStates(), true)));
} else {
@ -32,33 +33,28 @@ namespace storm {
}
}
template<typename ValueType>
std::unique_ptr<CheckResult> SparsePropositionalModelChecker<ValueType>::checkAtomicLabelFormula(storm::logic::AtomicLabelFormula const& stateFormula) {
template<typename SparseModelType>
std::unique_ptr<CheckResult> SparsePropositionalModelChecker<SparseModelType>::checkAtomicLabelFormula(storm::logic::AtomicLabelFormula const& stateFormula) {
STORM_LOG_THROW(model.hasLabel(stateFormula.getLabel()), storm::exceptions::InvalidPropertyException, "The property refers to unknown label '" << stateFormula.getLabel() << "'.");
return std::unique_ptr<CheckResult>(new ExplicitQualitativeCheckResult(model.getStates(stateFormula.getLabel())));
}
template<typename ValueType>
storm::models::sparse::Model<ValueType> const& SparsePropositionalModelChecker<ValueType>::getModel() const {
template<typename SparseModelType>
SparseModelType const& SparsePropositionalModelChecker<SparseModelType>::getModel() const {
return model;
}
template<typename ValueType>
template<typename ModelType>
ModelType const& SparsePropositionalModelChecker<ValueType>::getModelAs() const {
return dynamic_cast<ModelType const&>(model);
}
// Explicitly instantiate the template class.
template storm::models::sparse::Dtmc<double> const& SparsePropositionalModelChecker<double>::getModelAs() const;
template storm::models::sparse::Ctmc<double> const& SparsePropositionalModelChecker<double>::getModelAs() const;
template storm::models::sparse::Mdp<double> const& SparsePropositionalModelChecker<double>::getModelAs() const;
template class SparsePropositionalModelChecker<double>;
template class SparsePropositionalModelChecker<storm::models::sparse::Dtmc<double>>;
template class SparsePropositionalModelChecker<storm::models::sparse::Ctmc<double>>;
template class SparsePropositionalModelChecker<storm::models::sparse::Mdp<double>>;
template class SparsePropositionalModelChecker<storm::models::sparse::MarkovAutomaton<double>>;
#ifdef STORM_HAVE_CARL
template storm::models::sparse::Dtmc<storm::RationalFunction> const& SparsePropositionalModelChecker<storm::RationalFunction>::getModelAs() const;
template storm::models::sparse::Mdp<storm::RationalFunction> const& SparsePropositionalModelChecker<storm::RationalFunction>::getModelAs() const;
template class SparsePropositionalModelChecker<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
}
}

16
src/modelchecker/propositional/SparsePropositionalModelChecker.h

@ -8,10 +8,10 @@
namespace storm {
namespace modelchecker {
template<typename ValueType>
template<typename SparseModelType>
class SparsePropositionalModelChecker : public AbstractModelChecker {
public:
explicit SparsePropositionalModelChecker(storm::models::sparse::Model<ValueType> const& model);
explicit SparsePropositionalModelChecker(SparseModelType const& model);
// The implemented methods of the AbstractModelChecker interface.
virtual bool canHandle(storm::logic::Formula const& formula) const override;
@ -24,19 +24,11 @@ namespace storm {
*
* @return The model associated with this model checker instance.
*/
virtual storm::models::sparse::Model<ValueType> const& getModel() const;
/*!
* Retrieves the model associated with this model checker instance as the given template parameter type.
*
* @return The model associated with this model checker instance.
*/
template<typename ModelType>
ModelType const& getModelAs() const;
SparseModelType const& getModel() const;
private:
// The model that is to be analyzed by the model checker.
storm::models::sparse::Model<ValueType> const& model;
SparseModelType const& model;
};
}
}

2
src/models/ModelBase.h

@ -10,7 +10,7 @@
namespace storm {
namespace models {
class ModelBase: public std::enable_shared_from_this<ModelBase> {
class ModelBase : public std::enable_shared_from_this<ModelBase> {
public:
/*!
* Constructs a model of the given type.

26
src/models/sparse/Ctmc.cpp

@ -6,32 +6,30 @@ namespace storm {
namespace models {
namespace sparse {
template<typename ValueType>
Ctmc<ValueType>::Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
template <typename ValueType, typename RewardModelType>
Ctmc<ValueType, RewardModelType>::Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::models::sparse::StateLabeling const& stateLabeling,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: DeterministicModel<ValueType>(storm::models::ModelType::Ctmc, rateMatrix, stateLabeling, optionalStateRewardVector, optionalTransitionRewardMatrix, optionalChoiceLabeling) {
: DeterministicModel<ValueType>(storm::models::ModelType::Ctmc, rateMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
exitRates = createExitRateVector(this->getTransitionMatrix());
}
template<typename ValueType>
Ctmc<ValueType>::Ctmc(storm::storage::SparseMatrix<ValueType>&& rateMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
template <typename ValueType, typename RewardModelType>
Ctmc<ValueType, RewardModelType>::Ctmc(storm::storage::SparseMatrix<ValueType>&& rateMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
std::map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: DeterministicModel<ValueType>(storm::models::ModelType::Ctmc, std::move(rateMatrix), std::move(stateLabeling), std::move(optionalStateRewardVector), std::move(optionalTransitionRewardMatrix), std::move(optionalChoiceLabeling)) {
: DeterministicModel<ValueType>(storm::models::ModelType::Ctmc, std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
// It is important to refer to the transition matrix here, because the given rate matrix has been move elsewhere.
exitRates = createExitRateVector(this->getTransitionMatrix());
}
template<typename ValueType>
std::vector<ValueType> const& Ctmc<ValueType>::getExitRateVector() const {
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> const& Ctmc<ValueType, RewardModelType>::getExitRateVector() const {
return exitRates;
}
template<typename ValueType>
std::vector<ValueType> Ctmc<ValueType>::createExitRateVector(storm::storage::SparseMatrix<ValueType> const& rateMatrix) {
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> Ctmc<ValueType, RewardModelType>::createExitRateVector(storm::storage::SparseMatrix<ValueType> const& rateMatrix) {
std::vector<ValueType> exitRates(rateMatrix.getRowCount());
for (uint_fast64_t row = 0; row < rateMatrix.getRowCount(); ++row) {
exitRates[row] = rateMatrix.getRowSum(row);

16
src/models/sparse/Ctmc.h

@ -14,21 +14,19 @@ namespace storm {
/*!
* This class represents a continuous-time Markov chain.
*/
template <typename ValueType>
class Ctmc : public DeterministicModel<ValueType> {
template<class ValueType, typename RewardModelType = StandardRewardModel<ValueType>>
class Ctmc : public DeterministicModel<ValueType, RewardModelType> {
public:
/*!
* Constructs a model from the given data.
*
* @param rateMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Ctmc(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -36,13 +34,11 @@ namespace storm {
*
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Ctmc(storm::storage::SparseMatrix<ValueType>&& rateMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
Ctmc(Ctmc<ValueType> const& ctmc) = default;

22
src/models/sparse/DeterministicModel.cpp

@ -5,30 +5,28 @@
namespace storm {
namespace models {
namespace sparse {
template <typename ValueType>
DeterministicModel<ValueType>::DeterministicModel(storm::models::ModelType const& modelType,
template <typename ValueType, typename RewardModelType>
DeterministicModel<ValueType, RewardModelType>::DeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: Model<ValueType>(modelType, transitionMatrix, stateLabeling, optionalStateRewardVector, optionalTransitionRewardMatrix, optionalChoiceLabeling) {
: Model<ValueType>(modelType, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
// Intentionally left empty.
}
template <typename ValueType>
DeterministicModel<ValueType>::DeterministicModel(storm::models::ModelType const& modelType,
template <typename ValueType, typename RewardModelType>
DeterministicModel<ValueType, RewardModelType>::DeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: Model<ValueType>(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(optionalStateRewardVector), std::move(optionalTransitionRewardMatrix), std::move(optionalChoiceLabeling)) {
: Model<ValueType>(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
// Intentionally left empty.
}
template <typename ValueType>
void DeterministicModel<ValueType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
template <typename ValueType, typename RewardModelType>
void DeterministicModel<ValueType, RewardModelType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
Model<ValueType>::writeDotToStream(outStream, includeLabeling, subsystem, firstValue, secondValue, stateColoring, colors, scheduler, false);
// Simply iterate over all transitions and draw the arrows with probability information attached.

16
src/models/sparse/DeterministicModel.h

@ -11,8 +11,8 @@ namespace storm {
/*!
* The base class of all sparse deterministic models.
*/
template<class ValueType>
class DeterministicModel: public Model<ValueType> {
template<class ValueType, typename RewardModelType = StandardRewardModel<ValueType>>
class DeterministicModel: public Model<ValueType, RewardModelType> {
public:
/*!
* Constructs a model from the given data.
@ -20,15 +20,13 @@ namespace storm {
* @param modelType The type of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
DeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -37,15 +35,13 @@ namespace storm {
* @param modelType The type of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
DeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
DeterministicModel(DeterministicModel const& other) = default;

49
src/models/sparse/Dtmc.cpp

@ -7,29 +7,24 @@ namespace storm {
namespace models {
namespace sparse {
template<typename ValueType>
Dtmc<ValueType>::Dtmc(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix,
template <typename ValueType, typename RewardModelType>
Dtmc<ValueType, RewardModelType>::Dtmc(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: DeterministicModel<ValueType>(storm::models::ModelType::Dtmc, probabilityMatrix, stateLabeling, optionalStateRewardVector, optionalTransitionRewardMatrix, optionalChoiceLabeling) {
: DeterministicModel<ValueType>(storm::models::ModelType::Dtmc, probabilityMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
STORM_LOG_THROW(this->checkValidityOfProbabilityMatrix(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
STORM_LOG_THROW(!this->hasTransitionRewards() || this->getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
}
template<typename ValueType>
Dtmc<ValueType>::Dtmc(storm::storage::SparseMatrix<ValueType>&& probabilityMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: DeterministicModel<ValueType>(storm::models::ModelType::Dtmc, std::move(probabilityMatrix), std::move(stateLabeling), std::move(optionalStateRewardVector), std::move(optionalTransitionRewardMatrix), std::move(optionalChoiceLabeling)) {
template <typename ValueType, typename RewardModelType>
Dtmc<ValueType, RewardModelType>::Dtmc(storm::storage::SparseMatrix<ValueType>&& probabilityMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
std::map<std::string, RewardModelType>&& rewardModels, boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: DeterministicModel<ValueType>(storm::models::ModelType::Dtmc, std::move(probabilityMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
STORM_LOG_THROW(this->checkValidityOfProbabilityMatrix(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
STORM_LOG_THROW(!this->hasTransitionRewards() || this->getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
}
template<typename ValueType>
Dtmc<ValueType> Dtmc<ValueType>::getSubDtmc(storm::storage::BitVector const& states) const {
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
//
@ -183,23 +178,23 @@ namespace storm {
}
#ifdef STORM_HAVE_CARL
template<typename ValueType>
Dtmc<ValueType>::ConstraintCollector::ConstraintCollector(Dtmc<ValueType> const& dtmc) {
template <typename ValueType, typename RewardModelType>
Dtmc<ValueType, RewardModelType>::ConstraintCollector::ConstraintCollector(Dtmc<ValueType> const& dtmc) {
process(dtmc);
}
template<typename ValueType>
std::unordered_set<storm::ArithConstraint<ValueType>> const& Dtmc<ValueType>::ConstraintCollector::getWellformedConstraints() const {
template <typename ValueType, typename RewardModelType>
std::unordered_set<storm::ArithConstraint<ValueType>> const& Dtmc<ValueType, RewardModelType>::ConstraintCollector::getWellformedConstraints() const {
return this->wellformedConstraintSet;
}
template<typename ValueType>
std::unordered_set<storm::ArithConstraint<ValueType>> const& Dtmc<ValueType>::ConstraintCollector::getGraphPreservingConstraints() const {
template <typename ValueType, typename RewardModelType>
std::unordered_set<storm::ArithConstraint<ValueType>> const& Dtmc<ValueType, RewardModelType>::ConstraintCollector::getGraphPreservingConstraints() const {
return this->graphPreservingConstraintSet;
}
template<typename ValueType>
void Dtmc<ValueType>::ConstraintCollector::process(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
template <typename ValueType, typename RewardModelType>
void Dtmc<ValueType, RewardModelType>::ConstraintCollector::process(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
for(uint_fast64_t state = 0; state < dtmc.getNumberOfStates(); ++state) {
ValueType sum = storm::utility::zero<ValueType>();
for (auto const& transition : dtmc.getRows(state)) {
@ -218,14 +213,14 @@ namespace storm {
}
}
template<typename ValueType>
void Dtmc<ValueType>::ConstraintCollector::operator()(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
template <typename ValueType, typename RewardModelType>
void Dtmc<ValueType, RewardModelType>::ConstraintCollector::operator()(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
process(dtmc);
}
#endif
template <typename ValueType>
bool Dtmc<ValueType>::checkValidityOfProbabilityMatrix() const {
template <typename ValueType, typename RewardModelType>
bool Dtmc<ValueType, RewardModelType>::checkValidityOfProbabilityMatrix() const {
if (this->getTransitionMatrix().getRowCount() != this->getTransitionMatrix().getColumnCount()) {
return false;
}

16
src/models/sparse/Dtmc.h

@ -11,22 +11,20 @@ namespace storm {
/*!
* This class represents a discrete-time Markov chain.
*/
template <class ValueType>
class Dtmc : public DeterministicModel<ValueType> {
template<class ValueType, typename RewardModelType = StandardRewardModel<ValueType>>
class Dtmc : public DeterministicModel<ValueType, RewardModelType> {
public:
/*!
* Constructs a model from the given data.
*
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Dtmc(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -34,13 +32,11 @@ namespace storm {
*
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Dtmc(storm::storage::SparseMatrix<ValueType>&& probabilityMatrix, storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
Dtmc(Dtmc<ValueType> const& dtmc) = default;

68
src/models/sparse/MarkovAutomaton.cpp

@ -6,64 +6,60 @@ namespace storm {
namespace models {
namespace sparse {
template <typename ValueType>
MarkovAutomaton<ValueType>::MarkovAutomaton(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
template <typename ValueType, typename RewardModelType>
MarkovAutomaton<ValueType, RewardModelType>::MarkovAutomaton(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: NondeterministicModel<ValueType>(storm::models::ModelType::MarkovAutomaton, transitionMatrix, stateLabeling, optionalStateRewardVector, optionalTransitionRewardMatrix, optionalChoiceLabeling), markovianStates(markovianStates), exitRates(exitRates), closed(false) {
: NondeterministicModel<ValueType>(storm::models::ModelType::MarkovAutomaton, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling), markovianStates(markovianStates), exitRates(exitRates), closed(false) {
this->turnRatesToProbabilities();
STORM_LOG_THROW(!this->hasTransitionRewards() || this->getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "There are transition rewards for nonexistent transitions.");
}
template <typename ValueType>
MarkovAutomaton<ValueType>::MarkovAutomaton(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
template <typename ValueType, typename RewardModelType>
MarkovAutomaton<ValueType, RewardModelType>::MarkovAutomaton(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: NondeterministicModel<ValueType>(storm::models::ModelType::MarkovAutomaton, std::move(transitionMatrix), std::move(stateLabeling), std::move(optionalStateRewardVector), std::move(optionalTransitionRewardMatrix), std::move(optionalChoiceLabeling)), markovianStates(markovianStates), exitRates(std::move(exitRates)), closed(false) {
: NondeterministicModel<ValueType>(storm::models::ModelType::MarkovAutomaton, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)), markovianStates(markovianStates), exitRates(std::move(exitRates)), closed(false) {
this->turnRatesToProbabilities();
STORM_LOG_THROW(!this->hasTransitionRewards() || this->getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "There are transition rewards for nonexistent transitions.");
}
template <typename ValueType>
bool MarkovAutomaton<ValueType>::isClosed() const {
template <typename ValueType, typename RewardModelType>
bool MarkovAutomaton<ValueType, RewardModelType>::isClosed() const {
return closed;
}
template <typename ValueType>
bool MarkovAutomaton<ValueType>::isHybridState(storm::storage::sparse::state_type state) const {
template <typename ValueType, typename RewardModelType>
bool MarkovAutomaton<ValueType, RewardModelType>::isHybridState(storm::storage::sparse::state_type state) const {
return isMarkovianState(state) && (this->getTransitionMatrix().getRowGroupSize(state) > 1);
}
template <typename ValueType>
bool MarkovAutomaton<ValueType>::isMarkovianState(storm::storage::sparse::state_type state) const {
template <typename ValueType, typename RewardModelType>
bool MarkovAutomaton<ValueType, RewardModelType>::isMarkovianState(storm::storage::sparse::state_type state) const {
return this->markovianStates.get(state);
}
template <typename ValueType>
bool MarkovAutomaton<ValueType>::isProbabilisticState(storm::storage::sparse::state_type state) const {
template <typename ValueType, typename RewardModelType>
bool MarkovAutomaton<ValueType, RewardModelType>::isProbabilisticState(storm::storage::sparse::state_type state) const {
return !this->markovianStates.get(state);
}
template <typename ValueType>
std::vector<ValueType> const& MarkovAutomaton<ValueType>::getExitRates() const {
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> const& MarkovAutomaton<ValueType, RewardModelType>::getExitRates() const {
return this->exitRates;
}
template <typename ValueType>
ValueType const& MarkovAutomaton<ValueType>::getExitRate(storm::storage::sparse::state_type state) const {
template <typename ValueType, typename RewardModelType>
ValueType const& MarkovAutomaton<ValueType, RewardModelType>::getExitRate(storm::storage::sparse::state_type state) const {
return this->exitRates[state];
}
template <typename ValueType>
ValueType MarkovAutomaton<ValueType>::getMaximalExitRate() const {
template <typename ValueType, typename RewardModelType>
ValueType MarkovAutomaton<ValueType, RewardModelType>::getMaximalExitRate() const {
ValueType result = storm::utility::zero<ValueType>();
for (auto markovianState : this->markovianStates) {
result = std::max(result, this->exitRates[markovianState]);
@ -71,13 +67,13 @@ namespace storm {
return result;
}
template <typename ValueType>
storm::storage::BitVector const& MarkovAutomaton<ValueType>::getMarkovianStates() const {
template <typename ValueType, typename RewardModelType>
storm::storage::BitVector const& MarkovAutomaton<ValueType, RewardModelType>::getMarkovianStates() const {
return this->markovianStates;
}
template <typename ValueType>
void MarkovAutomaton<ValueType>::close() {
template <typename ValueType, typename RewardModelType>
void MarkovAutomaton<ValueType, RewardModelType>::close() {
if (!closed) {
// First, count the number of hybrid states to know how many Markovian choices
// will be removed.
@ -124,8 +120,8 @@ namespace storm {
}
}
template <typename ValueType>
void MarkovAutomaton<ValueType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
template <typename ValueType, typename RewardModelType>
void MarkovAutomaton<ValueType, RewardModelType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
NondeterministicModel<ValueType>::writeDotToStream(outStream, includeLabeling, subsystem, firstValue, secondValue, stateColoring, colors, scheduler, false);
// Write the probability distributions for all the states.
@ -205,13 +201,13 @@ namespace storm {
}
}
template <typename ValueType>
std::size_t MarkovAutomaton<ValueType>::getSizeInBytes() const {
template <typename ValueType, typename RewardModelType>
std::size_t MarkovAutomaton<ValueType, RewardModelType>::getSizeInBytes() const {
return NondeterministicModel<ValueType>::getSizeInBytes() + markovianStates.getSizeInBytes() + exitRates.size() * sizeof(ValueType);
}
template <typename ValueType>
void MarkovAutomaton<ValueType>::turnRatesToProbabilities() {
template <typename ValueType, typename RewardModelType>
void MarkovAutomaton<ValueType, RewardModelType>::turnRatesToProbabilities() {
for (auto state : this->markovianStates) {
for (auto& transition : this->getTransitionMatrix().getRowGroup(state)) {
transition.setValue(transition.getValue() / this->exitRates[state]);

14
src/models/sparse/MarkovAutomaton.h

@ -11,7 +11,7 @@ namespace storm {
/*!
* This class represents a Markov automaton.
*/
template <typename ValueType>
template<class ValueType, typename RewardModelType = StandardRewardModel<ValueType>>
class MarkovAutomaton : public NondeterministicModel<ValueType> {
public:
/*!
@ -21,16 +21,14 @@ namespace storm {
* @param stateLabeling The labeling of the states.
* @param markovianStates A bit vector indicating the Markovian states of the automaton.
* @param exitRates A vector storing the exit rates of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
MarkovAutomaton(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -40,16 +38,14 @@ namespace storm {
* @param stateLabeling The labeling of the states.
* @param markovianStates A bit vector indicating the Markovian states of the automaton.
* @param exitRates A vector storing the exit rates of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
MarkovAutomaton(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
storm::storage::BitVector const& markovianStates,
std::vector<ValueType> const& exitRates,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
MarkovAutomaton(MarkovAutomaton const& other) = default;

45
src/models/sparse/Mdp.cpp

@ -6,31 +6,27 @@ namespace storm {
namespace models {
namespace sparse {
template <typename ValueType>
Mdp<ValueType>::Mdp(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
template <typename ValueType, typename RewardModelType>
Mdp<ValueType, RewardModelType>::Mdp(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: NondeterministicModel<ValueType>(storm::models::ModelType::Mdp, transitionMatrix, stateLabeling, optionalStateRewardVector, optionalTransitionRewardMatrix, optionalChoiceLabeling) {
: NondeterministicModel<ValueType>(storm::models::ModelType::Mdp, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
STORM_LOG_THROW(this->checkValidityOfProbabilityMatrix(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
STORM_LOG_THROW(!this->hasTransitionRewards() || this->getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
}
template <typename ValueType>
Mdp<ValueType>::Mdp(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
template <typename ValueType, typename RewardModelType>
Mdp<ValueType, RewardModelType>::Mdp(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: NondeterministicModel<ValueType>(storm::models::ModelType::Mdp, std::move(transitionMatrix), std::move(stateLabeling), std::move(optionalStateRewardVector), std::move(optionalTransitionRewardMatrix), std::move(optionalChoiceLabeling)) {
: NondeterministicModel<ValueType>(storm::models::ModelType::Mdp, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels), std::move(optionalChoiceLabeling)) {
STORM_LOG_THROW(this->checkValidityOfProbabilityMatrix(), storm::exceptions::InvalidArgumentException, "The probability matrix is invalid.");
STORM_LOG_THROW(!this->hasTransitionRewards() || this->getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
}
template <typename ValueType>
Mdp<ValueType> Mdp<ValueType>::restrictChoiceLabels(LabelSet const& enabledChoiceLabels) const {
template <typename ValueType, typename RewardModelType>
Mdp<ValueType> Mdp<ValueType, RewardModelType>::restrictChoiceLabels(LabelSet const& enabledChoiceLabels) const {
STORM_LOG_THROW(this->hasChoiceLabeling(), storm::exceptions::InvalidArgumentException, "Restriction to label set is impossible for unlabeled model.");
std::vector<LabelSet> const& choiceLabeling = this->getChoiceLabeling();
@ -69,26 +65,23 @@ namespace storm {
}
Mdp<ValueType> restrictedMdp(transitionMatrixBuilder.build(), storm::models::sparse::StateLabeling(this->getStateLabeling()),
this->hasStateRewards() ? boost::optional<std::vector<ValueType>>(this->getStateRewardVector()) : boost::optional<std::vector<ValueType>>(),
this->hasTransitionRewards() ? boost::optional<storm::storage::SparseMatrix<ValueType>>(this->getTransitionRewardMatrix()) : boost::optional<storm::storage::SparseMatrix<ValueType>>(),
boost::optional<std::vector<LabelSet>>(newChoiceLabeling));
std::map<std::string, RewardModelType>(this->getRewardModels()), boost::optional<std::vector<LabelSet>>(newChoiceLabeling));
return restrictedMdp;
}
template <typename ValueType>
Mdp<ValueType> Mdp<ValueType>::restrictActions(storm::storage::BitVector const& enabledActions) const {
template <typename ValueType, typename RewardModelType>
Mdp<ValueType> Mdp<ValueType, RewardModelType>::restrictActions(storm::storage::BitVector const& enabledActions) const {
storm::storage::SparseMatrix<ValueType> restrictedTransitions = this->getTransitionMatrix().restrictRows(enabledActions);
if(this->hasTransitionRewards()) {
return Mdp<ValueType>(restrictedTransitions, this->getStateLabeling(), this->getOptionalStateRewardVector(), boost::optional<storm::storage::SparseMatrix<ValueType>>(this->getTransitionRewardMatrix().restrictRows(enabledActions)), this->getOptionalChoiceLabeling());
} else {
return Mdp<ValueType>( restrictedTransitions, this->getStateLabeling(), this->getOptionalStateRewardVector(), boost::optional<storm::storage::SparseMatrix<ValueType>>(), this->getOptionalChoiceLabeling());
std::map<std::string, RewardModelType> newRewardModels;
for (auto const& rewardModel : this->getRewardModels()) {
newRewardModels.emplace(rewardModel.first, rewardModel.second.restrictActions(enabledActions));
}
return Mdp<ValueType>(restrictedTransitions, this->getStateLabeling(), newRewardModels, this->getOptionalChoiceLabeling());
}
template <typename ValueType>
bool Mdp<ValueType>::checkValidityOfProbabilityMatrix() const {
template <typename ValueType, typename RewardModelType>
bool Mdp<ValueType, RewardModelType>::checkValidityOfProbabilityMatrix() const {
storm::utility::ConstantsComparator<ValueType> comparator;
// Get the settings object to customize linear solving.
for (uint_fast64_t row = 0; row < this->getTransitionMatrix().getRowCount(); row++) {

16
src/models/sparse/Mdp.h

@ -11,22 +11,20 @@ namespace storm {
/*!
* This class represents a (discrete-time) Markov decision process.
*/
template <typename ValueType>
class Mdp : public NondeterministicModel<ValueType> {
template<class ValueType, typename RewardModelType = StandardRewardModel<ValueType>>
class Mdp : public NondeterministicModel<ValueType, RewardModelType> {
public:
/*!
* Constructs a model from the given data.
*
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Mdp(storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -34,14 +32,12 @@ namespace storm {
*
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Mdp(storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
Mdp(Mdp const& other) = default;

204
src/models/sparse/Model.cpp

@ -3,165 +3,131 @@
#include "src/utility/vector.h"
#include "src/adapters/CarlAdapter.h"
#include "src/exceptions/IllegalArgumentException.h"
namespace storm {
namespace models {
namespace sparse {
template<typename ValueType>
Model<ValueType>::Model(storm::models::ModelType const& modelType,
template<typename ValueType, typename RewardModelType>
Model<ValueType, RewardModelType>::Model(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: ModelBase(modelType),
transitionMatrix(transitionMatrix),
stateLabeling(stateLabeling),
stateRewardVector(optionalStateRewardVector),
transitionRewardMatrix(optionalTransitionRewardMatrix),
choiceLabeling(optionalChoiceLabeling) {
// Intentionally left empty.
: ModelBase(modelType), transitionMatrix(transitionMatrix), stateLabeling(stateLabeling),
rewardModels(rewardModels), choiceLabeling(optionalChoiceLabeling) {
for (auto const& rewardModel : this->getRewardModels()) {
STORM_LOG_THROW(!rewardModel.second.hasTransitionRewards() || rewardModel.second.getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
}
}
template<typename ValueType>
Model<ValueType>::Model(storm::models::ModelType const& modelType,
template<typename ValueType, typename RewardModelType>
Model<ValueType, RewardModelType>::Model(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: ModelBase(modelType),
transitionMatrix(std::move(transitionMatrix)),
stateLabeling(std::move(stateLabeling)),
stateRewardVector(std::move(optionalStateRewardVector)),
transitionRewardMatrix(std::move(optionalTransitionRewardMatrix)),
choiceLabeling(std::move(optionalChoiceLabeling)) {
// Intentionally left empty.
: ModelBase(modelType), transitionMatrix(std::move(transitionMatrix)), stateLabeling(std::move(stateLabeling)),
rewardModels(std::move(rewardModels)), choiceLabeling(std::move(optionalChoiceLabeling)) {
for (auto const& rewardModel : this->getRewardModels()) {
STORM_LOG_THROW(!rewardModel.second.hasTransitionRewards() || rewardModel.second.getTransitionRewardMatrix().isSubmatrixOf(this->getTransitionMatrix()), storm::exceptions::InvalidArgumentException, "The transition reward matrix is not a submatrix of the transition matrix, i.e. there are rewards for transitions that do not exist.");
}
}
template <typename ValueType>
storm::storage::SparseMatrix<ValueType> Model<ValueType>::getBackwardTransitions() const {
template<typename ValueType, typename RewardModelType>
storm::storage::SparseMatrix<ValueType> Model<ValueType, RewardModelType>::getBackwardTransitions() const {
return this->getTransitionMatrix().transpose(true);
}
template <typename ValueType>
typename storm::storage::SparseMatrix<ValueType>::const_rows Model<ValueType>::getRows(storm::storage::sparse::state_type state) const {
template<typename ValueType, typename RewardModelType>
typename storm::storage::SparseMatrix<ValueType>::const_rows Model<ValueType, RewardModelType>::getRows(storm::storage::sparse::state_type state) const {
return this->getTransitionMatrix().getRowGroup(state);
}
template <typename ValueType>
uint_fast64_t Model<ValueType>::getNumberOfStates() const {
template<typename ValueType, typename RewardModelType>
uint_fast64_t Model<ValueType, RewardModelType>::getNumberOfStates() const {
return this->getTransitionMatrix().getColumnCount();
}
template <typename ValueType>
uint_fast64_t Model<ValueType>::getNumberOfTransitions() const {
template<typename ValueType, typename RewardModelType>
uint_fast64_t Model<ValueType, RewardModelType>::getNumberOfTransitions() const {
return this->getTransitionMatrix().getNonzeroEntryCount();
}
template <typename ValueType>
storm::storage::BitVector const& Model<ValueType>::getInitialStates() const {
template<typename ValueType, typename RewardModelType>
storm::storage::BitVector const& Model<ValueType, RewardModelType>::getInitialStates() const {
return this->getStates("init");
}
template <typename ValueType>
storm::storage::BitVector const& Model<ValueType>::getStates(std::string const& label) const {
template<typename ValueType, typename RewardModelType>
storm::storage::BitVector const& Model<ValueType, RewardModelType>::getStates(std::string const& label) const {
return stateLabeling.getStates(label);
}
template <typename ValueType>
bool Model<ValueType>::hasLabel(std::string const& label) const {
template<typename ValueType, typename RewardModelType>
bool Model<ValueType, RewardModelType>::hasLabel(std::string const& label) const {
return stateLabeling.containsLabel(label);
}
template <typename ValueType>
storm::storage::SparseMatrix<ValueType> const& Model<ValueType>::getTransitionMatrix() const {
template<typename ValueType, typename RewardModelType>
storm::storage::SparseMatrix<ValueType> const& Model<ValueType, RewardModelType>::getTransitionMatrix() const {
return transitionMatrix;
}
template <typename ValueType>
storm::storage::SparseMatrix<ValueType>& Model<ValueType>::getTransitionMatrix() {
template<typename ValueType, typename RewardModelType>
storm::storage::SparseMatrix<ValueType>& Model<ValueType, RewardModelType>::getTransitionMatrix() {
return transitionMatrix;
}
template <typename ValueType>
storm::storage::SparseMatrix<ValueType> const& Model<ValueType>::getTransitionRewardMatrix() const {
return transitionRewardMatrix.get();
}
template <typename ValueType>
storm::storage::SparseMatrix<ValueType>& Model<ValueType>::getTransitionRewardMatrix() {
return transitionRewardMatrix.get();
}
template <typename ValueType>
boost::optional<storm::storage::SparseMatrix<ValueType>> const& Model<ValueType>::getOptionalTransitionRewardMatrix() const {
return transitionRewardMatrix;
}
template <typename ValueType>
std::vector<ValueType> const& Model<ValueType>::getStateRewardVector() const {
return stateRewardVector.get();
template<typename ValueType, typename RewardModelType>
bool Model<ValueType, RewardModelType>::hasRewardModel(std::string const& rewardModelName) const {
return this->rewardModels.find(rewardModelName) != this->rewardModels.end();
}
template <typename ValueType>
boost::optional<std::vector<ValueType>> const& Model<ValueType>::getOptionalStateRewardVector() const {
return stateRewardVector;
template<typename ValueType, typename RewardModelType>
RewardModelType const& Model<ValueType, RewardModelType>::getRewardModel(std::string const& rewardModelName) const {
auto it = this->rewardModels.find(rewardModelName);
STORM_LOG_THROW(it != this->rewardModels.end(), storm::exceptions::IllegalArgumentException, "The requested reward model does not exist.");
return it->second;
}
template <typename ValueType>
std::vector<LabelSet> const& Model<ValueType>::getChoiceLabeling() const {
template<typename ValueType, typename RewardModelType>
std::vector<LabelSet> const& Model<ValueType, RewardModelType>::getChoiceLabeling() const {
return choiceLabeling.get();
}
template <typename ValueType>
boost::optional<std::vector<LabelSet>> const& Model<ValueType>::getOptionalChoiceLabeling() const {
template<typename ValueType, typename RewardModelType>
boost::optional<std::vector<LabelSet>> const& Model<ValueType, RewardModelType>::getOptionalChoiceLabeling() const {
return choiceLabeling;
}
template <typename ValueType>
storm::models::sparse::StateLabeling const& Model<ValueType>::getStateLabeling() const {
template<typename ValueType, typename RewardModelType>
storm::models::sparse::StateLabeling const& Model<ValueType, RewardModelType>::getStateLabeling() const {
return stateLabeling;
}
template <typename ValueType>
storm::models::sparse::StateLabeling& Model<ValueType>::getStateLabeling() {
template<typename ValueType, typename RewardModelType>
storm::models::sparse::StateLabeling& Model<ValueType, RewardModelType>::getStateLabeling() {
return stateLabeling;
}
template <typename ValueType>
bool Model<ValueType>::hasStateRewards() const {
return static_cast<bool>(stateRewardVector);
}
template <typename ValueType>
bool Model<ValueType>::hasTransitionRewards() const {
return static_cast<bool>(transitionRewardMatrix);
}
template <typename ValueType>
bool Model<ValueType>::hasChoiceLabeling() const {
template<typename ValueType, typename RewardModelType>
bool Model<ValueType, RewardModelType>::hasChoiceLabeling() const {
return static_cast<bool>(choiceLabeling);
}
template <typename ValueType>
void Model<ValueType>::convertTransitionRewardsToStateRewards() {
STORM_LOG_THROW(this->hasTransitionRewards(), storm::exceptions::InvalidOperationException, "Cannot reduce non-existant transition rewards to state rewards.");
if (this->hasStateRewards()) {
storm::utility::vector::addVectors(stateRewardVector.get(), transitionMatrix.getPointwiseProductRowSumVector(transitionRewardMatrix.get()), stateRewardVector.get());
} else {
this->stateRewardVector = transitionMatrix.getPointwiseProductRowSumVector(transitionRewardMatrix.get());
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::convertTransitionRewardsToStateActionRewards() {
for (auto& rewardModel : this->rewardModels) {
rewardModel.second.convertTransitionRewardsToStateActionRewards(this->getTransitionMatrix());
}
this->transitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>();
}
template <typename ValueType>
std::size_t Model<ValueType>::getSizeInBytes() const {
template<typename ValueType, typename RewardModelType>
std::size_t Model<ValueType, RewardModelType>::getSizeInBytes() const {
std::size_t result = transitionMatrix.getSizeInBytes() + stateLabeling.getSizeInBytes();
if (stateRewardVector) {
result += getStateRewardVector().size() * sizeof(ValueType);
}
if (hasTransitionRewards()) {
result += getTransitionRewardMatrix().getSizeInBytes();
for (auto const& rewardModel : this->rewardModels) {
result += rewardModel.second.getSizeInBytes();
}
if (hasChoiceLabeling()) {
result += getChoiceLabeling().size() * sizeof(LabelSet);
@ -169,19 +135,41 @@ namespace storm {
return result;
}
template <typename ValueType>
void Model<ValueType>::printModelInformationToStream(std::ostream& out) const {
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::printModelInformationToStream(std::ostream& out) const {
this->printModelInformationHeaderToStream(out);
this->printModelInformationFooterToStream(out);
}
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::printModelInformationHeaderToStream(std::ostream& out) const {
out << "-------------------------------------------------------------- " << std::endl;
out << "Model type: \t" << this->getType() << " (sparse)" << std::endl;
out << "States: \t" << this->getNumberOfStates() << std::endl;
out << "Transitions: \t" << this->getNumberOfTransitions() << std::endl;
}
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::printModelInformationFooterToStream(std::ostream& out) const {
this->printRewardModelsInformationToStream(out);
this->getStateLabeling().printLabelingInformationToStream(out);
out << "Size in memory: \t" << (this->getSizeInBytes())/1024 << " kbytes" << std::endl;
out << "-------------------------------------------------------------- " << std::endl;
}
template <typename ValueType>
void Model<ValueType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::printRewardModelsInformationToStream(std::ostream& out) const {
if (this->rewardModels.size()) {
std::vector<std::string> rewardModelNames;
std::for_each(this->rewardModels.begin(), this->rewardModels.end(), [&rewardModelNames] (typename std::map<std::string, RewardModelType>::const_iterator const& it) { rewardModelNames.push_back(it->first); });
out << "Reward Models: " << boost::join(rewardModelNames, ", ") << std::endl;
} else {
out << "Reward Models: none" << std::endl;
}
}
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
outStream << "digraph model {" << std::endl;
// Write all states to the stream.
@ -244,23 +232,23 @@ namespace storm {
}
}
template <typename ValueType>
std::set<std::string> Model<ValueType>::getLabelsOfState(storm::storage::sparse::state_type state) const {
template<typename ValueType, typename RewardModelType>
std::set<std::string> Model<ValueType, RewardModelType>::getLabelsOfState(storm::storage::sparse::state_type state) const {
return this->stateLabeling.getLabelsOfState(state);
}
template <typename ValueType>
void Model<ValueType>::setTransitionMatrix(storm::storage::SparseMatrix<ValueType> const& transitionMatrix) {
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::setTransitionMatrix(storm::storage::SparseMatrix<ValueType> const& transitionMatrix) {
this->transitionMatrix = transitionMatrix;
}
template <typename ValueType>
void Model<ValueType>::setTransitionMatrix(storm::storage::SparseMatrix<ValueType>&& transitionMatrix) {
template<typename ValueType, typename RewardModelType>
void Model<ValueType, RewardModelType>::setTransitionMatrix(storm::storage::SparseMatrix<ValueType>&& transitionMatrix) {
this->transitionMatrix = std::move(transitionMatrix);
}
template <typename ValueType>
bool Model<ValueType>::isSparseModel() const {
template<typename ValueType, typename RewardModelType>
bool Model<ValueType, RewardModelType>::isSparseModel() const {
return true;
}

117
src/models/sparse/Model.h

@ -6,6 +6,7 @@
#include <boost/optional.hpp>
#include "src/models/ModelBase.h"
#include "src/models/sparse/StandardRewardModel.h"
#include "src/models/sparse/StateLabeling.h"
#include "src/storage/sparse/StateType.h"
#include "src/storage/BitVector.h"
@ -22,9 +23,12 @@ namespace storm {
/*!
* Base class for all sparse models.
*/
template<class ValueType>
template<class CValueType, class CRewardModelType = StandardRewardModel<CValueType>>
class Model : public storm::models::ModelBase {
public:
typedef CValueType ValueType;
typedef CRewardModelType RewardModelType;
Model(Model<ValueType> const& other) = default;
Model& operator=(Model<ValueType> const& other) = default;
@ -39,15 +43,13 @@ namespace storm {
* @param modelType The type of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Model(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -56,15 +58,13 @@ namespace storm {
* @param modelType The type of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
Model(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -133,45 +133,21 @@ namespace storm {
* @return A matrix representing the transitions of the model.
*/
storm::storage::SparseMatrix<ValueType>& getTransitionMatrix();
/*!
* Retrieves the matrix representing the transition rewards of the model. Note that calling this method
* is only valid if the model has transition rewards.
*
* @return The matrix representing the transition rewards of the model.
*/
storm::storage::SparseMatrix<ValueType> const& getTransitionRewardMatrix() const;
/*!
* Retrieves an optional value that contains the transition reward matrix if there is one.
*
* @return The transition reward matrix if there is one.
*/
boost::optional<storm::storage::SparseMatrix<ValueType>> const& getOptionalTransitionRewardMatrix() const;
/*!
* Retrieves the matrix representing the transition rewards of the model. Note that calling this method
* is only valid if the model has transition rewards.
*
* @return The matrix representing the transition rewards of the model.
*/
storm::storage::SparseMatrix<ValueType>& getTransitionRewardMatrix();
/*!
* Retrieves a vector representing the state rewards of the model. Note that calling this method is only
* valid if the model has state rewards.
* Retrieves whether the model has a reward model with the given name.
*
* @return A vector representing the state rewards of the model.
* @return True iff the model has a reward model with the given name.
*/
std::vector<ValueType> const& getStateRewardVector() const;
bool hasRewardModel(std::string const& rewardModelName) const;
/*!
* Retrieves an optional value that contains the state reward vector if there is one.
* Retrieves the reward model with the given name, if one exists. Otherwise, an exception is thrown.
*
* @return The state reward vector if there is one.
* @return The reward model with the given name, if it exists.
*/
boost::optional<std::vector<ValueType>> const& getOptionalStateRewardVector() const;
RewardModelType const& getRewardModel(std::string const& rewardModelName) const;
/*!
* Retrieves the labels for the choices of the model. Note that calling this method is only valid if the
* model has a choice labeling.
@ -201,21 +177,6 @@ namespace storm {
*/
storm::models::sparse::StateLabeling& getStateLabeling();
/*!
* Retrieves whether this model has state rewards.
*
* @return True iff this model has state rewards.
*/
bool hasStateRewards() const;
/*!
* Retrieves whether this model has transition rewards.
*
* @return True iff this model has transition rewards.
*/
bool hasTransitionRewards() const;
/*!
* Retrieves whether this model has a labeling of the choices.
*
@ -224,11 +185,11 @@ namespace storm {
bool hasChoiceLabeling() const;
/*!
* Converts the transition rewards to state rewards. Note that calling this method is only valid if the
* model has transition rewards. Also note that this does not preserve all properties, but it preserves
* expected rewards.
* Converts the transition rewards of all reward models to state rewards. Note that calling this method
* is only valid if the model has transition rewards. Also note that this does not preserve all
* properties, but it preserves expected rewards.
*/
void convertTransitionRewardsToStateRewards();
void convertTransitionRewardsToStateActionRewards();
/*!
* Retrieves (an approximation of) the size of the model in bytes.
@ -283,6 +244,35 @@ namespace storm {
* @param transitionMatrix The new transition matrix of the model.
*/
void setTransitionMatrix(storm::storage::SparseMatrix<ValueType>&& transitionMatrix);
/*!
* Prints the information header (number of states and transitions) of the model to the specified stream.
*
* @param out The stream the information is to be printed to.
*/
void printModelInformationHeaderToStream(std::ostream& out) const;
/*!
* Prints the information footer (reward models, labels and size in memory) of the model to the
* specified stream.
*
* @param out The stream the information is to be printed to.
*/
void printModelInformationFooterToStream(std::ostream& out) const;
/*!
* Prints information about the reward models to the specified stream.
*
* @param out The stream the information is to be printed to.
*/
void printRewardModelsInformationToStream(std::ostream& out) const;
/*!
* Retrieves the reward models.
*
* @return A mapping from reward model names to the reward models.
*/
std::map<std::string, RewardModelType> const& getRewardModels() const;
private:
// A matrix representing transition relation.
@ -291,11 +281,8 @@ namespace storm {
// The labeling of the states.
storm::models::sparse::StateLabeling stateLabeling;
// If set, a vector representing the rewards of the states.
boost::optional<std::vector<ValueType>> stateRewardVector;
// If set, a matrix representing the rewards of transitions.
boost::optional<storm::storage::SparseMatrix<ValueType>> transitionRewardMatrix;
// The reward models of the model.
std::map<std::string, RewardModelType> rewardModels;
// If set, a vector representing the labels of choices.
boost::optional<std::vector<LabelSet>> choiceLabeling;

47
src/models/sparse/NondeterministicModel.cpp

@ -6,59 +6,52 @@ namespace storm {
namespace models {
namespace sparse {
template<typename ValueType>
NondeterministicModel<ValueType>::NondeterministicModel(storm::models::ModelType const& modelType,
template<typename ValueType, typename RewardModelType>
NondeterministicModel<ValueType, RewardModelType>::NondeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType> const& rewardModels,
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling)
: Model<ValueType>(modelType, transitionMatrix, stateLabeling, optionalStateRewardVector, optionalTransitionRewardMatrix, optionalChoiceLabeling) {
: Model<ValueType>(modelType, transitionMatrix, stateLabeling, rewardModels, optionalChoiceLabeling) {
// Intentionally left empty.
}
template<typename ValueType>
NondeterministicModel<ValueType>::NondeterministicModel(storm::models::ModelType const& modelType,
template<typename ValueType, typename RewardModelType>
NondeterministicModel<ValueType, RewardModelType>::NondeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix,
std::map<std::string, RewardModelType>&& rewardModels,
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling)
: Model<ValueType>(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(optionalStateRewardVector), std::move(optionalTransitionRewardMatrix),
: Model<ValueType>(modelType, std::move(transitionMatrix), std::move(stateLabeling), std::move(rewardModels),
std::move(optionalChoiceLabeling)) {
// Intentionally left empty.
}
template<typename ValueType>
uint_fast64_t NondeterministicModel<ValueType>::getNumberOfChoices() const {
template<typename ValueType, typename RewardModelType>
uint_fast64_t NondeterministicModel<ValueType, RewardModelType>::getNumberOfChoices() const {
return this->getTransitionMatrix().getRowCount();
}
template<typename ValueType>
std::vector<uint_fast64_t> const& NondeterministicModel<ValueType>::getNondeterministicChoiceIndices() const {
template<typename ValueType, typename RewardModelType>
std::vector<uint_fast64_t> const& NondeterministicModel<ValueType, RewardModelType>::getNondeterministicChoiceIndices() const {
return this->getTransitionMatrix().getRowGroupIndices();
}
template<typename ValueType>
uint_fast64_t NondeterministicModel<ValueType>::getNumberOfChoices(uint_fast64_t state) const {
template<typename ValueType, typename RewardModelType>
uint_fast64_t NondeterministicModel<ValueType, RewardModelType>::getNumberOfChoices(uint_fast64_t state) const {
auto indices = this->getNondeterministicChoiceIndices();
return indices[state+1] - indices[state];
}
template<typename ValueType>
void NondeterministicModel<ValueType>::printModelInformationToStream(std::ostream& out) const {
out << "-------------------------------------------------------------- " << std::endl;
out << "Model type: \t\t" << this->getType() << " (sparse)" << std::endl;
out << "States: \t\t" << this->getNumberOfStates() << std::endl;
out << "Transitions: \t\t" << this->getNumberOfTransitions() << std::endl;
template<typename ValueType, typename RewardModelType>
void NondeterministicModel<ValueType, RewardModelType>::printModelInformationToStream(std::ostream& out) const {
this->printModelInformationHeaderToStream(out);
out << "Choices: \t\t" << this->getNumberOfChoices() << std::endl;
this->getStateLabeling().printLabelingInformationToStream(out);
out << "Size in memory: \t" << (this->getSizeInBytes())/1024 << " kbytes" << std::endl;
out << "-------------------------------------------------------------- " << std::endl;
this->printModelInformationFooterToStream(out);
}
template<typename ValueType>
void NondeterministicModel<ValueType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
template<typename ValueType, typename RewardModelType>
void NondeterministicModel<ValueType, RewardModelType>::writeDotToStream(std::ostream& outStream, bool includeLabeling, storm::storage::BitVector const* subsystem, std::vector<ValueType> const* firstValue, std::vector<ValueType> const* secondValue, std::vector<uint_fast64_t> const* stateColoring, std::vector<std::string> const* colors, std::vector<uint_fast64_t>* scheduler, bool finalizeOutput) const {
Model<ValueType>::writeDotToStream(outStream, includeLabeling, subsystem, firstValue, secondValue, stateColoring, colors, scheduler, false);
// Write the probability distributions for all the states.

16
src/models/sparse/NondeterministicModel.h

@ -11,8 +11,8 @@ namespace storm {
/*!
* The base class of sparse nondeterministic models.
*/
template<class ValueType>
class NondeterministicModel: public Model<ValueType> {
template<class ValueType, typename RewardModelType = StandardRewardModel<ValueType>>
class NondeterministicModel: public Model<ValueType, RewardModelType> {
public:
/*!
* Constructs a model from the given data.
@ -20,15 +20,13 @@ namespace storm {
* @param modelType The type of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
NondeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType> const& transitionMatrix,
storm::models::sparse::StateLabeling const& stateLabeling,
boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType> const& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>> const& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
/*!
@ -37,15 +35,13 @@ namespace storm {
* @param modelType The type of the model.
* @param transitionMatrix The matrix representing the transitions in the model.
* @param stateLabeling The labeling of the states.
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
* @param rewardModels A mapping of reward model names to reward models.
* @param optionalChoiceLabeling A vector that represents the labels associated with the choices of each state.
*/
NondeterministicModel(storm::models::ModelType const& modelType,
storm::storage::SparseMatrix<ValueType>&& transitionMatrix,
storm::models::sparse::StateLabeling&& stateLabeling,
boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>(),
std::map<std::string, RewardModelType>&& rewardModels = std::map<std::string, RewardModelType>(),
boost::optional<std::vector<LabelSet>>&& optionalChoiceLabeling = boost::optional<std::vector<LabelSet>>());
NondeterministicModel(NondeterministicModel const& other) = default;

122
src/models/sparse/StandardRewardModel.cpp

@ -0,0 +1,122 @@
#include "src/models/sparse/StandardRewardModel.h"
#include "src/utility/vector.h"
#include "src/exceptions/InvalidOperationException.h"
namespace storm {
namespace models {
namespace sparse {
template<typename ValueType>
StandardRewardModel<ValueType>::StandardRewardModel(boost::optional<std::vector<ValueType>> const& optionalStateRewardVector,
boost::optional<std::vector<ValueType>> const& optionalStateActionRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix)
: optionalStateRewardVector(optionalStateRewardVector), optionalStateActionRewardVector(optionalStateActionRewardVector), optionalTransitionRewardMatrix(optionalTransitionRewardMatrix) {
// Intentionally left empty.
}
template<typename ValueType>
StandardRewardModel<ValueType>::StandardRewardModel(boost::optional<std::vector<ValueType>>&& optionalStateRewardVector,
boost::optional<std::vector<ValueType>>&& optionalStateActionRewardVector,
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix)
: optionalStateRewardVector(std::move(optionalStateRewardVector)), optionalStateActionRewardVector(std::move(optionalStateActionRewardVector)), optionalTransitionRewardMatrix(std::move(optionalTransitionRewardMatrix)) {
// Intentionally left empty.
}
template<typename ValueType>
bool StandardRewardModel<ValueType>::hasStateRewards() const {
return static_cast<bool>(this->optionalStateRewardVector);
}
template<typename ValueType>
std::vector<ValueType> const& StandardRewardModel<ValueType>::getStateRewardVector() const {
return this->optionalStateRewardVector.get();
}
template<typename ValueType>
boost::optional<std::vector<ValueType>> const& StandardRewardModel<ValueType>::getOptionalStateRewardVector() const {
return this->optionalStateRewardVector;
}
template<typename ValueType>
bool StandardRewardModel<ValueType>::hasStateActionRewards() const {
return static_cast<bool>(this->optionalStateActionRewardVector);
}
template<typename ValueType>
std::vector<ValueType> const& StandardRewardModel<ValueType>::getStateActionRewardVector() const {
return this->optionalStateActionRewardVector.get();
}
template<typename ValueType>
boost::optional<std::vector<ValueType>> const& StandardRewardModel<ValueType>::getOptionalStateActionRewardVector() const {
return this->optionalStateActionRewardVector;
}
template<typename ValueType>
bool StandardRewardModel<ValueType>::hasTransitionRewards() const {
return static_cast<bool>(this->optionalTransitionRewardMatrix);
}
template<typename ValueType>
storm::storage::SparseMatrix<ValueType> const& StandardRewardModel<ValueType>::getTransitionRewardMatrix() const {
return this->optionalTransitionRewardMatrix.get();
}
template<typename ValueType>
boost::optional<storm::storage::SparseMatrix<ValueType>> const& StandardRewardModel<ValueType>::getOptionalTransitionRewardMatrix() const {
return this->optionalTransitionRewardMatrix;
}
template<typename ValueType>
StandardRewardModel<ValueType> StandardRewardModel<ValueType>::restrictActions(storm::storage::BitVector const& enabledActions) const {
boost::optional<std::vector<ValueType>> newStateRewardVector(this->getOptionalStateRewardVector());
boost::optional<std::vector<ValueType>> newStateActionRewardVector;
if (this->hasStateActionRewards()) {
newStateActionRewardVector = std::vector<ValueType>(enabledActions.getNumberOfSetBits());
storm::utility::vector::selectVectorValues(newStateActionRewardVector.get(), enabledActions, this->getStateActionRewardVector());
}
boost::optional<storm::storage::SparseMatrix<ValueType>> newTransitionRewardMatrix;
if (this->hasTransitionRewards()) {
newTransitionRewardMatrix = this->getTransitionRewardMatrix().restrictRows(enabledActions);
}
return StandardRewardModel(std::move(newStateRewardVector), std::move(newStateActionRewardVector), std::move(newTransitionRewardMatrix));
}
template<typename ValueType>
template<typename MatrixValueType>
void StandardRewardModel<ValueType>::convertTransitionRewardsToStateActionRewards(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) {
STORM_LOG_THROW(this->hasTransitionRewards(), storm::exceptions::InvalidOperationException, "Cannot reduce non-existant transition rewards to state rewards.");
if (this->hasStateActionRewards()) {
storm::utility::vector::addVectors(this->getStateActionRewardVector(), transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()), this->getStateActionRewardVector);
} else {
this->optionalStateActionRewardVector = transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix());
}
this->optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>();
}
template<typename ValueType>
bool StandardRewardModel<ValueType>::empty() const {
return !(static_cast<bool>(this->optionalStateRewardVector) || static_cast<bool>(this->optionalStateActionRewardVector) || static_cast<bool>(this->optionalTransitionRewardMatrix));
}
template<typename ValueType>
std::size_t StandardRewardModel<ValueType>::getSizeInBytes() const {
std::size_t result = 0;
if (this->hasStateRewards()) {
result += this->getStateRewardVector().size() * sizeof(ValueType);
}
if (this->hasStateActionRewards()) {
result += this->getStateActionRewardVector().size() * sizeof(ValueType);
}
if (this->hasTransitionRewards()) {
result += this->getTransitionRewardMatrix().getSizeInBytes();
}
return result;
}
// Explicitly instantiate the class.
template class StandardRewardModel<double>;
}
}
}

159
src/models/sparse/StandardRewardModel.h

@ -0,0 +1,159 @@
#ifndef STORM_MODELS_SPARSE_STANDARDREWARDMODEL_H_
#define STORM_MODELS_SPARSE_STANDARDREWARDMODEL_H_
#include <vector>
#include <boost/optional.hpp>
#include "src/storage/SparseMatrix.h"
#include "src/utility/OsDetection.h"
namespace storm {
namespace models {
namespace sparse {
template <typename ValueType>
class StandardRewardModel {
public:
/*!
* Constructs a reward model by copying the given data.
*
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalStateActionRewardVector The reward values associated with state-action pairs.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
*/
StandardRewardModel(boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<std::vector<ValueType>> const& optionalStateActionRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>> const& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>());
/*!
* Constructs a reward model by moving the given data.
*
* @param optionalStateRewardVector The reward values associated with the states.
* @param optionalStateActionRewardVector The reward values associated with state-action pairs.
* @param optionalTransitionRewardMatrix The reward values associated with the transitions of the model.
*/
StandardRewardModel(boost::optional<std::vector<ValueType>>&& optionalStateRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<std::vector<ValueType>>&& optionalStateActionRewardVector = boost::optional<std::vector<ValueType>>(),
boost::optional<storm::storage::SparseMatrix<ValueType>>&& optionalTransitionRewardMatrix = boost::optional<storm::storage::SparseMatrix<ValueType>>());
StandardRewardModel(StandardRewardModel<ValueType> const& dtmc) = default;
StandardRewardModel& operator=(StandardRewardModel<ValueType> const& dtmc) = default;
#ifndef WINDOWS
StandardRewardModel(StandardRewardModel<ValueType>&& dtmc) = default;
StandardRewardModel& operator=(StandardRewardModel<ValueType>&& dtmc) = default;
#endif
/*!
* Retrieves whether the reward model has state rewards.
*
* @return True iff the reward model has state rewards.
*/
bool hasStateRewards() const;
/*!
* Retrieves the state rewards of the reward model. Note that it is illegal to call this function if the
* reward model does not have state rewards.
*
* @return The state reward vector.
*/
std::vector<ValueType> const& getStateRewardVector() const;
/*!
* Retrieves an optional value that contains the state reward vector if there is one.
*
* @return The state reward vector if there is one.
*/
boost::optional<std::vector<ValueType>> const& getOptionalStateRewardVector() const;
/*!
* Retrieves whether the reward model has state-action rewards.
*
* @return True iff the reward model has state-action rewards.
*/
bool hasStateActionRewards() const;
/*!
* Retrieves the state-action rewards of the reward model. Note that it is illegal to call this function
* if the reward model does not have state-action rewards.
*
* @return The state-action reward vector.
*/
std::vector<ValueType> const& getStateActionRewardVector() const;
/*!
* Retrieves an optional value that contains the state-action reward vector if there is one.
*
* @return The state-action reward vector if there is one.
*/
boost::optional<std::vector<ValueType>> const& getOptionalStateActionRewardVector() const;
/*!
* Retrieves whether the reward model has transition rewards.
*
* @return True iff the reward model has transition rewards.
*/
bool hasTransitionRewards() const;
/*!
* Retrieves the transition rewards of the reward model. Note that it is illegal to call this function
* if the reward model does not have transition rewards.
*
* @return The transition reward matrix.
*/
storm::storage::SparseMatrix<ValueType> const& getTransitionRewardMatrix() const;
/*!
* Retrieves an optional value that contains the transition reward matrix if there is one.
*
* @return The transition reward matrix if there is one.
*/
boost::optional<storm::storage::SparseMatrix<ValueType>> const& getOptionalTransitionRewardMatrix() const;
/*!
* Creates a new reward model by restricting the actions of the action-based rewards.
*
* @param enabledActions A bit vector representing the enabled actions.
* @return The restricted reward model.
*/
StandardRewardModel<ValueType> restrictActions(storm::storage::BitVector const& enabledActions) const;
/*!
* Converts the transition-based rewards to state-action rewards by taking the average of each row. Note
* that this preserves expected rewards, but not all reward-based properties. Also note that it is only
* legal to do this transformation if the reward model has transition rewards.
*
* @param transitionMatrix The transition matrix that is used to weight the rewards in the reward matrix.
*/
template<typename MatrixValueType>
void convertTransitionRewardsToStateActionRewards(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix);
/*!
* Retrieves whether the reward model is empty, i.e. contains no state-, state-action- or transition-based
* rewards.
*
* @return True iff the reward model is empty.
*/
bool empty() const;
/*!
* Retrieves (an approximation of) the size of the model in bytes.
*
* @return The size of the internal representation of the model measured in bytes.
*/
std::size_t getSizeInBytes() const;
private:
// An (optional) vector representing the state rewards.
boost::optional<std::vector<ValueType>> optionalStateRewardVector;
// An (optional) vector representing the state-action rewards.
boost::optional<std::vector<ValueType>> optionalStateActionRewardVector;
// An (optional) matrix representing the transition rewards.
boost::optional<storm::storage::SparseMatrix<ValueType>> optionalTransitionRewardMatrix;
};
}
}
}
#endif /* STORM_MODELS_SPARSE_STANDARDREWARDMODEL_H_ */

9
src/parser/FormulaParser.cpp

@ -77,7 +77,10 @@ namespace storm {
steadyStateOperator = (qi::lit("LRA") > operatorInformation > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createLongRunAverageOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
steadyStateOperator.name("long-run average operator");
rewardOperator = (qi::lit("R") > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
rewardModelName = qi::lit("{\"") > label > qi::lit("\"}");
rewardModelName.name("reward model name");
rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
rewardOperator.name("reward operator");
expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
@ -253,8 +256,8 @@ namespace storm {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::LongRunAverageOperatorFormula(std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createRewardOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::RewardOperatorFormula(std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
std::shared_ptr<storm::logic::Formula> FormulaParser::createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::RewardOperatorFormula(rewardModelName, std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createExpectedTimeOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {

3
src/parser/FormulaParser.h

@ -134,6 +134,7 @@ namespace storm {
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> atomicStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> operatorFormula;
qi::rule<Iterator, std::string(), Skipper> label;
qi::rule<Iterator, std::string(), Skipper> rewardModelName;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> andStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> orStateFormula;
@ -170,7 +171,7 @@ namespace storm {
std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const;
std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createExpectedTimeOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createProbabilityOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula);
std::shared_ptr<storm::logic::Formula> createBinaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::BinaryBooleanStateFormula::OperatorType operatorType);

48
src/storage/StronglyConnectedComponentDecomposition.cpp

@ -4,56 +4,56 @@
namespace storm {
namespace storage {
template<typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition() : Decomposition() {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition() : Decomposition() {
// Intentionally left empty.
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType> const& model, bool dropNaiveSccs, bool onlyBottomSccs) : Decomposition() {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, bool dropNaiveSccs, bool onlyBottomSccs) : Decomposition() {
performSccDecomposition(model, dropNaiveSccs, onlyBottomSccs);
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs) {
storm::storage::BitVector subsystem(model.getNumberOfStates(), block.begin(), block.end());
performSccDecomposition(model.getTransitionMatrix(), subsystem, dropNaiveSccs, onlyBottomSccs);
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) {
performSccDecomposition(model.getTransitionMatrix(), subsystem, dropNaiveSccs, onlyBottomSccs);
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) {
performSccDecomposition(transitionMatrix, subsystem, dropNaiveSccs, onlyBottomSccs);
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(StronglyConnectedComponentDecomposition const& other) : Decomposition(other) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition(StronglyConnectedComponentDecomposition const& other) : Decomposition(other) {
// Intentionally left empty.
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>& StronglyConnectedComponentDecomposition<ValueType>::operator=(StronglyConnectedComponentDecomposition const& other) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>& StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::operator=(StronglyConnectedComponentDecomposition const& other) {
this->blocks = other.blocks;
return *this;
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(StronglyConnectedComponentDecomposition&& other) : Decomposition(std::move(other)) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::StronglyConnectedComponentDecomposition(StronglyConnectedComponentDecomposition&& other) : Decomposition(std::move(other)) {
// Intentionally left empty.
}
template <typename ValueType>
StronglyConnectedComponentDecomposition<ValueType>& StronglyConnectedComponentDecomposition<ValueType>::operator=(StronglyConnectedComponentDecomposition&& other) {
template <typename ValueType, typename RewardModelType>
StronglyConnectedComponentDecomposition<ValueType, RewardModelType>& StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::operator=(StronglyConnectedComponentDecomposition&& other) {
this->blocks = std::move(other.blocks);
return *this;
}
template <typename ValueType>
void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) {
template <typename ValueType, typename RewardModelType>
void StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) {
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
// Set up the environment of the algorithm.
@ -141,8 +141,8 @@ namespace storm {
}
}
template <typename ValueType>
void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::models::sparse::Model<ValueType> const& model, bool dropNaiveSccs, bool onlyBottomSccs) {
template <typename ValueType, typename RewardModelType>
void StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::performSccDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, bool dropNaiveSccs, bool onlyBottomSccs) {
// Prepare a block that contains all states for a call to the other overload of this function.
storm::storage::BitVector fullSystem(model.getNumberOfStates(), true);
@ -150,8 +150,8 @@ namespace storm {
performSccDecomposition(model.getTransitionMatrix(), fullSystem, dropNaiveSccs, onlyBottomSccs);
}
template <typename ValueType>
void StronglyConnectedComponentDecomposition<ValueType>::performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount) {
template <typename ValueType, typename RewardModelType>
void StronglyConnectedComponentDecomposition<ValueType, RewardModelType>::performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount) {
// Prepare the stack used for turning the recursive procedure into an iterative one.
std::vector<uint_fast64_t> recursionStateStack;

12
src/storage/StronglyConnectedComponentDecomposition.h

@ -10,7 +10,7 @@ namespace storm {
namespace models {
namespace sparse {
// Forward declare the model class.
template <typename ValueType> class Model;
template <typename ValueType, typename RewardModelType> class Model;
}
}
@ -19,7 +19,7 @@ namespace storm {
/*!
* This class represents the decomposition of a graph-like structure into its strongly connected components.
*/
template <typename ValueType>
template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
class StronglyConnectedComponentDecomposition : public Decomposition<StronglyConnectedComponent> {
public:
/*
@ -36,7 +36,7 @@ namespace storm {
* @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of
* leaving the SCC), are kept.
*/
StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType> const& model, bool dropNaiveSccs = false, bool onlyBottomSccs = false);
StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, bool dropNaiveSccs = false, bool onlyBottomSccs = false);
/*
* Creates an SCC decomposition of the given block in the given model.
@ -48,7 +48,7 @@ namespace storm {
* @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of
* leaving the SCC), are kept.
*/
StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType> const& model, StateBlock const& block, bool dropNaiveSccs = false, bool onlyBottomSccs = false);
StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, StateBlock const& block, bool dropNaiveSccs = false, bool onlyBottomSccs = false);
/*
* Creates an SCC decomposition of the given subsystem in the given model.
@ -60,7 +60,7 @@ namespace storm {
* @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of
* leaving the SCC), are kept.
*/
StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs = false, bool onlyBottomSccs = false);
StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs = false, bool onlyBottomSccs = false);
/*
* Creates an SCC decomposition of the given subsystem in the given system (whose transition relation is
@ -114,7 +114,7 @@ namespace storm {
* @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of
* leaving the SCC), are kept.
*/
void performSccDecomposition(storm::models::sparse::Model<ValueType> const& model, bool dropNaiveSccs, bool onlyBottomSccs);
void performSccDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, bool dropNaiveSccs, bool onlyBottomSccs);
/*
* Performs the SCC decomposition of the given block in the given model. As a side-effect this fills

12
src/storage/prism/Update.cpp

@ -1,6 +1,7 @@
#include "Update.h"
#include <algorithm>
#include <boost/algorithm/string/join.hpp>
#include "src/utility/macros.h"
#include "src/exceptions/OutOfRangeException.h"
@ -54,13 +55,10 @@ namespace storm {
std::ostream& operator<<(std::ostream& stream, Update const& update) {
stream << update.getLikelihoodExpression() << " : ";
uint_fast64_t i = 0;
for (auto const& assignment : update.getAssignments()) {
stream << assignment;
if (i < update.getAssignments().size() - 1) {
stream << " & ";
}
++i;
if (update.getAssignments().empty()) {
stream << " true ";
} else {
stream << boost::algorithm::join(update.getAssignments(), " & ");
}
return stream;
}

18
src/utility/vector.h

@ -131,7 +131,23 @@ namespace storm {
/*!
* Applies the given operation pointwise on the two given vectors and writes the result to the third vector.
* To botain an in-place operation, the third vector may be equal to any of the other two vectors.
* It does so by selecting the elements of the first operand given by the bit vector and uses this element
* for the next
* To obtain an in-place operation, the third vector may be equal to any of the other two vectors.
*
* @param firstOperand The first operand.
* @param positions The
* @param secondOperand The second operand.
* @param target The target vector.
*/
template<class T>
void applyPointwiseRepeatedly(std::vector<T> const& firstOperand, storm::storage::BitVector const& positions, std::vector<uint_fast64_t> const& rowGrouping, std::vector<T> const& secondOperand, std::vector<T>& target, std::function<T (T const&, T const&)> function) {
}
/*!
* Applies the given operation pointwise on the two given vectors and writes the result to the third vector.
* To obtain an in-place operation, the third vector may be equal to any of the other two vectors.
*
* @param firstOperand The first operand.
* @param secondOperand The second operand.

Loading…
Cancel
Save