Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
ToRationalFunctionVisitor.cpp
Go to the documentation of this file.
2
3#include <sstream>
4
9
10namespace storm {
11namespace expressions {
12
13#ifdef STORM_HAVE_CARL
14template<typename RationalFunctionType>
15ToRationalFunctionVisitor<RationalFunctionType>::ToRationalFunctionVisitor(ExpressionEvaluatorBase<RationalFunctionType> const& evaluator)
16 : ExpressionVisitor(), cache(new storm::RawPolynomialCache()), evaluator(evaluator) {
17 // Intentionally left empty.
18}
19
20template<typename RationalFunctionType>
21RationalFunctionType ToRationalFunctionVisitor<RationalFunctionType>::toRationalFunction(Expression const& expression) {
22 return boost::any_cast<RationalFunctionType>(expression.accept(*this, boost::none));
23}
24
25template<typename RationalFunctionType>
26boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IfThenElseExpression const& expression, boost::any const& data) {
27 bool conditionValue = evaluator.asBool(expression.getCondition());
28 if (conditionValue) {
29 return expression.getThenExpression()->accept(*this, data);
30 } else {
31 return expression.getElseExpression()->accept(*this, data);
32 }
33}
34
35template<typename RationalFunctionType>
36boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryBooleanFunctionExpression const&, boost::any const&) {
37 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
38}
39
40template<typename RationalFunctionType>
41boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) {
42 RationalFunctionType firstOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getFirstOperand()->accept(*this, data));
43 RationalFunctionType secondOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getSecondOperand()->accept(*this, data));
44 switch (expression.getOperatorType()) {
45 case BinaryNumericalFunctionExpression::OperatorType::Plus:
46 return firstOperandAsRationalFunction + secondOperandAsRationalFunction;
47 case BinaryNumericalFunctionExpression::OperatorType::Minus:
48 return firstOperandAsRationalFunction - secondOperandAsRationalFunction;
49 case BinaryNumericalFunctionExpression::OperatorType::Times:
50 return firstOperandAsRationalFunction * secondOperandAsRationalFunction;
51 case BinaryNumericalFunctionExpression::OperatorType::Divide:
52 return firstOperandAsRationalFunction / secondOperandAsRationalFunction;
53 case BinaryNumericalFunctionExpression::OperatorType::Power: {
54 STORM_LOG_THROW(storm::utility::isInteger(secondOperandAsRationalFunction), storm::exceptions::InvalidArgumentException,
55 "Exponent of power operator must be an integer but is " << secondOperandAsRationalFunction << ".");
56 auto exponentAsInteger = storm::utility::convertNumber<carl::sint>(secondOperandAsRationalFunction);
57 return storm::utility::pow(firstOperandAsRationalFunction, exponentAsInteger);
58 }
59 default:
60 STORM_LOG_ASSERT(false, "Illegal operator type " << expression.getOperator() << " in expression" << expression << ".");
61 }
62
63 // Return a dummy. This point must, however, never be reached.
64 return boost::any();
65}
66
67template<typename RationalFunctionType>
68boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryRelationExpression const&, boost::any const&) {
69 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
70}
71
72template<typename RationalFunctionType>
73boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(VariableExpression const& expression, boost::any const&) {
74 auto valueIt = valueMapping.find(expression.getVariable());
75 if (valueIt != valueMapping.end()) {
76 return valueIt->second;
77 }
78
79 auto variablePair = variableToVariableMap.find(expression.getVariable());
80 if (variablePair != variableToVariableMap.end()) {
81 return convertVariableToPolynomial(variablePair->second);
82 } else {
83 storm::RationalFunctionVariable carlVariable = storm::createRFVariable(expression.getVariableName());
84 variableToVariableMap.emplace(expression.getVariable(), carlVariable);
85 return convertVariableToPolynomial(carlVariable);
86 }
87}
88
89template<typename RationalFunctionType>
90boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryBooleanFunctionExpression const&, boost::any const&) {
91 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
92}
93
94template<typename RationalFunctionType>
95boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) {
96 RationalFunctionType operandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getOperand()->accept(*this, data));
97 switch (expression.getOperatorType()) {
98 case UnaryNumericalFunctionExpression::OperatorType::Minus:
99 return -operandAsRationalFunction;
100 default:
101 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
102 }
103 return boost::any();
104}
105
106template<typename RationalFunctionType>
107boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BooleanLiteralExpression const&, boost::any const&) {
108 STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function.");
109}
110
111template<typename RationalFunctionType>
112boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IntegerLiteralExpression const& expression, boost::any const&) {
113 return RationalFunctionType(storm::utility::convertNumber<storm::RationalFunction>(expression.getValue()));
114}
115
116template<typename RationalFunctionType>
117boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(RationalLiteralExpression const& expression, boost::any const&) {
118 return storm::utility::convertNumber<storm::RationalFunction>(expression.getValue());
119}
120
121template<typename RationalFunctionType>
122void ToRationalFunctionVisitor<RationalFunctionType>::setMapping(storm::expressions::Variable const& variable, RationalFunctionType const& value) {
123 valueMapping[variable] = value;
124}
125
126template class ToRationalFunctionVisitor<storm::RationalFunction>;
127#endif
128} // namespace expressions
129} // namespace storm
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
bool isInteger(ValueType const &number)
Definition constants.cpp:76
ValueType pow(ValueType const &value, int_fast64_t exponent)
LabParser.cpp.
Definition cli.cpp:18
carl::Cache< carl::PolynomialFactorizationPair< RawPolynomial > > RawPolynomialCache
RationalFunctionVariable createRFVariable(std::string const &name)
carl::Variable RationalFunctionVariable