#include #include #include #include "storm/storage/expressions/SimplificationVisitor.h" #include "storm/storage/expressions/Expressions.h" #include "storm/storage/expressions/PredicateExpression.h" #include "storm/storage/expressions/ExpressionManager.h" namespace storm { namespace expressions { SimplificationVisitor::SimplificationVisitor() { // Intentionally left empty. } Expression SimplificationVisitor::substitute(Expression const &expression) { return Expression(boost::any_cast>( expression.getBaseExpression().accept(*this, boost::none))); } boost::any SimplificationVisitor::visit(IfThenElseExpression const &expression, boost::any const &data) { std::shared_ptr conditionExpression = boost::any_cast>( expression.getCondition()->accept(*this, data)); std::shared_ptr thenExpression = boost::any_cast>( expression.getThenExpression()->accept(*this, data)); std::shared_ptr elseExpression = boost::any_cast>( expression.getElseExpression()->accept(*this, data)); // If the arguments did not change, we simply push the expression itself. if (conditionExpression.get() == expression.getCondition().get() && thenExpression.get() == expression.getThenExpression().get() && elseExpression.get() == expression.getElseExpression().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr( new IfThenElseExpression(expression.getManager(), expression.getType(), conditionExpression, thenExpression, elseExpression))); } } boost::any SimplificationVisitor::visit(BinaryBooleanFunctionExpression const &expression, boost::any const &data) { std::shared_ptr firstExpression = boost::any_cast>( expression.getFirstOperand()->accept(*this, data)); std::shared_ptr secondExpression = boost::any_cast>( expression.getSecondOperand()->accept(*this, data)); // If the arguments did not change, we simply push the expression itself. if (firstExpression.get() == expression.getFirstOperand().get() && secondExpression.get() == expression.getSecondOperand().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr( new BinaryBooleanFunctionExpression(expression.getManager(), expression.getType(), firstExpression, secondExpression, expression.getOperatorType()))); } } boost::any SimplificationVisitor::visit(BinaryNumericalFunctionExpression const &expression, boost::any const &data) { std::shared_ptr firstExpression = boost::any_cast>( expression.getFirstOperand()->accept(*this, data)); std::shared_ptr secondExpression = boost::any_cast>( expression.getSecondOperand()->accept(*this, data)); // If the arguments did not change, we simply push the expression itself. if (firstExpression.get() == expression.getFirstOperand().get() && secondExpression.get() == expression.getSecondOperand().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr( new BinaryNumericalFunctionExpression(expression.getManager(), expression.getType(), firstExpression, secondExpression, expression.getOperatorType()))); } } boost::any SimplificationVisitor::visit(BinaryRelationExpression const &expression, boost::any const &data) { std::shared_ptr firstExpression = boost::any_cast>( expression.getFirstOperand()->accept(*this, data)); std::shared_ptr secondExpression = boost::any_cast>( expression.getSecondOperand()->accept(*this, data)); // If the arguments did not change, we simply push the expression itself. if (firstExpression.get() == expression.getFirstOperand().get() && secondExpression.get() == expression.getSecondOperand().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr( new BinaryRelationExpression(expression.getManager(), expression.getType(), firstExpression, secondExpression, expression.getRelationType()))); } } boost::any SimplificationVisitor::visit(VariableExpression const &expression, boost::any const &) { return expression.getSharedPointer(); } boost::any SimplificationVisitor::visit(UnaryBooleanFunctionExpression const &expression, boost::any const &data) { std::shared_ptr operandExpression = boost::any_cast>( expression.getOperand()->accept(*this, data)); // If the argument did not change, we simply push the expression itself. if (operandExpression.get() == expression.getOperand().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr( new UnaryBooleanFunctionExpression(expression.getManager(), expression.getType(), operandExpression, expression.getOperatorType()))); } } boost::any SimplificationVisitor::visit(UnaryNumericalFunctionExpression const &expression, boost::any const &data) { std::shared_ptr operandExpression = boost::any_cast>( expression.getOperand()->accept(*this, data)); // If the argument did not change, we simply push the expression itself. if (operandExpression.get() == expression.getOperand().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr( new UnaryNumericalFunctionExpression(expression.getManager(), expression.getType(), operandExpression, expression.getOperatorType()))); } } boost::any SimplificationVisitor::visit(PredicateExpression const &expression, boost::any const &data) { std::vector newExpressions; for (uint64_t i = 0; i < expression.getArity(); ++i) { newExpressions.emplace_back(boost::any_cast>( expression.getOperand(i)->accept(*this, data))); } std::vector newSumExpressions; for (auto const &expr : newExpressions) { newSumExpressions.push_back( ite(expr, expression.getManager().integer(1), expression.getManager().integer(0))); } storm::expressions::Expression finalexpr; if (expression.getPredicateType() == PredicateExpression::PredicateType::AtLeastOneOf) { finalexpr = storm::expressions::sum(newSumExpressions) > expression.getManager().integer(0); } else if (expression.getPredicateType() == PredicateExpression::PredicateType::AtMostOneOf) { finalexpr = storm::expressions::sum(newSumExpressions) <= expression.getManager().integer(1); } else if (expression.getPredicateType() == PredicateExpression::PredicateType::ExactlyOneOf) { finalexpr = storm::expressions::sum(newSumExpressions) == expression.getManager().integer(1); } else { STORM_LOG_ASSERT(false, "Unknown predicate type."); } return std::const_pointer_cast(finalexpr.getBaseExpressionPointer()); } boost::any SimplificationVisitor::visit(BooleanLiteralExpression const &expression, boost::any const &) { return expression.getSharedPointer(); } boost::any SimplificationVisitor::visit(IntegerLiteralExpression const &expression, boost::any const &) { return expression.getSharedPointer(); } boost::any SimplificationVisitor::visit(RationalLiteralExpression const &expression, boost::any const &) { return expression.getSharedPointer(); } } }