#include #include #include #include "src/storage/expressions/SubstitutionVisitor.h" #include "src/storage/expressions/Expressions.h" namespace storm { namespace expressions { template SubstitutionVisitor::SubstitutionVisitor(MapType const& identifierToExpressionMap) : identifierToExpressionMap(identifierToExpressionMap) { // Intentionally left empty. } template Expression SubstitutionVisitor::substitute(BaseExpression const* expression) { expression->accept(this); return Expression(this->expressionStack.top()); } template void SubstitutionVisitor::visit(IfThenElseExpression const* expression) { expression->getCondition()->accept(this); std::shared_ptr conditionExpression = expressionStack.top(); expressionStack.pop(); expression->getThenExpression()->accept(this); std::shared_ptr thenExpression = expressionStack.top(); expressionStack.pop(); expression->getElseExpression()->accept(this); std::shared_ptr elseExpression = expressionStack.top(); expressionStack.pop(); // 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()) { this->expressionStack.push(expression->getSharedPointer()); } else { this->expressionStack.push(std::shared_ptr(new IfThenElseExpression(expression->getReturnType(), conditionExpression, thenExpression, elseExpression))); } } template void SubstitutionVisitor::visit(BinaryBooleanFunctionExpression const* expression) { expression->getFirstOperand()->accept(this); std::shared_ptr firstExpression = expressionStack.top(); expressionStack.pop(); expression->getSecondOperand()->accept(this); std::shared_ptr secondExpression = expressionStack.top(); expressionStack.pop(); // If the arguments did not change, we simply push the expression itself. if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) { this->expressionStack.push(expression->getSharedPointer()); } else { this->expressionStack.push(std::shared_ptr(new BinaryBooleanFunctionExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getOperatorType()))); } } template void SubstitutionVisitor::visit(BinaryNumericalFunctionExpression const* expression) { expression->getFirstOperand()->accept(this); std::shared_ptr firstExpression = expressionStack.top(); expressionStack.pop(); expression->getSecondOperand()->accept(this); std::shared_ptr secondExpression = expressionStack.top(); expressionStack.pop(); // If the arguments did not change, we simply push the expression itself. if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) { this->expressionStack.push(expression->getSharedPointer()); } else { this->expressionStack.push(std::shared_ptr(new BinaryNumericalFunctionExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getOperatorType()))); } } template void SubstitutionVisitor::visit(BinaryRelationExpression const* expression) { expression->getFirstOperand()->accept(this); std::shared_ptr firstExpression = expressionStack.top(); expressionStack.pop(); expression->getSecondOperand()->accept(this); std::shared_ptr secondExpression = expressionStack.top(); expressionStack.pop(); // If the arguments did not change, we simply push the expression itself. if (firstExpression.get() == expression->getFirstOperand().get() && secondExpression.get() == expression->getSecondOperand().get()) { this->expressionStack.push(expression->getSharedPointer()); } else { this->expressionStack.push(std::shared_ptr(new BinaryRelationExpression(expression->getReturnType(), firstExpression, secondExpression, expression->getRelationType()))); } } template void SubstitutionVisitor::visit(BooleanConstantExpression const* expression) { // If the boolean constant is in the key set of the substitution, we need to replace it. auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName()); if (nameExpressionPair != this->identifierToExpressionMap.end()) { this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer()); } else { this->expressionStack.push(expression->getSharedPointer()); } } template void SubstitutionVisitor::visit(DoubleConstantExpression const* expression) { // If the double constant is in the key set of the substitution, we need to replace it. auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName()); if (nameExpressionPair != this->identifierToExpressionMap.end()) { this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer()); } else { this->expressionStack.push(expression->getSharedPointer()); } } template void SubstitutionVisitor::visit(IntegerConstantExpression const* expression) { // If the integer constant is in the key set of the substitution, we need to replace it. auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getConstantName()); if (nameExpressionPair != this->identifierToExpressionMap.end()) { this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer()); } else { this->expressionStack.push(expression->getSharedPointer()); } } template void SubstitutionVisitor::visit(VariableExpression const* expression) { // If the variable is in the key set of the substitution, we need to replace it. auto const& nameExpressionPair = this->identifierToExpressionMap.find(expression->getVariableName()); if (nameExpressionPair != this->identifierToExpressionMap.end()) { this->expressionStack.push(nameExpressionPair->second.getBaseExpressionPointer()); } else { this->expressionStack.push(expression->getSharedPointer()); } } template void SubstitutionVisitor::visit(UnaryBooleanFunctionExpression const* expression) { expression->getOperand()->accept(this); std::shared_ptr operandExpression = expressionStack.top(); expressionStack.pop(); // If the argument did not change, we simply push the expression itself. if (operandExpression.get() == expression->getOperand().get()) { expressionStack.push(expression->getSharedPointer()); } else { expressionStack.push(std::shared_ptr(new UnaryBooleanFunctionExpression(expression->getReturnType(), operandExpression, expression->getOperatorType()))); } } template void SubstitutionVisitor::visit(UnaryNumericalFunctionExpression const* expression) { expression->getOperand()->accept(this); std::shared_ptr operandExpression = expressionStack.top(); expressionStack.pop(); // If the argument did not change, we simply push the expression itself. if (operandExpression.get() == expression->getOperand().get()) { expressionStack.push(expression->getSharedPointer()); } else { expressionStack.push(std::shared_ptr(new UnaryNumericalFunctionExpression(expression->getReturnType(), operandExpression, expression->getOperatorType()))); } } template void SubstitutionVisitor::visit(BooleanLiteralExpression const* expression) { this->expressionStack.push(expression->getSharedPointer()); } template void SubstitutionVisitor::visit(IntegerLiteralExpression const* expression) { this->expressionStack.push(expression->getSharedPointer()); } template void SubstitutionVisitor::visit(DoubleLiteralExpression const* expression) { this->expressionStack.push(expression->getSharedPointer()); } // Explicitly instantiate the class with map and unordered_map. template class SubstitutionVisitor>; template class SubstitutionVisitor>; } }