#include "src/storage/expressions/ToRationalFunctionVisitor.h" #include <sstream> #include "src/utility/macros.h" #ifdef STORM_HAVE_CARL namespace storm { namespace expressions { template<typename RationalFunctionType> ToRationalFunctionVisitor<RationalFunctionType>::ToRationalFunctionVisitor() : ExpressionVisitor(), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>()) { // Intentionally left empty. } template<typename RationalFunctionType> RationalFunctionType ToRationalFunctionVisitor<RationalFunctionType>::toRationalFunction(Expression const& expression) { return boost::any_cast<RationalFunctionType>(expression.accept(*this)); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IfThenElseExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryBooleanFunctionExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryNumericalFunctionExpression const& expression) { RationalFunctionType firstOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getFirstOperand()->accept(*this)); RationalFunctionType secondOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(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<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryRelationExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(VariableExpression const& expression) { auto variablePair = variableToVariableMap.find(expression.getVariable()); if (variablePair != variableToVariableMap.end()) { return convertVariableToPolynomial(variablePair->second); } else { carl::Variable carlVariable = carl::VariablePool::getInstance().getFreshVariable(expression.getVariableName()); variableToVariableMap.emplace(expression.getVariable(), carlVariable); return convertVariableToPolynomial(carlVariable); } } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryBooleanFunctionExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryNumericalFunctionExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BooleanLiteralExpression const& expression) { STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IntegerLiteralExpression const& expression) { return RationalFunctionType(carl::rationalize<storm::RationalNumber>(static_cast<size_t>(expression.getValue()))); } template<typename RationalFunctionType> boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(DoubleLiteralExpression const& expression) { return RationalFunctionType(carl::rationalize<storm::RationalNumber>(expression.getValue())); } template class ToRationalFunctionVisitor<storm::RationalFunction>; } } #endif