#include "storm/storage/jani/expressions/JaniReduceNestingExpressionVisitor.h" #include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace jani { storm::expressions::Expression reduceNestingInJaniExpression(storm::expressions::Expression const& expression) { return storm::expressions::JaniReduceNestingExpressionVisitor().reduceNesting(expression); } } namespace expressions { JaniReduceNestingExpressionVisitor::JaniReduceNestingExpressionVisitor() : ReduceNestingVisitor() { // Intentionally left empty. } boost::any JaniReduceNestingExpressionVisitor::visit(ValueArrayExpression const& expression, boost::any const& data) { uint64_t size = expression.size()->evaluateAsInt(); std::vector> newElements; newElements.reserve(size); for (uint64_t i = 0; i < size; ++i) { newElements.push_back(boost::any_cast>(expression.at(i)->accept(*this, data))); } return std::const_pointer_cast(std::shared_ptr(new ValueArrayExpression(expression.getManager(), expression.getType(), newElements))); } boost::any JaniReduceNestingExpressionVisitor::visit(ConstructorArrayExpression const& expression, boost::any const& data) { std::shared_ptr newSize = boost::any_cast>(expression.size()->accept(*this, data)); std::shared_ptr elementExpression = boost::any_cast>(expression.getElementExpression()->accept(*this, data)); // If the arguments did not change, we simply push the expression itself. if (newSize.get() == expression.size().get() && elementExpression.get() == expression.getElementExpression().get()) { return expression.getSharedPointer(); } else { return std::const_pointer_cast(std::shared_ptr(new ConstructorArrayExpression(expression.getManager(), expression.getType(), newSize, expression.getIndexVar(), elementExpression))); } } boost::any JaniReduceNestingExpressionVisitor::visit(ArrayAccessExpression 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 ArrayAccessExpression(expression.getManager(), expression.getType(), firstExpression, secondExpression))); } } boost::any JaniReduceNestingExpressionVisitor::visit(FunctionCallExpression const& expression, boost::any const& data) { std::vector> newArguments; newArguments.reserve(expression.getNumberOfArguments()); for (uint64_t i = 0; i < expression.getNumberOfArguments(); ++i) { newArguments.push_back(boost::any_cast>(expression.getArgument(i)->accept(*this, data))); } return std::const_pointer_cast(std::shared_ptr(new FunctionCallExpression(expression.getManager(), expression.getType(), expression.getFunctionIdentifier(), newArguments))); } } }