Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
FormulaInformation.cpp
Go to the documentation of this file.
2
12
13namespace storm {
14namespace pomdp {
15namespace analysis {
16
18 STORM_LOG_ASSERT(states.empty() == observations.empty(), "Inconsistent StateSet.");
19 return observations.empty();
20}
21
23 // Intentionally left empty
24}
25
26FormulaInformation::FormulaInformation(Type const& type, storm::solver::OptimizationDirection const& dir, std::optional<std::string> const& rewardModelName)
27 : type(type), optimizationDirection(dir), rewardModelName(rewardModelName) {
29 !this->rewardModelName.has_value() || this->type == Type::NonNestedExpectedRewardFormula || this->type == Type::DiscountedTotalRewardFormula,
30 "Got a reward model name for a non-reward formula.");
31}
32
34 return type;
35}
36
40
44
48
50 return type == Type::Unsupported;
51}
52
54 return rewardBounded;
55}
56
59 "Target states requested for unexpected formula type.");
60 return targetStates.value();
61}
62
64 STORM_LOG_ASSERT(this->type == Type::NonNestedReachabilityProbability, "Sink states requested for unexpected formula type.");
65 return sinkStates.value();
66}
67
68std::string const& FormulaInformation::getRewardModelName() const {
70 "Reward model requested for unexpected formula type.");
71 return rewardModelName.value();
72}
73
75 return optimizationDirection;
76}
77
78std::vector<storm::logic::TimeBoundReference> const& FormulaInformation::getRewardBoundReferences() const {
79 return rewardBoundReferences;
80}
81
83 return storm::solver::minimize(optimizationDirection);
84}
85
87 return storm::solver::maximize(optimizationDirection);
88}
90 rewardBounded = newValue;
91}
92
93template<typename PomdpType>
96 result.states = std::move(inputStates);
97 for (uint64_t state : result.states) {
98 result.observations.insert(pomdp.getObservation(state));
99 }
100 // check if this set is observation-closed, i.e., whether there is a state outside of this set with one of the observations collected above
101 result.observationClosed = true;
102 for (uint64_t state = result.states.getNextUnsetIndex(0); state < result.states.size(); state = result.states.getNextUnsetIndex(state + 1)) {
103 if (result.observations.count(pomdp.getObservation(state)) > 0) {
104 result.observationClosed = false;
105 break;
106 }
107 }
108 return result;
109}
110
111template<typename PomdpType>
114 "Target states updated for unexpected formula type.");
115 targetStates = getStateSet(pomdp, std::move(newTargetStates));
116}
117
118template<typename PomdpType>
120 STORM_LOG_ASSERT(this->type == Type::NonNestedReachabilityProbability, "Sink states requested for unexpected formula type.");
121 sinkStates = getStateSet(pomdp, std::move(newSinkStates));
122}
123void FormulaInformation::setRewardBoundReferences(std::vector<logic::TimeBoundReference>& newRewardBoundReferences) {
124 STORM_LOG_ASSERT(this->type == Type::NonNestedReachabilityProbability && this->isBounded(), "RewardBoundReference requested for unexpected formula type.");
125 rewardBoundReferences = newRewardBoundReferences;
126}
127
128template<typename PomdpType>
129storm::storage::BitVector getStates(storm::logic::Formula const& propositionalFormula, bool formulaInverted, PomdpType const& pomdp) {
131 auto checkResult = mc.check(propositionalFormula);
132 storm::storage::BitVector resultBitVector(checkResult->template asExplicitQualitativeCheckResult<typename PomdpType::ValueType>().getTruthValuesVector());
133 if (formulaInverted) {
134 resultBitVector.complement();
135 }
136 return resultBitVector;
137}
138
139template<typename PomdpType>
141 STORM_LOG_THROW(formula.hasOptimalityType(), storm::exceptions::InvalidPropertyException,
142 "The property does not specify an optimization direction (min/max).");
143 STORM_LOG_WARN_COND(!formula.hasBound(), "The probability threshold for the given property will be ignored.");
144 auto const& subformula = formula.getSubformula();
145 bool bounded = false;
146 std::vector<storm::logic::TimeBoundReference> rewardBoundReferences;
147
148 std::shared_ptr<storm::logic::Formula const> targetStatesFormula, constraintsStatesFormula;
149 if (subformula.isEventuallyFormula()) {
150 targetStatesFormula = subformula.asEventuallyFormula().getSubformula().asSharedPointer();
151 constraintsStatesFormula = storm::logic::Formula::getTrueFormula()->asSharedPointer();
152 } else if (subformula.isUntilFormula()) {
153 storm::logic::UntilFormula const& untilFormula = subformula.asUntilFormula();
154 targetStatesFormula = untilFormula.getRightSubformula().asSharedPointer();
155 constraintsStatesFormula = untilFormula.getLeftSubformula().asSharedPointer();
156 } else if (subformula.isBoundedUntilFormula()) {
157 storm::logic::BoundedUntilFormula const& boundedUntilFormula = subformula.asBoundedUntilFormula();
158 STORM_LOG_THROW(!boundedUntilFormula.hasMultiDimensionalSubformulas(), storm::exceptions::NotSupportedException,
159 "Reward-bounded POMDP properties with dimension-specific state subformulas are not supported.");
160 for (uint64_t i = 0; i < boundedUntilFormula.getDimension(); ++i) {
161 STORM_LOG_THROW(boundedUntilFormula.getLeftSubformula(i).isTrueFormula(), storm::exceptions::NotSupportedException,
162 "Reward-bounded until properties for POMDPs currently require 'true' as the left-hand side, i.e., they must be reward-bounded "
163 "reachability properties.");
164 }
165 targetStatesFormula = boundedUntilFormula.getRightSubformula().asSharedPointer();
166 constraintsStatesFormula = boundedUntilFormula.getLeftSubformula().asSharedPointer();
167 bounded = true;
168 for (uint64_t i = 0; i < boundedUntilFormula.getDimension(); ++i) {
169 auto const& boundReference = boundedUntilFormula.getTimeBoundReference(i);
170 STORM_LOG_THROW(boundReference.isRewardBound() && !boundReference.hasRewardAccumulation(), storm::exceptions::NotSupportedException,
171 "For POMDPs, only plain reward bounds are supported.");
172 STORM_LOG_THROW(boundReference.hasRewardModelName(), storm::exceptions::NotSupportedException,
173 "For POMDPs, reward-bounded formulae must explicitly name a reward model for each bound.");
174 rewardBoundReferences.push_back(boundReference);
175 }
176 }
177 if (targetStatesFormula && targetStatesFormula->isInFragment(storm::logic::propositional()) && constraintsStatesFormula &&
178 constraintsStatesFormula->isInFragment(storm::logic::propositional())) {
180 result.updateTargetStates(pomdp, getStates(*targetStatesFormula, false, pomdp));
181 result.updateSinkStates(pomdp, getStates(*constraintsStatesFormula, true, pomdp));
182 result.setRewardBounded(bounded);
183 if (bounded) {
184 result.setRewardBoundReferences(rewardBoundReferences);
185 }
186 return result;
187 }
188 return FormulaInformation();
189}
190
191template<typename PomdpType>
193 STORM_LOG_THROW(formula.hasOptimalityType(), storm::exceptions::InvalidPropertyException,
194 "The property does not specify an optimization direction (min/max).");
195 STORM_LOG_WARN_COND(!formula.hasBound(), "The reward threshold for the given property will be ignored.");
196 std::string rewardModelName = "";
197 if (formula.hasRewardModelName()) {
198 rewardModelName = formula.getRewardModelName();
199 STORM_LOG_THROW(pomdp.hasRewardModel(rewardModelName), storm::exceptions::InvalidPropertyException,
200 "Selected reward model with name '" << rewardModelName << "' does not exist.");
201 } else {
202 STORM_LOG_THROW(pomdp.hasUniqueRewardModel(), storm::exceptions::InvalidPropertyException,
203 "Reward operator formula does not specify a reward model and the reward model is not unique.");
204 rewardModelName = pomdp.getUniqueRewardModelName();
205 }
206 auto const& subformula = formula.getSubformula();
207 if (subformula.isDiscountedTotalRewardFormula()) {
209 return result;
210 }
211 std::shared_ptr<storm::logic::Formula const> targetStatesFormula;
212 if (subformula.isEventuallyFormula()) {
213 targetStatesFormula = subformula.asEventuallyFormula().getSubformula().asSharedPointer();
214 }
215 if (targetStatesFormula && targetStatesFormula->isInFragment(storm::logic::propositional())) {
217 result.updateTargetStates(pomdp, getStates(*targetStatesFormula, false, pomdp));
218 return result;
219 }
220 return FormulaInformation();
221}
222
223template<typename PomdpType>
225 if (formula.isProbabilityOperatorFormula()) {
227 } else if (formula.isRewardOperatorFormula()) {
229 }
230 return FormulaInformation();
231}
232
234 storm::storage::BitVector&& newTargetStates);
236 storm::storage::BitVector&& newSinkStates);
238 storm::logic::Formula const& formula);
245
246} // namespace analysis
247} // namespace pomdp
248} // namespace storm
Formula const & getRightSubformula() const
Formula const & getLeftSubformula() const
TimeBoundReference const & getTimeBoundReference(unsigned i=0) const
RewardOperatorFormula & asRewardOperatorFormula()
Definition Formula.cpp:514
UntilFormula & asUntilFormula()
Definition Formula.cpp:339
virtual bool isTrueFormula() const
Definition Formula.cpp:70
BoundedUntilFormula & asBoundedUntilFormula()
Definition Formula.cpp:363
static std::shared_ptr< Formula const > getTrueFormula()
Definition Formula.cpp:227
virtual bool isProbabilityOperatorFormula() const
Definition Formula.cpp:194
ProbabilityOperatorFormula & asProbabilityOperatorFormula()
Definition Formula.cpp:506
virtual bool isRewardOperatorFormula() const
Definition Formula.cpp:198
std::shared_ptr< Formula const > asSharedPointer()
Definition Formula.cpp:601
storm::solver::OptimizationDirection const & getOptimalityType() const
std::string const & getRewardModelName() const
Retrieves the name of the reward model this property refers to (if any).
bool hasRewardModelName() const
Retrieves whether the reward model refers to a specific reward model.
Formula const & getSubformula() const
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
Checks the provided formula.
This class represents a partially observable Markov decision process.
Definition Pomdp.h:13
void updateSinkStates(PomdpType const &pomdp, storm::storage::BitVector &&newSinkStates)
storm::solver::OptimizationDirection const & getOptimizationDirection() const
Type
Possible supported formula types.
void setRewardBoundReferences(std::vector< logic::TimeBoundReference > &newRewardBoundReferences)
void updateTargetStates(PomdpType const &pomdp, storm::storage::BitVector &&newTargetStates)
std::vector< logic::TimeBoundReference > const & getRewardBoundReferences() const
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:16
void complement()
Negates all bits in the bit vector.
uint64_t getNextUnsetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to false in the bit vector.
size_t size() const
Retrieves the number of bits this bit vector can store.
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_WARN_COND(cond, message)
Definition macros.h:54
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
FragmentSpecification propositional()
storm::storage::BitVector getStates(storm::logic::Formula const &propositionalFormula, bool formulaInverted, PomdpType const &pomdp)
FormulaInformation::StateSet getStateSet(PomdpType const &pomdp, storm::storage::BitVector &&inputStates)
FormulaInformation getFormulaInformation(PomdpType const &pomdp, storm::logic::ProbabilityOperatorFormula const &formula)
bool constexpr maximize(OptimizationDirection d)
bool constexpr minimize(OptimizationDirection d)