#include "src/storage/expressions/ToRationalFunctionVisitor.h" #include #include "src/utility/macros.h" #include "src/exceptions/InvalidArgumentException.h" namespace storm { namespace expressions { #ifdef STORM_HAVE_CARL template ToRationalFunctionVisitor::ToRationalFunctionVisitor() : ExpressionVisitor(), cache(new carl::Cache>()) { // Intentionally left empty. } template RationalFunctionType ToRationalFunctionVisitor::toRationalFunction(Expression const& expression) { return boost::any_cast(expression.accept(*this)); } template boost::any ToRationalFunctionVisitor::visit(IfThenElseExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template boost::any ToRationalFunctionVisitor::visit(BinaryBooleanFunctionExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template boost::any ToRationalFunctionVisitor::visit(BinaryNumericalFunctionExpression const& expression) { RationalFunctionType firstOperandAsRationalFunction = boost::any_cast(expression.getFirstOperand()->accept(*this)); RationalFunctionType secondOperandAsRationalFunction = boost::any_cast(expression.getSecondOperand()->accept(*this)); switch(expression.getOperatorType()) { case BinaryNumericalFunctionExpression::OperatorType::Plus: return firstOperandAsRationalFunction + secondOperandAsRationalFunction; break; case BinaryNumericalFunctionExpression::OperatorType::Minus: return firstOperandAsRationalFunction - secondOperandAsRationalFunction; break; case BinaryNumericalFunctionExpression::OperatorType::Times: return firstOperandAsRationalFunction * secondOperandAsRationalFunction; break; case BinaryNumericalFunctionExpression::OperatorType::Divide: return firstOperandAsRationalFunction / secondOperandAsRationalFunction; break; default: STORM_LOG_ASSERT(false, "Illegal operator type."); } // Return a dummy. This point must, however, never be reached. return boost::any(); } template boost::any ToRationalFunctionVisitor::visit(BinaryRelationExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template boost::any ToRationalFunctionVisitor::visit(VariableExpression const& expression) { auto variablePair = variableToVariableMap.find(expression.getVariable()); if (variablePair != variableToVariableMap.end()) { return convertVariableToPolynomial(variablePair->second); } else { carl::Variable carlVariable = carl::freshRealVariable(expression.getVariableName()); variableToVariableMap.emplace(expression.getVariable(), carlVariable); return convertVariableToPolynomial(carlVariable); } } template boost::any ToRationalFunctionVisitor::visit(UnaryBooleanFunctionExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template boost::any ToRationalFunctionVisitor::visit(UnaryNumericalFunctionExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template boost::any ToRationalFunctionVisitor::visit(BooleanLiteralExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template boost::any ToRationalFunctionVisitor::visit(IntegerLiteralExpression const& expression) { return RationalFunctionType(carl::rationalize(static_cast(expression.getValue()))); } template boost::any ToRationalFunctionVisitor::visit(DoubleLiteralExpression const& expression) { return RationalFunctionType(carl::rationalize(expression.getValue())); } template class ToRationalFunctionVisitor; #endif } }