#include #include #include "src/storage/expressions/SubstitutionVisitor.h" #include "src/storage/expressions/BinaryBooleanFunctionExpression.h" #include "src/storage/expressions/BinaryNumericalFunctionExpression.h" #include "src/storage/expressions/BinaryRelationExpression.h" #include "src/storage/expressions/BooleanConstantExpression.h" #include "src/storage/expressions/IntegerConstantExpression.h" #include "src/storage/expressions/DoubleConstantExpression.h" #include "src/storage/expressions/BooleanLiteralExpression.h" #include "src/storage/expressions/IntegerLiteralExpression.h" #include "src/storage/expressions/DoubleLiteralExpression.h" #include "src/storage/expressions/VariableExpression.h" #include "src/storage/expressions/UnaryBooleanFunctionExpression.h" #include "src/storage/expressions/UnaryNumericalFunctionExpression.h" namespace storm { namespace expressions { template class MapType> SubstitutionVisitor::SubstitutionVisitor(MapType const& identifierToExpressionMap) : identifierToExpressionMap(identifierToExpressionMap) { // Intentionally left empty. } template class MapType> Expression SubstitutionVisitor::substitute(BaseExpression const* expression) { expression->accept(this); return Expression(this->expressionStack.top()); } template class MapType> 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 class MapType> 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 class MapType> 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 class MapType> 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 class MapType> 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 class MapType> 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 class MapType> 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 class MapType> 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 class MapType> 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 class MapType> void SubstitutionVisitor::visit(BooleanLiteralExpression const* expression) { this->expressionStack.push(expression->getSharedPointer()); } template class MapType> void SubstitutionVisitor::visit(IntegerLiteralExpression const* expression) { this->expressionStack.push(expression->getSharedPointer()); } template class MapType> 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; } }