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(TimeOperatorFormula const& f, boost::any const& data) const {
148 incrementNestingLevel();
149 boost::any result = CloneVisitor::visit(f, data);
150 decrementNestingLevel();
151 return result;
152}
153
154boost::any ExtractMaximalStateFormulasVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
155 incrementNestingLevel();
156 boost::any result = CloneVisitor::visit(f, data);
157 decrementNestingLevel();
158 return result;
159}
160
161boost::any ExtractMaximalStateFormulasVisitor::visit(MultiObjectiveFormula const& f, boost::any const& data) const {
162 incrementNestingLevel();
163 boost::any result = CloneVisitor::visit(f, data);
164 decrementNestingLevel();
165 return result;
166}
167
168boost::any ExtractMaximalStateFormulasVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
169 incrementNestingLevel();
170 boost::any result = CloneVisitor::visit(f, data);
171 decrementNestingLevel();
172 return result;
173}
174
175boost::any ExtractMaximalStateFormulasVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const {
176 incrementNestingLevel();
177 boost::any result = CloneVisitor::visit(f, data);
178 decrementNestingLevel();
179 return result;
180}
181
182std::shared_ptr<Formula> ExtractMaximalStateFormulasVisitor::extract(std::shared_ptr<Formula> f) const {
183 // We use the string representation of formulae to check if they are equivalent.
184 // Of course, this could be made more elegant if there were an actual operator< and/or operator== for formulae
185
186 std::string label;
187
188 // Find equivalent formula in cache
189 auto it = cachedFormulas.find(f->toString());
190 if (it != cachedFormulas.end()) {
191 // Reuse label of equivalent formula
192 label = it->second;
193 } else {
194 // Create new label
195 label = "p" + std::to_string(extractedFormulas.size());
196 extractedFormulas[label] = f;
197 // Update cache
198 cachedFormulas[f->toString()] = label;
199 }
200
201 return std::make_shared<storm::logic::AtomicLabelFormula>(label);
202}
203
204void ExtractMaximalStateFormulasVisitor::incrementNestingLevel() const {
205 const_cast<std::size_t&>(nestingLevel)++;
206}
207void ExtractMaximalStateFormulasVisitor::decrementNestingLevel() const {
208 STORM_LOG_ASSERT(nestingLevel > 0, "Illegal nesting level decrement.");
209 const_cast<std::size_t&>(nestingLevel)--;
210}
211
212} // namespace logic
213} // 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:16
Formula const & getSubformula() const
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28