Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ExtractMaximalStateFormulasVisitor.cpp
Go to the documentation of this file.
2#include <boost/any.hpp>
3#include <optional>
4
6
8
9namespace storm {
10namespace logic {
11
12ExtractMaximalStateFormulasVisitor::ExtractMaximalStateFormulasVisitor(ApToFormulaMap& extractedFormulas)
13 : extractedFormulas(extractedFormulas), nestingLevel(0) {}
14
15std::shared_ptr<Formula> ExtractMaximalStateFormulasVisitor::extract(PathFormula const& f, ApToFormulaMap& extractedFormulas) {
16 ExtractMaximalStateFormulasVisitor visitor(extractedFormulas);
17 boost::any result = f.accept(visitor, boost::any());
18 return boost::any_cast<std::shared_ptr<Formula>>(result);
19}
20
21boost::any ExtractMaximalStateFormulasVisitor::visit(BinaryBooleanPathFormula const& f, boost::any const& data) const {
22 if (nestingLevel > 0) {
23 return CloneVisitor::visit(f, data);
24 }
25
26 std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
27 if (left->hasQualitativeResult()) {
28 left = extract(left);
29 }
30
31 std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
32 if (right->hasQualitativeResult()) {
33 right = extract(right);
34 }
35
36 return std::static_pointer_cast<Formula>(std::make_shared<BinaryBooleanPathFormula>(f.getOperator(), left, right));
37}
38
39boost::any ExtractMaximalStateFormulasVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const {
40 if (nestingLevel > 0) {
41 return CloneVisitor::visit(f, data);
42 }
43
44 STORM_LOG_THROW(!f.hasMultiDimensionalSubformulas(), storm::exceptions::InvalidOperationException,
45 "Can not extract maximal state formulas for multi-dimensional bounded until.");
46
47 std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
48 if (left->hasQualitativeResult()) {
49 left = extract(left);
50 }
51
52 std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
53 if (right->hasQualitativeResult()) {
54 right = extract(right);
55 }
56
57 // Copy bound information
58 std::vector<std::optional<TimeBound>> lowerBounds, upperBounds;
59 std::vector<TimeBoundReference> timeBoundReferences;
60 for (uint64_t i = 0; i < f.getDimension(); ++i) {
61 if (f.hasLowerBound(i)) {
62 lowerBounds.emplace_back(TimeBound(f.isLowerBoundStrict(i), f.getLowerBound(i)));
63 } else {
64 lowerBounds.emplace_back();
65 }
66 if (f.hasUpperBound(i)) {
67 upperBounds.emplace_back(TimeBound(f.isUpperBoundStrict(i), f.getUpperBound(i)));
68 } else {
69 upperBounds.emplace_back();
70 }
71 timeBoundReferences.push_back(f.getTimeBoundReference(i));
72 }
73
74 return std::static_pointer_cast<Formula>(std::make_shared<BoundedUntilFormula>(left, right, lowerBounds, upperBounds, timeBoundReferences));
75}
76
77boost::any ExtractMaximalStateFormulasVisitor::visit(EventuallyFormula const& f, boost::any const& data) const {
78 if (nestingLevel > 0) {
79 return CloneVisitor::visit(f, data);
80 }
81
82 std::shared_ptr<Formula> sub = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
83 if (sub->hasQualitativeResult()) {
84 sub = extract(sub);
85 }
86
87 return std::static_pointer_cast<Formula>(std::make_shared<EventuallyFormula>(sub));
88}
89
90boost::any ExtractMaximalStateFormulasVisitor::visit(GloballyFormula const& f, boost::any const& data) const {
91 if (nestingLevel > 0) {
92 return CloneVisitor::visit(f, data);
93 }
94
95 std::shared_ptr<Formula> sub = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
96 if (sub->hasQualitativeResult()) {
97 sub = extract(sub);
98 }
99
100 return std::static_pointer_cast<Formula>(std::make_shared<GloballyFormula>(sub));
101}
102
103boost::any ExtractMaximalStateFormulasVisitor::visit(NextFormula const& f, boost::any const& data) const {
104 if (nestingLevel > 0) {
105 return CloneVisitor::visit(f, data);
106 }
107
108 std::shared_ptr<Formula> sub = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
109 if (sub->hasQualitativeResult()) {
110 sub = extract(sub);
111 }
112
113 return std::static_pointer_cast<Formula>(std::make_shared<NextFormula>(sub));
114}
115
116boost::any ExtractMaximalStateFormulasVisitor::visit(UnaryBooleanPathFormula const& f, boost::any const& data) const {
117 if (nestingLevel > 0) {
118 return CloneVisitor::visit(f, data);
119 }
120
121 std::shared_ptr<Formula> sub = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
122 if (sub->hasQualitativeResult()) {
123 sub = extract(sub);
124 }
125
126 return std::static_pointer_cast<Formula>(std::make_shared<UnaryBooleanPathFormula>(f.getOperator(), sub));
127}
128
129boost::any ExtractMaximalStateFormulasVisitor::visit(UntilFormula const& f, boost::any const& data) const {
130 if (nestingLevel > 0) {
131 return CloneVisitor::visit(f, data);
132 }
133
134 std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
135 if (left->hasQualitativeResult()) {
136 left = extract(left);
137 }
138
139 std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
140 if (right->hasQualitativeResult()) {
141 right = extract(right);
142 }
143
144 return std::static_pointer_cast<Formula>(std::make_shared<UntilFormula>(left, right));
145}
146
147boost::any ExtractMaximalStateFormulasVisitor::visit(WeakUntilFormula const& f, boost::any const& data) const {
148 if (nestingLevel > 0) {
149 return CloneVisitor::visit(f, data);
150 }
151
152 std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
153 if (left->hasQualitativeResult()) {
154 left = extract(left);
155 }
156
157 std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
158 if (right->hasQualitativeResult()) {
159 right = extract(right);
160 }
161
162 return std::static_pointer_cast<Formula>(std::make_shared<WeakUntilFormula>(left, right));
163}
164
165boost::any ExtractMaximalStateFormulasVisitor::visit(ReleaseFormula const& f, boost::any const& data) const {
166 if (nestingLevel > 0) {
167 return CloneVisitor::visit(f, data);
168 }
169
170 std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
171 if (left->hasQualitativeResult()) {
172 left = extract(left);
173 }
174
175 std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
176 if (right->hasQualitativeResult()) {
177 right = extract(right);
178 }
179
180 return std::static_pointer_cast<Formula>(std::make_shared<ReleaseFormula>(left, right));
181}
182
183boost::any ExtractMaximalStateFormulasVisitor::visit(TimeOperatorFormula const& f, boost::any const& data) const {
184 incrementNestingLevel();
185 boost::any result = CloneVisitor::visit(f, data);
186 decrementNestingLevel();
187 return result;
188}
189
190boost::any ExtractMaximalStateFormulasVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
191 incrementNestingLevel();
192 boost::any result = CloneVisitor::visit(f, data);
193 decrementNestingLevel();
194 return result;
195}
196
197boost::any ExtractMaximalStateFormulasVisitor::visit(MultiObjectiveFormula const& f, boost::any const& data) const {
198 incrementNestingLevel();
199 boost::any result = CloneVisitor::visit(f, data);
200 decrementNestingLevel();
201 return result;
202}
203
204boost::any ExtractMaximalStateFormulasVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
205 incrementNestingLevel();
206 boost::any result = CloneVisitor::visit(f, data);
207 decrementNestingLevel();
208 return result;
209}
210
211boost::any ExtractMaximalStateFormulasVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const {
212 incrementNestingLevel();
213 boost::any result = CloneVisitor::visit(f, data);
214 decrementNestingLevel();
215 return result;
216}
217
218std::shared_ptr<Formula> ExtractMaximalStateFormulasVisitor::extract(std::shared_ptr<Formula> f) const {
219 // We use the string representation of formulae to check if they are equivalent.
220 // Of course, this could be made more elegant if there were an actual operator< and/or operator== for formulae
221
222 std::string label;
223
224 // Find equivalent formula in cache
225 auto it = cachedFormulas.find(f->toString());
226 if (it != cachedFormulas.end()) {
227 // Reuse label of equivalent formula
228 label = it->second;
229 } else {
230 // Create new label
231 label = "p" + std::to_string(extractedFormulas.size());
232 extractedFormulas[label] = f;
233 // Update cache
234 cachedFormulas[f->toString()] = label;
235 }
236
237 return std::make_shared<storm::logic::AtomicLabelFormula>(label);
238}
239
240void ExtractMaximalStateFormulasVisitor::incrementNestingLevel() const {
241 const_cast<std::size_t&>(nestingLevel)++;
242}
243void ExtractMaximalStateFormulasVisitor::decrementNestingLevel() const {
244 STORM_LOG_ASSERT(nestingLevel > 0, "Illegal nesting level decrement.");
245 const_cast<std::size_t&>(nestingLevel)--;
246}
247
248} // namespace logic
249} // namespace storm
Formula const & getRightSubformula() const
Formula const & getLeftSubformula() const
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
virtual boost::any visit(AtomicExpressionFormula const &f, boost::any const &data) const override
virtual boost::any visit(BinaryBooleanPathFormula const &f, boost::any const &data) const override
static std::shared_ptr< Formula > extract(PathFormula const &f, ApToFormulaMap &extractedFormulas)
Finds state subformulae in f and replaces them by atomic propositions.
std::map< std::string, std::shared_ptr< Formula const > > ApToFormulaMap
boost::any accept(FormulaVisitor const &visitor) const
Definition Formula.cpp:17
Formula const & getSubformula() const
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39