16namespace modelchecker {
17namespace multiobjective {
18namespace preprocessing {
20template<
typename SparseModelType>
24 auto backwardTransitions = preprocessorResult.
preprocessedModel->getBackwardTransitions();
26 setReward0States(result, preprocessorResult, backwardTransitions);
27 checkRewardFiniteness(result, preprocessorResult, backwardTransitions);
32template<
typename SparseModelType>
36 uint_fast64_t stateCount = preprocessorResult.
preprocessedModel->getNumberOfStates();
37 auto const& transitions = preprocessorResult.
preprocessedModel->getTransitionMatrix();
38 std::vector<uint_fast64_t>
const& groupIndices = transitions.getRowGroupIndices();
45 for (
auto const& obj : preprocessorResult.objectives) {
46 if (obj.formula->isRewardOperatorFormula()) {
47 auto const& rewModel = preprocessorResult.
preprocessedModel->getRewardModel(obj.formula->asRewardOperatorFormula().getRewardModelName());
48 if (obj.formula->getSubformula().isLongRunAverageRewardFormula()) {
49 zeroLraRewardChoices &= rewModel.getChoicesWithZeroReward(transitions);
50 }
else if (obj.formula->getSubformula().isTotalRewardFormula()) {
51 zeroTotalRewardChoices &= rewModel.getChoicesWithZeroReward(transitions);
54 "Analyzing subformula " << obj.formula->getSubformula() <<
" is not supported properly.");
55 zeroCumulativeRewardChoices &= rewModel.getChoicesWithZeroReward(transitions);
61 auto statesWithTotalRewardForAllChoices = transitions.getRowGroupFilter(~zeroTotalRewardChoices,
true);
63 statesWithTotalRewardForAllChoices,
false, 0, zeroTotalRewardChoices);
64 result.totalReward0EStates.complement();
68 auto statesWithoutLraReward = transitions.getRowGroupFilter(zeroLraRewardChoices,
true);
71 result.reward0AStates =
74 auto statesWithTotalOrCumulativeReward = transitions.getRowGroupFilter(~(zeroTotalRewardChoices & zeroCumulativeRewardChoices),
false);
76 assert(result.reward0AStates.isSubsetOf(result.totalReward0EStates));
79template<
typename SparseModelType>
80void SparseMultiObjectiveRewardAnalysis<SparseModelType>::checkRewardFiniteness(
85 auto const& transitions = preprocessorResult.
preprocessedModel->getTransitionMatrix();
86 std::vector<uint_fast64_t>
const& groupIndices = transitions.getRowGroupIndices();
93 for (
auto objIndex : preprocessorResult.maybeInfiniteRewardObjectives) {
95 "Objective needs to be checked for finite reward but has no reward operator.");
97 preprocessorResult.
objectives[objIndex].formula->asRewardOperatorFormula().getRewardModelName());
98 auto irrelevantChoices = rewModel.getChoicesWithZeroReward(transitions);
100 if (preprocessorResult.
objectives[objIndex].formula->getSubformula().isCumulativeRewardFormula()) {
101 auto const& timeBoundReference =
102 preprocessorResult.
objectives[objIndex].formula->getSubformula().asCumulativeRewardFormula().getTimeBoundReference();
104 assert(timeBoundReference.isRewardBound());
105 auto const& rewModelOfBound = preprocessorResult.
preprocessedModel->getRewardModel(timeBoundReference.getRewardName());
106 irrelevantChoices |= ~rewModelOfBound.getChoicesWithZeroReward(transitions);
110 bool const negativeRewards = rewModel.hasNegativeRewards();
111 bool const positiveRewards = rewModel.hasPositiveRewards();
112 bool const hasMixedSignRewards = negativeRewards && positiveRewards;
114 if (hasMixedSignRewards || (maximizing && !negativeRewards) || (!maximizing && !positiveRewards)) {
115 attractingInfRewardChoices &= irrelevantChoices;
117 drainingInfRewardChoices &= irrelevantChoices;
120 attractingInfRewardChoices.complement();
121 drainingInfRewardChoices.complement();
131 result.totalRewardLessInfinityEStates =
133 if ((result.totalRewardLessInfinityEStates.get() & preprocessorResult.
preprocessedModel->getInitialStates()).empty()) {
141 result.totalRewardLessInfinityEStates = allStates;
145template<
typename SparseModelType>
150 "Tried to find an upper result bound for an objective, but a result bound is already there.");
153 auto const& transitions = model.getTransitionMatrix();
155 if (objective.
formula->isRewardOperatorFormula()) {
156 auto const& rewModel = model.getRewardModel(objective.
formula->asRewardOperatorFormula().getRewardModelName());
157 auto actionRewards = rewModel.getTotalRewardVector(transitions);
159 if (objective.
formula->getSubformula().isTotalRewardFormula() || objective.
formula->getSubformula().isCumulativeRewardFormula()) {
165 auto nonZeroRewardStates = rewModel.getStatesWithZeroReward(transitions);
166 nonZeroRewardStates.complement();
169 auto zeroRewardChoices = rewModel.getChoicesWithZeroReward(transitions);
174 allStates.
resize(ecElimRes.matrix.getRowGroupCount());
176 std::vector<ValueType> rew0StateProbs;
177 rew0StateProbs.reserve(ecElimRes.matrix.getRowCount());
178 for (uint64_t state = 0; state < allStates.
size(); ++state) {
179 for (uint64_t choice = ecElimRes.matrix.getRowGroupIndices()[state]; choice < ecElimRes.matrix.getRowGroupIndices()[state + 1]; ++choice) {
181 bool isOutChoice =
false;
182 uint64_t originalModelChoice = ecElimRes.newToOldRowMapping[choice];
183 for (
auto const& entry : transitions.getRow(originalModelChoice)) {
184 if (!expRewGreater0EStates.get(entry.getColumn())) {
186 outStates.
set(state,
true);
187 rew0StateProbs.push_back(storm::utility::one<ValueType>() - ecElimRes.matrix.getRowSum(choice));
193 rew0StateProbs.push_back(storm::utility::zero<ValueType>());
202 std::vector<ValueType> rewards;
203 rewards.reserve(ecElimRes.matrix.getRowCount());
204 for (
auto row : ecElimRes.newToOldRowMapping) {
205 rewards.push_back(actionRewards[row]);
ValueType computeUpperBound()
Computes an upper bound on the expected rewards.
static ReturnType analyze(storm::modelchecker::multiobjective::preprocessing::SparseMultiObjectivePreprocessorResult< SparseModelType > const &preprocessorResult)
Analyzes the reward objectives of the multi objective query.
static void computeUpperResultBound(SparseModelType const &model, storm::modelchecker::multiobjective::Objective< ValueType > &objective, storm::storage::SparseMatrix< ValueType > const &backwardTransitions)
Tries to finds an upper bound for the expected reward of the objective (assuming it considers an expe...
A bit vector that is internally represented as a vector of 64-bit values.
bool full() const
Retrieves whether all bits are set in this bit vector.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
A class that holds a possibly non-square matrix in the compressed row storage format.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_INFO_COND(cond, message)
bool constexpr maximize(OptimizationDirection d)
storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under any pos...
storm::storage::BitVector performProb1A(storm::models::sparse::NondeterministicModel< T, RM > const &model, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 1 of satisfying phi until psi under all possible re...
storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Computes the sets of states that have probability greater 0 of satisfying phi until psi under at leas...
storm::storage::BitVector performProb0A(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
bool checkIfECWithChoiceExists(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &subsystem, storm::storage::BitVector const &choices)
Checks whether there is an End Component that.
storm::storage::BitVector performProb1E(storm::storage::SparseMatrix< T > const &transitionMatrix, std::vector< uint_fast64_t > const &nondeterministicChoiceIndices, storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, boost::optional< storm::storage::BitVector > const &choiceConstraint)
Computes the sets of states that have probability 1 of satisfying phi until psi under at least one po...
bool isZero(ValueType const &a)
boost::optional< ValueType > upperResultBound
std::shared_ptr< storm::logic::OperatorFormula const > formula
std::shared_ptr< SparseModelType > preprocessedModel
std::vector< Objective< typename SparseModelType::ValueType > > objectives