You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
6.6 KiB

  1. #include "storm/modelchecker/helper/finitehorizon/SparseNondeterministicStepBoundedHorizonHelper.h"
  2. #include "storm/modelchecker/hints/ExplicitModelCheckerHint.h"
  3. #include "storm/modelchecker/prctl/helper/SparseMdpEndComponentInformation.h"
  4. #include "storm/models/sparse/StandardRewardModel.h"
  5. #include "storm/utility/macros.h"
  6. #include "storm/utility/vector.h"
  7. #include "storm/utility/graph.h"
  8. #include "storm/storage/expressions/Expression.h"
  9. #include "storm/solver/Multiplier.h"
  10. #include "storm/utility/SignalHandler.h"
  11. #include "storm/environment/solver/MinMaxSolverEnvironment.h"
  12. namespace storm {
  13. namespace modelchecker {
  14. namespace helper {
  15. template<typename ValueType>
  16. SparseNondeterministicStepBoundedHorizonHelper<ValueType>::SparseNondeterministicStepBoundedHorizonHelper(/*storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions*/)
  17. //transitionMatrix(transitionMatrix), backwardTransitions(backwardTransitions)
  18. {
  19. // Intentionally left empty.
  20. }
  21. template<typename ValueType>
  22. std::vector<ValueType> SparseNondeterministicStepBoundedHorizonHelper<ValueType>::compute(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint64_t lowerBound, uint64_t upperBound, ModelCheckerHint const& hint, storm::storage::BitVector& resultMaybeStates, std::vector<ValueType>& choiceValues)
  23. {
  24. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
  25. storm::storage::BitVector makeZeroColumns;
  26. // Determine the states that have 0 probability of reaching the target states.
  27. storm::storage::BitVector maybeStates;
  28. if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
  29. maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
  30. } else {
  31. if (goal.minimize()) {
  32. maybeStates = storm::utility::graph::performProbGreater0A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, phiStates, psiStates, true, upperBound);
  33. } else {
  34. maybeStates = storm::utility::graph::performProbGreater0E(backwardTransitions, phiStates, psiStates, true, upperBound);
  35. }
  36. if (lowerBound == 0) {
  37. maybeStates &= ~psiStates;
  38. } else {
  39. makeZeroColumns = psiStates;
  40. }
  41. }
  42. STORM_LOG_INFO("Preprocessing: " << maybeStates.getNumberOfSetBits() << " non-target states with probability greater 0.");
  43. if (!maybeStates.empty()) {
  44. // We can eliminate the rows and columns from the original transition probability matrix that have probability 0.
  45. storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, false, makeZeroColumns);
  46. std::vector<ValueType> b = transitionMatrix.getConstrainedRowGroupSumVector(maybeStates, psiStates);
  47. // Create the vector with which to multiply.
  48. std::vector<ValueType> subresult(maybeStates.getNumberOfSetBits());
  49. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix);
  50. if (lowerBound == 0) {
  51. if(goal.isShieldingTask())
  52. {
  53. multiplier->repeatedMultiplyAndReduceWithChoices(env, goal.direction(), subresult, &b, upperBound, nullptr, choiceValues, transitionMatrix.getRowGroupIndices());
  54. } else {
  55. multiplier->repeatedMultiplyAndReduce(env, goal.direction(), subresult, &b, upperBound);
  56. }
  57. } else {
  58. if(goal.isShieldingTask())
  59. {
  60. multiplier->repeatedMultiplyAndReduceWithChoices(env, goal.direction(), subresult, &b, upperBound - lowerBound + 1, nullptr, choiceValues, transitionMatrix.getRowGroupIndices());
  61. storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, false);
  62. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix);
  63. b = std::vector<ValueType>(b.size(), storm::utility::zero<ValueType>());
  64. multiplier->repeatedMultiplyAndReduceWithChoices(env, goal.direction(), subresult, &b, lowerBound - 1, nullptr, choiceValues, transitionMatrix.getRowGroupIndices());
  65. } else {
  66. multiplier->repeatedMultiplyAndReduce(env, goal.direction(), subresult, &b, upperBound - lowerBound + 1);
  67. storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, false);
  68. auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix);
  69. b = std::vector<ValueType>(b.size(), storm::utility::zero<ValueType>());
  70. multiplier->repeatedMultiplyAndReduce(env, goal.direction(), subresult, &b, lowerBound - 1);
  71. }
  72. }
  73. // Set the values of the resulting vector accordingly.
  74. storm::utility::vector::setVectorValues(result, maybeStates, subresult);
  75. }
  76. if (lowerBound == 0) {
  77. storm::utility::vector::setVectorValues(result, psiStates, storm::utility::one<ValueType>());
  78. }
  79. //TODO: check if this works with nullptr as default for resultMaybeStates
  80. if(!resultMaybeStates.empty())
  81. {
  82. resultMaybeStates = maybeStates;
  83. }
  84. return result;
  85. }
  86. template class SparseNondeterministicStepBoundedHorizonHelper<double>;
  87. template class SparseNondeterministicStepBoundedHorizonHelper<storm::RationalNumber>;
  88. }
  89. }
  90. }