14namespace transformer {
16template<
typename ValueType>
19template<
typename ValueType>
24 "The formula " << formula <<
" does not specify whether to minimize or maximize.");
32 subformula->asEventuallyFormula().getSubformula().asSharedPointer());
37 return transformMax(subformula->asUntilFormula());
41 return transformMinReward(subformula->asEventuallyFormula());
44 STORM_LOG_THROW(
false, storm::exceptions::InvalidPropertyException,
"Mec elimination is not supported for the property " << formula);
48template<
typename ValueType>
52 auto backwardTransitions = pomdp.getBackwardTransitions();
55 allStates, checkPropositionalFormula(formula.
getSubformula()));
56 STORM_LOG_THROW(prob1EStates.full(), storm::exceptions::InvalidPropertyException,
57 "There are states from which the set of target states is not reachable. This is not supported.");
59 allStates, checkPropositionalFormula(formula.
getSubformula()));
61 auto mecs = decomposeEndComponents(~prob1AStates, ~allStates);
67 std::vector<storm::storage::BitVector> mecChoicesPerObservation = getEndComponentChoicesPerObservation(mecs, uniqueOutStates);
71 for (
auto const state : stateFilter) {
72 mecChoicesPerObservation[pomdp.getObservation(state)].
clear();
76 for (
auto& clearedChoices : mecChoicesPerObservation) {
77 STORM_LOG_ASSERT(clearedChoices.size() == 0 || !clearedChoices.full(),
"Tried to clear all choices for an observation.");
83 for (
auto const state : stateFilter) {
84 uint64_t offset = pomdp.getTransitionMatrix().getRowGroupIndices()[state];
85 for (
auto const& choice : mecChoicesPerObservation[pomdp.getObservation(state)]) {
86 choiceFilter.set(offset + choice,
false);
90 ChoiceSelector<ValueType> cs(pomdp);
91 auto res = cs.transform(choiceFilter)->template as<storm::models::sparse::Pomdp<ValueType>>();
96template<
typename ValueType>
97std::shared_ptr<storm::models::sparse::Pomdp<ValueType>> GlobalPomdpMecChoiceEliminator<ValueType>::transformMax(
99 auto backwardTransitions = pomdp.getBackwardTransitions();
103 auto mecs = decomposeEndComponents(~(prob01States.first | prob01States.second), prob01States.first);
109 std::vector<storm::storage::BitVector> mecChoicesPerObservation = getEndComponentChoicesPerObservation(mecs, uniqueOutStates);
113 for (
auto const state : stateFilter) {
114 mecChoicesPerObservation[pomdp.getObservation(state)].
clear();
118 for (
auto& clearedChoices : mecChoicesPerObservation) {
119 STORM_LOG_ASSERT(clearedChoices.size() == 0 || !clearedChoices.full(),
"Tried to clear all choices for an observation.");
125 for (
auto const state : stateFilter) {
126 uint64_t offset = pomdp.getTransitionMatrix().getRowGroupIndices()[state];
127 for (
auto const& choice : mecChoicesPerObservation[pomdp.getObservation(state)]) {
128 choiceFilter.set(offset + choice,
false);
132 ChoiceSelector<ValueType> cs(pomdp);
133 auto res = cs.transform(choiceFilter)->template as<storm::models::sparse::Pomdp<ValueType>>();
138template<
typename ValueType>
142 for (
auto const& mec : mecs) {
143 std::optional<uint64_t> uniqueOutState = std::nullopt;
144 for (
auto const& stateActionsPair : mec) {
146 if (stateActionsPair.second.size() != pomdp.getNumberOfChoices(stateActionsPair.first)) {
147 if (uniqueOutState) {
149 uniqueOutState = std::nullopt;
152 uniqueOutState = stateActionsPair.first;
156 if (uniqueOutState) {
157 result.set(uniqueOutState.value(),
true);
163template<
typename ValueType>
164std::vector<storm::storage::BitVector> GlobalPomdpMecChoiceEliminator<ValueType>::getEndComponentChoicesPerObservation(
166 std::vector<storm::storage::BitVector> result(pomdp.getNrObservations());
167 for (
auto const& mec : mecs) {
168 for (
auto const& stateActions : mec) {
169 if (consideredStates.
get(stateActions.first)) {
171 uint64_t offset = pomdp.getTransitionMatrix().getRowGroupIndices()[stateActions.first];
172 for (
auto const& choice : stateActions.second) {
173 assert(choice >= offset);
174 localChoiceIndices.set(choice - offset,
true);
177 auto& mecChoices = result[pomdp.getObservation(stateActions.first)];
178 if (mecChoices.size() == 0) {
179 mecChoices = localChoiceIndices;
182 "Observation action count does not match for two states with the same observation");
183 mecChoices &= localChoiceIndices;
191template<
typename ValueType>
194 if (redirectingStates.
empty()) {
199 true, pomdp.getTransitionMatrix().getRowGroupCount());
201 for (uint64_t rowGroup = 0; rowGroup < pomdp.getTransitionMatrix().getRowGroupCount(); ++rowGroup) {
202 assert(row == pomdp.getTransitionMatrix().getRowGroupIndices()[rowGroup]);
203 builder.newRowGroup(row);
204 for (; row < pomdp.getTransitionMatrix().getRowGroupIndices()[rowGroup + 1]; ++row) {
205 ValueType redirectedProbabilityMass = pomdp.getTransitionMatrix().getConstrainedRowSum(row, redirectingStates);
207 for (
auto const& entry : pomdp.getTransitionMatrix().getRow(row)) {
208 if (!redirectingStates.
get(entry.getColumn())) {
209 if (insertSelfloop && entry.getColumn() >= rowGroup) {
211 insertSelfloop =
false;
212 if (entry.getColumn() == rowGroup) {
213 builder.addNextValue(row, rowGroup, entry.getValue() + redirectedProbabilityMass);
216 builder.addNextValue(row, rowGroup, redirectedProbabilityMass);
219 builder.addNextValue(row, entry.getColumn(), entry.getValue());
222 if (insertSelfloop) {
223 builder.addNextValue(row, rowGroup, redirectedProbabilityMass);
232template<
typename ValueType>
235 STORM_LOG_THROW(mc.canHandle(propositionalFormula), storm::exceptions::InvalidPropertyException,
236 "Propositional model checker can not handle formula " << propositionalFormula);
237 return mc.check(propositionalFormula)->asExplicitQualitativeCheckResult().getTruthValuesVector();
240template class GlobalPomdpMecChoiceEliminator<storm::RationalNumber>;
242template class GlobalPomdpMecChoiceEliminator<double>;
This class represents a partially observable Markov decision process.
A bit vector that is internally represented as a vector of 64-bit values.
void complement()
Negates all bits in the bit vector.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
void clear()
Removes all set bits from the bit vector.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
This class represents the decomposition of a nondeterministic model into its maximal end components.
A class that can be used to build a sparse matrix by adding value by value.
A class that holds a possibly non-square matrix in the compressed row storage format.
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
SFTBDDChecker::ValueType ValueType
bool isLowerBound(ComparisonType t)
bool constexpr minimize(OptimizationDirection d)
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01Max(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)
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 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)
ComparisonType comparisonType