Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
RewardAccumulationEliminationVisitor.cpp
Go to the documentation of this file.
2#include <boost/any.hpp>
3#include <optional>
5
10
13
14namespace storm {
15namespace logic {
16
18 // Intentionally left empty
19}
20
22 boost::any result = f.accept(*this, boost::any());
23 return boost::any_cast<std::shared_ptr<Formula>>(result);
24}
25
26void RewardAccumulationEliminationVisitor::eliminateRewardAccumulations(std::vector<storm::jani::Property>& properties) const {
27 for (auto& p : properties) {
29 }
30}
31
33 auto formula = eliminateRewardAccumulations(*property.getFilter().getFormula());
34 auto states = eliminateRewardAccumulations(*property.getFilter().getStatesFormula());
35 storm::jani::FilterExpression fe(formula, property.getFilter().getFilterType(), states);
36 property = storm::jani::Property(property.getName(), storm::jani::FilterExpression(formula, property.getFilter().getFilterType(), states),
37 property.getUndefinedConstants(), property.getComment());
38}
39
40boost::any RewardAccumulationEliminationVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const {
41 std::vector<std::optional<TimeBound>> lowerBounds, upperBounds;
42 std::vector<TimeBoundReference> timeBoundReferences;
43 for (uint64_t i = 0; i < f.getDimension(); ++i) {
44 if (f.hasLowerBound(i)) {
45 lowerBounds.emplace_back(TimeBound(f.isLowerBoundStrict(i), f.getLowerBound(i)));
46 } else {
47 lowerBounds.emplace_back();
48 }
49 if (f.hasUpperBound(i)) {
50 upperBounds.emplace_back(TimeBound(f.isUpperBoundStrict(i), f.getUpperBound(i)));
51 } else {
52 upperBounds.emplace_back();
53 }
55 if (tbr.hasRewardAccumulation() && canEliminate(tbr.getRewardAccumulation(), tbr.getRewardName())) {
56 // Eliminate accumulation
57 tbr = storm::logic::TimeBoundReference(tbr.getRewardName(), boost::none);
58 }
59 timeBoundReferences.push_back(std::move(tbr));
60 }
62 std::vector<std::shared_ptr<Formula const>> leftSubformulas, rightSubformulas;
63 for (uint64_t i = 0; i < f.getDimension(); ++i) {
64 leftSubformulas.push_back(boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula(i).accept(*this, data)));
65 rightSubformulas.push_back(boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula(i).accept(*this, data)));
66 }
67 return std::static_pointer_cast<Formula>(
68 std::make_shared<BoundedUntilFormula>(leftSubformulas, rightSubformulas, lowerBounds, upperBounds, timeBoundReferences));
69 } else {
70 std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
71 std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
72 return std::static_pointer_cast<Formula>(std::make_shared<BoundedUntilFormula>(left, right, lowerBounds, upperBounds, timeBoundReferences));
73 }
74}
75
76boost::any RewardAccumulationEliminationVisitor::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
77 boost::optional<storm::logic::RewardAccumulation> rewAcc;
78 STORM_LOG_THROW(!data.empty(), storm::exceptions::UnexpectedException, "Formula " << f << " does not seem to be a subformula of a reward operator.");
79 auto rewName = boost::any_cast<boost::optional<std::string>>(data);
80 if (f.hasRewardAccumulation() && !canEliminate(f.getRewardAccumulation(), rewName)) {
81 rewAcc = f.getRewardAccumulation();
82 }
83
84 std::vector<TimeBound> bounds;
85 std::vector<TimeBoundReference> timeBoundReferences;
86 for (uint64_t i = 0; i < f.getDimension(); ++i) {
87 bounds.emplace_back(TimeBound(f.isBoundStrict(i), f.getBound(i)));
89 if (tbr.hasRewardAccumulation() && canEliminate(tbr.getRewardAccumulation(), tbr.getRewardName())) {
90 // Eliminate accumulation
91 tbr = storm::logic::TimeBoundReference(tbr.getRewardName(), boost::none);
92 }
93 timeBoundReferences.push_back(std::move(tbr));
94 }
95 return std::static_pointer_cast<Formula>(std::make_shared<CumulativeRewardFormula>(bounds, timeBoundReferences, rewAcc));
96}
97
98boost::any RewardAccumulationEliminationVisitor::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
99 STORM_LOG_THROW(!data.empty(), storm::exceptions::UnexpectedException, "Formula " << f << " does not seem to be a subformula of a reward operator.");
100 auto rewName = boost::any_cast<boost::optional<std::string>>(data);
101 if (!f.hasRewardAccumulation() || canEliminate(f.getRewardAccumulation(), rewName)) {
102 return std::static_pointer_cast<Formula>(std::make_shared<LongRunAverageRewardFormula>());
103 } else {
104 return std::static_pointer_cast<Formula>(std::make_shared<LongRunAverageRewardFormula>(f.getRewardAccumulation()));
105 }
106}
107
108boost::any RewardAccumulationEliminationVisitor::visit(EventuallyFormula const& f, boost::any const& data) const {
109 std::shared_ptr<Formula> subformula = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
110 if (f.hasRewardAccumulation()) {
111 if (f.isTimePathFormula()) {
112 if (model.isDiscreteTimeModel() && ((!f.getRewardAccumulation().isExitSet() && !f.getRewardAccumulation().isStepsSet()) ||
114 return std::static_pointer_cast<Formula>(std::make_shared<EventuallyFormula>(subformula, f.getContext(), f.getRewardAccumulation()));
115 } else if (!model.isDiscreteTimeModel() &&
117 return std::static_pointer_cast<Formula>(std::make_shared<EventuallyFormula>(subformula, f.getContext(), f.getRewardAccumulation()));
118 }
119 } else if (f.isRewardPathFormula()) {
120 STORM_LOG_THROW(!data.empty(), storm::exceptions::UnexpectedException,
121 "Formula " << f << " does not seem to be a subformula of a reward operator.");
122 auto rewName = boost::any_cast<boost::optional<std::string>>(data);
123 if (!canEliminate(f.getRewardAccumulation(), rewName)) {
124 return std::static_pointer_cast<Formula>(std::make_shared<EventuallyFormula>(subformula, f.getContext(), f.getRewardAccumulation()));
125 }
126 }
127 }
128 return std::static_pointer_cast<Formula>(std::make_shared<EventuallyFormula>(subformula, f.getContext()));
129}
130
131boost::any RewardAccumulationEliminationVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const {
132 std::shared_ptr<Formula> subformula = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, f.getOptionalRewardModelName()));
133 return std::static_pointer_cast<Formula>(std::make_shared<RewardOperatorFormula>(subformula, f.getOptionalRewardModelName(), f.getOperatorInformation()));
134}
135
136boost::any RewardAccumulationEliminationVisitor::visit(TotalRewardFormula const& f, boost::any const& data) const {
137 STORM_LOG_THROW(!data.empty(), storm::exceptions::UnexpectedException, "Formula " << f << " does not seem to be a subformula of a reward operator.");
138 auto rewName = boost::any_cast<boost::optional<std::string>>(data);
139 if (!f.hasRewardAccumulation() || canEliminate(f.getRewardAccumulation(), rewName)) {
140 return std::static_pointer_cast<Formula>(std::make_shared<TotalRewardFormula>());
141 } else {
142 return std::static_pointer_cast<Formula>(std::make_shared<TotalRewardFormula>(f.getRewardAccumulation()));
143 }
144}
145
146bool RewardAccumulationEliminationVisitor::canEliminate(storm::logic::RewardAccumulation const& accumulation,
147 boost::optional<std::string> rewardModelName) const {
148 STORM_LOG_THROW(rewardModelName.is_initialized(), storm::exceptions::InvalidPropertyException,
149 "Unable to find transient variable for unique reward model.");
150 storm::jani::RewardModelInformation info(model, rewardModelName.get());
151
152 if ((info.hasActionRewards() || info.hasTransitionRewards()) && !accumulation.isStepsSet()) {
153 return false;
154 }
155 if (info.hasStateRewards()) {
156 if (model.isDiscreteTimeModel()) {
157 if (!accumulation.isExitSet()) {
158 return false;
159 }
160 // accumulating over time in discrete time models has no effect, i.e., the value of accumulation.isTimeSet() does not matter here.
161 } else {
162 if (accumulation.isExitSet() || !accumulation.isTimeSet()) {
163 return false;
164 }
165 }
166 }
167 return true;
168}
169
170boost::any RewardAccumulationEliminationVisitor::visit(DiscountedCumulativeRewardFormula const& f, boost::any const& data) const {
171 boost::optional<storm::logic::RewardAccumulation> rewAcc;
172 STORM_LOG_THROW(!data.empty(), storm::exceptions::UnexpectedException, "Formula " << f << " does not seem to be a subformula of a reward operator.");
173 auto rewName = boost::any_cast<boost::optional<std::string>>(data);
174 if (f.hasRewardAccumulation() && !canEliminate(f.getRewardAccumulation(), rewName)) {
175 rewAcc = f.getRewardAccumulation();
176 }
177
178 std::vector<TimeBound> bounds;
179 std::vector<TimeBoundReference> timeBoundReferences;
180 for (uint64_t i = 0; i < f.getDimension(); ++i) {
181 bounds.emplace_back(TimeBound(f.isBoundStrict(i), f.getBound(i)));
183 if (tbr.hasRewardAccumulation() && canEliminate(tbr.getRewardAccumulation(), tbr.getRewardName())) {
184 // Eliminate accumulation
185 tbr = storm::logic::TimeBoundReference(tbr.getRewardName(), boost::none);
186 }
187 timeBoundReferences.push_back(std::move(tbr));
188 }
189
190 return std::static_pointer_cast<Formula>(std::make_shared<DiscountedCumulativeRewardFormula>(f.getDiscountFactor(), bounds, timeBoundReferences, rewAcc));
191}
192
193boost::any RewardAccumulationEliminationVisitor::visit(DiscountedTotalRewardFormula const& f, boost::any const& data) const {
194 STORM_LOG_THROW(!data.empty(), storm::exceptions::UnexpectedException, "Formula " << f << " does not seem to be a subformula of a reward operator.");
195 auto rewName = boost::any_cast<boost::optional<std::string>>(data);
196 if (!f.hasRewardAccumulation() || canEliminate(f.getRewardAccumulation(), rewName)) {
197 return std::static_pointer_cast<Formula>(std::make_shared<DiscountedTotalRewardFormula>(f.getDiscountFactor()));
198 } else {
199 return std::static_pointer_cast<Formula>(std::make_shared<DiscountedTotalRewardFormula>(f.getDiscountFactor(), f.getRewardAccumulation()));
200 }
201}
202} // namespace logic
203} // namespace storm
std::shared_ptr< storm::logic::Formula const > const & getFormula() const
Definition Property.h:48
std::shared_ptr< storm::logic::Formula const > const & getStatesFormula() const
Definition Property.h:52
storm::modelchecker::FilterType getFilterType() const
Definition Property.h:56
bool isDiscreteTimeModel() const
Determines whether this model is a discrete-time model.
Definition Model.cpp:1384
std::set< storm::expressions::Variable > const & getUndefinedConstants() const
Definition Property.cpp:96
std::string const & getName() const
Get the provided name.
Definition Property.cpp:23
std::string const & getComment() const
Get the provided comment, if any.
Definition Property.cpp:27
FilterExpression const & getFilter() const
Definition Property.cpp:88
TimeBoundReference const & getTimeBoundReference(unsigned i=0) const
bool isLowerBoundStrict(unsigned i=0) const
storm::expressions::Expression const & getUpperBound(unsigned i=0) const
storm::expressions::Expression const & getLowerBound(unsigned i=0) const
bool isUpperBoundStrict(unsigned i=0) const
TimeBoundReference const & getTimeBoundReference() const
RewardAccumulation const & getRewardAccumulation() const
storm::expressions::Expression const & getBound() const
storm::expressions::Expression const & getDiscountFactor() const
storm::expressions::Expression const & getDiscountFactor() const
FormulaContext const & getContext() const
virtual bool isTimePathFormula() const override
virtual bool isRewardPathFormula() const override
RewardAccumulation const & getRewardAccumulation() const
boost::any accept(FormulaVisitor const &visitor) const
Definition Formula.cpp:16
RewardAccumulation const & getRewardAccumulation() const
OperatorInformation const & getOperatorInformation() const
std::shared_ptr< Formula > eliminateRewardAccumulations(Formula const &f) const
Eliminates any reward accumulations of the formula, where the presence of the reward accumulation doe...
virtual boost::any visit(BoundedUntilFormula const &f, boost::any const &data) const override
boost::optional< std::string > const & getOptionalRewardModelName() const
Retrieves the optional representing the reward model name this property refers to.
std::string const & getRewardName() const
RewardAccumulation const & getRewardAccumulation() const
RewardAccumulation const & getRewardAccumulation() const
Formula const & getSubformula() const
Formula const & getSubformula() const
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28