Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ToCppVisitor.cpp
Go to the documentation of this file.
2
4
6
9
10namespace storm {
11namespace expressions {
12
13ToCppTranslationOptions::ToCppTranslationOptions(std::unordered_map<storm::expressions::Variable, std::string> const& prefixes,
14 std::unordered_map<storm::expressions::Variable, std::string> const& names, ToCppTranslationMode mode)
15 : prefixes(prefixes), names(names), mode(mode) {
16 // Intentionally left empty.
17}
18
19std::unordered_map<storm::expressions::Variable, std::string> const& ToCppTranslationOptions::getPrefixes() const {
20 return prefixes.get();
21}
22
23std::unordered_map<storm::expressions::Variable, std::string> const& ToCppTranslationOptions::getNames() const {
24 return names.get();
25}
26
28 return mode;
29}
30
32 expression.accept(*this, options);
33 std::string result = stream.str();
34 stream.str("");
35 return result;
36}
37
38boost::any ToCppVisitor::visit(IfThenElseExpression const& expression, boost::any const& data) {
39 ToCppTranslationOptions const& options = boost::any_cast<ToCppTranslationOptions>(data);
40
41 // Clear the type cast for the condition.
42 ToCppTranslationOptions conditionOptions(options.getPrefixes(), options.getNames());
43 stream << "(";
44 expression.getCondition()->accept(*this, conditionOptions);
45 stream << " ? ";
46 expression.getThenExpression()->accept(*this, data);
47 stream << " : ";
48 expression.getElseExpression()->accept(*this, data);
49 stream << ")";
50 return boost::none;
51}
52
53boost::any ToCppVisitor::visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) {
54 ToCppTranslationOptions newOptions = boost::any_cast<ToCppTranslationOptions>(data);
55
56 switch (expression.getOperatorType()) {
58 stream << "(";
59 expression.getFirstOperand()->accept(*this, newOptions);
60 stream << " && ";
61 expression.getSecondOperand()->accept(*this, newOptions);
62 stream << ")";
63 break;
65 stream << "(";
66 expression.getFirstOperand()->accept(*this, newOptions);
67 stream << " || ";
68 expression.getSecondOperand()->accept(*this, newOptions);
69 stream << ")";
70 break;
72 stream << "(";
73 expression.getFirstOperand()->accept(*this, newOptions);
74 stream << " ^ ";
75 expression.getSecondOperand()->accept(*this, newOptions);
76 stream << ")";
77 break;
79 stream << "(!";
80 expression.getFirstOperand()->accept(*this, newOptions);
81 stream << " || ";
82 expression.getSecondOperand()->accept(*this, newOptions);
83 stream << ")";
84 break;
86 stream << "!(";
87 expression.getFirstOperand()->accept(*this, newOptions);
88 stream << " ^ ";
89 expression.getSecondOperand()->accept(*this, newOptions);
90 stream << ")";
91 break;
92 }
93 return boost::none;
94}
95
96boost::any ToCppVisitor::visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) {
97 switch (expression.getOperatorType()) {
99 stream << "(";
100 expression.getFirstOperand()->accept(*this, data);
101 stream << " + ";
102 expression.getSecondOperand()->accept(*this, data);
103 stream << ")";
104 break;
106 stream << "(";
107 expression.getFirstOperand()->accept(*this, data);
108 stream << " - ";
109 expression.getSecondOperand()->accept(*this, data);
110 stream << ")";
111 break;
113 stream << "(";
114 expression.getFirstOperand()->accept(*this, data);
115 stream << " * ";
116 expression.getSecondOperand()->accept(*this, data);
117 stream << ")";
118 break;
120 stream << "(";
121 expression.getFirstOperand()->accept(*this, data);
122 stream << " / ";
123 expression.getSecondOperand()->accept(*this, data);
124 stream << ")";
125 break;
127 stream << "std::min(";
128 expression.getFirstOperand()->accept(*this, data);
129 stream << ", ";
130 expression.getSecondOperand()->accept(*this, data);
131 stream << ")";
132 break;
134 stream << "std::max(";
135 expression.getFirstOperand()->accept(*this, data);
136 stream << ", ";
137 expression.getSecondOperand()->accept(*this, data);
138 stream << ")";
139 break;
141 stream << "std::pow(";
142 expression.getFirstOperand()->accept(*this, data);
143 stream << ", ";
144 expression.getSecondOperand()->accept(*this, data);
145 stream << ")";
146 break;
148 stream << "(";
149 expression.getFirstOperand()->accept(*this, data);
150 stream << " % ";
151 expression.getSecondOperand()->accept(*this, data);
152 stream << ")";
153 break;
155 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Log expressions not implemented for C++ translation.");
156 }
157 return boost::none;
158}
159
160boost::any ToCppVisitor::visit(BinaryRelationExpression const& expression, boost::any const& data) {
161 ToCppTranslationOptions newOptions = boost::any_cast<ToCppTranslationOptions>(data);
162
163 switch (expression.getRelationType()) {
165 stream << "(";
166 expression.getFirstOperand()->accept(*this, newOptions);
167 stream << " == ";
168 expression.getSecondOperand()->accept(*this, newOptions);
169 stream << ")";
170 break;
172 stream << "(";
173 expression.getFirstOperand()->accept(*this, newOptions);
174 stream << " != ";
175 expression.getSecondOperand()->accept(*this, newOptions);
176 stream << ")";
177 break;
179 stream << "(";
180 expression.getFirstOperand()->accept(*this, newOptions);
181 stream << " < ";
182 expression.getSecondOperand()->accept(*this, newOptions);
183 stream << ")";
184 break;
186 stream << "(";
187 expression.getFirstOperand()->accept(*this, newOptions);
188 stream << " <= ";
189 expression.getSecondOperand()->accept(*this, newOptions);
190 stream << ")";
191 break;
193 stream << "(";
194 expression.getFirstOperand()->accept(*this, newOptions);
195 stream << " > ";
196 expression.getSecondOperand()->accept(*this, newOptions);
197 stream << ")";
198 break;
200 stream << "(";
201 expression.getFirstOperand()->accept(*this, newOptions);
202 stream << " >= ";
203 expression.getSecondOperand()->accept(*this, newOptions);
204 stream << ")";
205 break;
206 }
207 return boost::none;
208}
209
210std::string getVariableName(storm::expressions::Variable const& variable, std::unordered_map<storm::expressions::Variable, std::string> const& prefixes,
211 std::unordered_map<storm::expressions::Variable, std::string> const& names) {
212 auto prefixIt = prefixes.find(variable);
213 if (prefixIt != prefixes.end()) {
214 auto nameIt = names.find(variable);
215 if (nameIt != names.end()) {
216 return prefixIt->second + nameIt->second;
217 } else {
218 return prefixIt->second + variable.getName();
219 }
220 } else {
221 auto nameIt = names.find(variable);
222 if (nameIt != names.end()) {
223 return nameIt->second;
224 } else {
225 return variable.getName();
226 }
227 }
228}
229
230boost::any ToCppVisitor::visit(VariableExpression const& expression, boost::any const& data) {
231 ToCppTranslationOptions const& options = boost::any_cast<ToCppTranslationOptions const&>(data);
232 storm::expressions::Variable const& variable = expression.getVariable();
233 std::string variableName = getVariableName(variable, options.getPrefixes(), options.getNames());
234
235 if (variable.hasBooleanType()) {
236 stream << variableName;
237 } else {
238 switch (options.getMode()) {
240 stream << variableName;
241 break;
243 stream << "static_cast<double>(" << variableName << ")";
244 break;
246 stream << "carl::rationalize<storm::RationalNumber>(" << variableName << ")";
247 break;
249 // Here, we rely on the variable name mapping to a rational function representing the variable being available.
250 stream << variableName;
251 break;
252 }
253 }
254 return boost::none;
255}
256
257boost::any ToCppVisitor::visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) {
258 ToCppTranslationOptions newOptions = boost::any_cast<ToCppTranslationOptions>(data);
259
260 switch (expression.getOperatorType()) {
262 stream << "!(";
263 expression.getOperand()->accept(*this, newOptions);
264 stream << ")";
265 break;
266 }
267 return boost::none;
268}
269
270boost::any ToCppVisitor::visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) {
271 ToCppTranslationOptions const& options = boost::any_cast<ToCppTranslationOptions const&>(data);
272 switch (expression.getOperatorType()) {
274 stream << "-(";
275 expression.getOperand()->accept(*this, data);
276 stream << ")";
277 break;
279 STORM_LOG_THROW(options.getMode() != ToCppTranslationMode::CastRationalFunction, storm::exceptions::NotSupportedException,
280 "Floor is not supported by rational functions.");
282 stream << "std::floor";
283 } else {
284 stream << "carl::floor";
285 }
286 stream << "(";
287 expression.getOperand()->accept(*this, data);
288 stream << ")";
289 break;
291 STORM_LOG_THROW(options.getMode() != ToCppTranslationMode::CastRationalFunction, storm::exceptions::NotSupportedException,
292 "Ceil is not supported by rational functions.");
294 stream << "std::ceil";
295 } else {
296 stream << "carl::ceil";
297 }
298 stream << "(";
299 expression.getOperand()->accept(*this, data);
300 stream << ")";
301 break;
302 }
303 return boost::none;
304}
305
306boost::any ToCppVisitor::visit(BooleanLiteralExpression const& expression, boost::any const&) {
307 stream << std::boolalpha << expression.getValue();
308 return boost::none;
309}
310
311boost::any ToCppVisitor::visit(IntegerLiteralExpression const& expression, boost::any const& data) {
312 ToCppTranslationOptions const& options = boost::any_cast<ToCppTranslationOptions const&>(data);
313 switch (options.getMode()) {
315 stream << expression.getValue();
316 break;
318 stream << "static_cast<double>(" << expression.getValue() << ")";
319 break;
321 stream << "carl::rationalize<storm::RationalNumber>(\"" << expression.getValue() << "\")";
322 break;
324 stream << "storm::RationalFunction(carl::rationalize<storm::RationalNumber>(\"" << expression.getValue() << "\"))";
325 break;
326 }
327 return boost::none;
328}
329
330boost::any ToCppVisitor::visit(RationalLiteralExpression const& expression, boost::any const& data) {
331 ToCppTranslationOptions const& options = boost::any_cast<ToCppTranslationOptions const&>(data);
332 switch (options.getMode()) {
334 stream << "(static_cast<double>(" << carl::getNum(expression.getValue()) << ")/" << carl::getDenom(expression.getValue()) << ")";
335 break;
337 stream << "static_cast<double>(" << expression.getValueAsDouble() << ")";
338 break;
340 stream << "carl::rationalize<storm::RationalNumber>(\"" << expression.getValue() << "\")";
341 break;
343 stream << "storm::RationalFunction(carl::rationalize<storm::RationalNumber>(\"" << expression.getValue() << "\"))";
344 break;
345 }
346 return boost::none;
347}
348
349} // namespace expressions
350} // namespace storm
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
std::shared_ptr< BaseExpression const > const & getSecondOperand() const
Retrieves the second operand of the expression.
std::shared_ptr< BaseExpression const > const & getFirstOperand() const
Retrieves the first operand of the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with the expression.
RelationType getRelationType() const
Retrieves the relation associated with the expression.
bool getValue() const
Retrieves the value of the boolean literal.
boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const
Accepts the given visitor.
std::shared_ptr< BaseExpression const > getElseExpression() const
Retrieves the else expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getCondition() const
Retrieves the condition expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getThenExpression() const
Retrieves the then expression of the if-then-else expression.
int_fast64_t getValue() const
Retrieves the value of the integer literal.
double getValueAsDouble() const
Retrieves the value of the double literal.
storm::RationalNumber getValue() const
Retrieves the value of the double literal.
ToCppTranslationOptions(std::unordered_map< storm::expressions::Variable, std::string > const &prefixes, std::unordered_map< storm::expressions::Variable, std::string > const &names, ToCppTranslationMode mode=ToCppTranslationMode::KeepType)
std::unordered_map< storm::expressions::Variable, std::string > const & getNames() const
std::unordered_map< storm::expressions::Variable, std::string > const & getPrefixes() const
ToCppTranslationMode const & getMode() const
virtual boost::any visit(IfThenElseExpression const &expression, boost::any const &data) override
std::string translate(storm::expressions::Expression const &expression, ToCppTranslationOptions const &options)
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
OperatorType getOperatorType() const
Retrieves the operator associated with this expression.
Variable const & getVariable() const
Retrieves the variable associated with this expression.
bool hasBooleanType() const
Checks whether the variable is of boolean type.
Definition Variable.cpp:59
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:46
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
std::string getVariableName(storm::expressions::Variable const &variable, std::unordered_map< storm::expressions::Variable, std::string > const &prefixes, std::unordered_map< storm::expressions::Variable, std::string > const &names)
LabParser.cpp.
Definition cli.cpp:18