diff --git a/src/parser/ExpressionParser.cpp b/src/parser/ExpressionParser.cpp index e879994f6..bb143a2c0 100644 --- a/src/parser/ExpressionParser.cpp +++ b/src/parser/ExpressionParser.cpp @@ -27,7 +27,10 @@ namespace storm { unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_1)]; unaryExpression.name("unary expression"); - multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]); + powerExpression = unaryExpression[qi::_val = qi::_1] >> -(qi::lit("^") > expression)[qi::_val = phoenix::bind(&ExpressionParser::createPowerExpression, phoenix::ref(*this), qi::_val, qi::_1)]; + powerExpression.name("power expression"); + + multiplicationExpression = powerExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> powerExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]); multiplicationExpression.name("multiplication expression"); plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]]; @@ -69,12 +72,18 @@ namespace storm { } void ExpressionParser::setIdentifierMapping(qi::symbols const* identifiers_) { - this->createExpressions = true; - this->identifiers_ = identifiers_; + if (identifiers_ != nullptr) { + this->createExpressions = true; + this->identifiers_ = identifiers_; + } else { + this->createExpressions = false; + this->identifiers_ = nullptr; + } } void ExpressionParser::unsetIdentifierMapping() { this->createExpressions = false; + this->identifiers_ = nullptr; } void ExpressionParser::setAcceptDoubleLiterals(bool flag) { @@ -86,7 +95,7 @@ namespace storm { try { return e1.ite(e2, e3); } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -98,7 +107,7 @@ namespace storm { try { return e1.implies(e2); } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -110,7 +119,7 @@ namespace storm { try { return e1 || e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -122,7 +131,7 @@ namespace storm { try{ return e1 && e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -134,7 +143,7 @@ namespace storm { try { return e1 > e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -146,7 +155,7 @@ namespace storm { try { return e1 >= e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -158,7 +167,7 @@ namespace storm { try { return e1 < e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -170,7 +179,7 @@ namespace storm { try { return e1 <= e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -186,7 +195,7 @@ namespace storm { return e1 == e2; } } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -196,13 +205,9 @@ namespace storm { storm::expressions::Expression ExpressionParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const { if (this->createExpressions) { try { - if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) { - return e1 ^ e2; - } else { - return e1 != e2; - } + return e1 != e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -214,7 +219,7 @@ namespace storm { try { return e1 + e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -226,7 +231,7 @@ namespace storm { try { return e1 - e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -238,7 +243,19 @@ namespace storm { try { return e1 * e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); + } + } else { + return storm::expressions::Expression::createFalse(); + } + } + + storm::expressions::Expression ExpressionParser::createPowerExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const { + if (this->createExpressions) { + try { + return e1 ^ e2; + } catch (storm::exceptions::InvalidTypeException const& e) { + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -250,7 +267,7 @@ namespace storm { try { return e1 / e2; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -262,7 +279,7 @@ namespace storm { try { return !e1; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -274,7 +291,7 @@ namespace storm { try { return -e1; } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -308,9 +325,9 @@ namespace storm { storm::expressions::Expression ExpressionParser::createIntegerLiteralExpression(int value) const { if (this->createExpressions) { - return storm::expressions::Expression::createFalse(); - } else { return storm::expressions::Expression::createIntegerLiteral(static_cast(value)); + } else { + return storm::expressions::Expression::createFalse(); } } @@ -319,7 +336,7 @@ namespace storm { try { return storm::expressions::Expression::minimum(e1, e2); } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -331,7 +348,7 @@ namespace storm { try { return storm::expressions::Expression::maximum(e1, e2); } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -343,7 +360,7 @@ namespace storm { try { return e1.floor(); } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -355,7 +372,7 @@ namespace storm { try { return e1.ceil(); } catch (storm::exceptions::InvalidTypeException const& e) { - LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what() << "."); + LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what()); } } else { return storm::expressions::Expression::createFalse(); @@ -364,11 +381,12 @@ namespace storm { storm::expressions::Expression ExpressionParser::getIdentifierExpression(std::string const& identifier) const { if (this->createExpressions) { - return storm::expressions::Expression::createFalse(); - } else { + LOG_THROW(this->identifiers_ != nullptr, storm::exceptions::WrongFormatException, "Unable to substitute identifier expressions without given mapping."); storm::expressions::Expression const* expression = this->identifiers_->find(identifier); LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'."); return *expression; + } else { + return storm::expressions::Expression::createFalse(); } } diff --git a/src/parser/ExpressionParser.h b/src/parser/ExpressionParser.h index c340f9c14..380644caf 100644 --- a/src/parser/ExpressionParser.h +++ b/src/parser/ExpressionParser.h @@ -66,6 +66,7 @@ namespace storm { qi::rule, Skipper> equalityExpression; qi::rule, Skipper> plusExpression; qi::rule, Skipper> multiplicationExpression; + qi::rule, Skipper> powerExpression; qi::rule unaryExpression; qi::rule atomicExpression; qi::rule literalExpression; @@ -91,6 +92,7 @@ namespace storm { storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const; storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const; storm::expressions::Expression createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const; + storm::expressions::Expression createPowerExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const; storm::expressions::Expression createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const; storm::expressions::Expression createNotExpression(storm::expressions::Expression e1) const; storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1) const; diff --git a/src/parser/PrismParser.cpp b/src/parser/PrismParser.cpp index 5e64ca8eb..b026880d3 100644 --- a/src/parser/PrismParser.cpp +++ b/src/parser/PrismParser.cpp @@ -189,6 +189,7 @@ namespace storm { void PrismParser::moveToSecondRun() { this->secondRun = true; + this->expressionParser.setIdentifierMapping(&this->identifiers_); } void PrismParser::allowDoubleLiterals(bool flag) { diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp index f6172821d..7db4fa0cf 100644 --- a/src/storage/expressions/BinaryNumericalFunctionExpression.cpp +++ b/src/storage/expressions/BinaryNumericalFunctionExpression.cpp @@ -1,4 +1,5 @@ #include +#include #include "src/storage/expressions/BinaryNumericalFunctionExpression.h" #include "src/exceptions/ExceptionMacros.h" @@ -22,6 +23,7 @@ namespace storm { case OperatorType::Divide: return storm::expressions::OperatorType::Divide; break; case OperatorType::Min: return storm::expressions::OperatorType::Min; break; case OperatorType::Max: return storm::expressions::OperatorType::Max; break; + case OperatorType::Power: return storm::expressions::OperatorType::Power; break; } } @@ -37,6 +39,7 @@ namespace storm { case OperatorType::Divide: return firstOperandEvaluation / secondOperandEvaluation; break; case OperatorType::Min: return std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: return std::max(firstOperandEvaluation, secondOperandEvaluation); break; + case OperatorType::Power: return static_cast(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break; } } @@ -52,6 +55,7 @@ namespace storm { case OperatorType::Divide: return static_cast(firstOperandEvaluation / secondOperandEvaluation); break; case OperatorType::Min: return static_cast(std::min(firstOperandEvaluation, secondOperandEvaluation)); break; case OperatorType::Max: return static_cast(std::max(firstOperandEvaluation, secondOperandEvaluation)); break; + case OperatorType::Power: return std::pow(firstOperandEvaluation, secondOperandEvaluation); break; } } @@ -79,6 +83,7 @@ namespace storm { case OperatorType::Divide: stream << *this->getFirstOperand() << " / " << *this->getSecondOperand(); break; case OperatorType::Min: stream << "min(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break; case OperatorType::Max: stream << "max(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break; + case OperatorType::Power: stream << *this->getFirstOperand() << " ^ " << *this->getSecondOperand(); break; } stream << ")"; } diff --git a/src/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storage/expressions/BinaryNumericalFunctionExpression.h index 13ee489df..77b8021a4 100644 --- a/src/storage/expressions/BinaryNumericalFunctionExpression.h +++ b/src/storage/expressions/BinaryNumericalFunctionExpression.h @@ -11,7 +11,7 @@ namespace storm { /*! * An enum type specifying the different operators applicable. */ - enum class OperatorType {Plus, Minus, Times, Divide, Min, Max}; + enum class OperatorType {Plus, Minus, Times, Divide, Min, Max, Power}; /*! * Constructs a binary numerical function expression with the given return type, operands and operator. diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp index e8de2af62..2c247f796 100644 --- a/src/storage/expressions/Expression.cpp +++ b/src/storage/expressions/Expression.cpp @@ -196,8 +196,8 @@ namespace storm { } Expression Expression::operator^(Expression const& other) const { - LOG_THROW(this->hasBooleanReturnType() && other.hasBooleanReturnType(), storm::exceptions::InvalidTypeException, "Operator '^' requires boolean operands."); - return Expression(std::shared_ptr(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Xor))); + LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '^' requires numerical operands."); + return Expression(std::shared_ptr(new BinaryNumericalFunctionExpression(this->getReturnType() == ExpressionReturnType::Int && other.getReturnType() == ExpressionReturnType::Int ? ExpressionReturnType::Int : ExpressionReturnType::Double, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Power))); } Expression Expression::operator&&(Expression const& other) const { @@ -221,8 +221,12 @@ namespace storm { } Expression Expression::operator!=(Expression const& other) const { - LOG_THROW(this->hasNumericalReturnType() && other.hasNumericalReturnType(), storm::exceptions::InvalidTypeException, "Operator '!=' requires numerical operands."); - return Expression(std::shared_ptr(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::NotEqual))); + LOG_THROW((this->hasNumericalReturnType() && other.hasNumericalReturnType()) || (this->hasBooleanReturnType() && other.hasBooleanReturnType()), storm::exceptions::InvalidTypeException, "Operator '!=' requires operands of equal type."); + if (this->hasNumericalReturnType() && other.hasNumericalReturnType()) { + return Expression(std::shared_ptr(new BinaryRelationExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryRelationExpression::RelationType::NotEqual))); + } else { + return Expression(std::shared_ptr(new BinaryBooleanFunctionExpression(ExpressionReturnType::Bool, this->getBaseExpressionPointer(), other.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Xor))); + } } Expression Expression::operator>(Expression const& other) const { diff --git a/src/storage/expressions/OperatorType.h b/src/storage/expressions/OperatorType.h index 8a4f199aa..8968cf105 100644 --- a/src/storage/expressions/OperatorType.h +++ b/src/storage/expressions/OperatorType.h @@ -16,6 +16,7 @@ namespace storm { Divide, Min, Max, + Power, Equal, NotEqual, Less, diff --git a/test/functional/parser/PrismParserTest.cpp b/test/functional/parser/PrismParserTest.cpp index 5bf7bfd49..3621149b8 100644 --- a/test/functional/parser/PrismParserTest.cpp +++ b/test/functional/parser/PrismParserTest.cpp @@ -4,6 +4,7 @@ TEST(PrismParser, StandardModelTest) { storm::prism::Program result; + result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm"); EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm")); EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm")); EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm")); diff --git a/test/functional/storage/ExpressionTest.cpp b/test/functional/storage/ExpressionTest.cpp index d3a920d1d..642456995 100644 --- a/test/functional/storage/ExpressionTest.cpp +++ b/test/functional/storage/ExpressionTest.cpp @@ -223,10 +223,10 @@ TEST(Expression, OperatorTest) { ASSERT_NO_THROW(tempExpression = boolVarExpression.iff(boolVarExpression)); EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool); - ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException); - ASSERT_NO_THROW(tempExpression = trueExpression ^ falseExpression); + ASSERT_THROW(tempExpression = trueExpression != piExpression, storm::exceptions::InvalidTypeException); + ASSERT_NO_THROW(tempExpression = trueExpression != falseExpression); EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool); - ASSERT_NO_THROW(tempExpression = boolVarExpression ^ boolVarExpression); + ASSERT_NO_THROW(tempExpression = boolVarExpression != boolVarExpression); EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Bool); ASSERT_THROW(tempExpression = trueExpression.floor(), storm::exceptions::InvalidTypeException); @@ -240,6 +240,12 @@ TEST(Expression, OperatorTest) { EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int); ASSERT_NO_THROW(tempExpression = doubleVarExpression.ceil()); EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int); + + ASSERT_THROW(tempExpression = trueExpression ^ piExpression, storm::exceptions::InvalidTypeException); + ASSERT_NO_THROW(tempExpression = threeExpression ^ threeExpression); + EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Int); + ASSERT_NO_THROW(tempExpression = intVarExpression ^ doubleVarExpression); + EXPECT_TRUE(tempExpression.getReturnType() == storm::expressions::ExpressionReturnType::Double); } TEST(Expression, SubstitutionTest) {