You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
8.7 KiB
228 lines
8.7 KiB
/*
|
|
* SymbolicExpressionAdapter.h
|
|
*
|
|
* Created on: 27.01.2013
|
|
* Author: Christian Dehnert
|
|
*/
|
|
|
|
#ifndef STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_
|
|
#define STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_
|
|
|
|
#include "src/ir/expressions/ExpressionVisitor.h"
|
|
#include "src/exceptions/ExpressionEvaluationException.h"
|
|
|
|
#include "cuddObj.hh"
|
|
|
|
#include <stack>
|
|
#include <iostream>
|
|
|
|
namespace storm {
|
|
|
|
namespace adapters {
|
|
|
|
class SymbolicExpressionAdapter : public storm::ir::expressions::ExpressionVisitor {
|
|
public:
|
|
SymbolicExpressionAdapter(storm::ir::Program const& program, std::unordered_map<std::string, std::vector<ADD*>>& variableToDecisionDiagramVariableMap) : program(program), stack(), variableToDecisionDiagramVariableMap(variableToDecisionDiagramVariableMap) {
|
|
|
|
}
|
|
|
|
ADD* translateExpression(std::unique_ptr<storm::ir::expressions::BaseExpression> const& expression) {
|
|
expression->accept(this);
|
|
return stack.top();
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::BinaryBooleanFunctionExpression* expression) {
|
|
expression->getLeft()->accept(this);
|
|
expression->getRight()->accept(this);
|
|
|
|
ADD* rightResult = stack.top();
|
|
stack.pop();
|
|
ADD* leftResult = stack.top();
|
|
stack.pop();
|
|
|
|
switch(expression->getFunctionType()) {
|
|
case storm::ir::expressions::BinaryBooleanFunctionExpression::AND:
|
|
stack.push(new ADD(leftResult->Times(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryBooleanFunctionExpression::OR:
|
|
stack.push(new ADD(leftResult->Plus(*rightResult)));
|
|
break;
|
|
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Unknown boolean binary operator: '" << expression->getFunctionType() << "'.";
|
|
}
|
|
|
|
// delete leftResult;
|
|
// delete rightResult;
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::BinaryNumericalFunctionExpression* expression) {
|
|
expression->getLeft()->accept(this);
|
|
expression->getRight()->accept(this);
|
|
|
|
ADD* rightResult = stack.top();
|
|
stack.pop();
|
|
ADD* leftResult = stack.top();
|
|
stack.pop();
|
|
|
|
switch(expression->getFunctionType()) {
|
|
case storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS:
|
|
stack.push(new ADD(leftResult->Plus(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS:
|
|
stack.push(new ADD(leftResult->Minus(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES:
|
|
stack.push(new ADD(leftResult->Times(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryNumericalFunctionExpression::DIVIDE:
|
|
stack.push(new ADD(leftResult->Divide(*rightResult)));
|
|
break;
|
|
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Unknown boolean binary operator: '" << expression->getFunctionType() << "'.";
|
|
}
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::BinaryRelationExpression* expression) {
|
|
expression->getLeft()->accept(this);
|
|
expression->getRight()->accept(this);
|
|
|
|
ADD* rightResult = stack.top();
|
|
stack.pop();
|
|
ADD* leftResult = stack.top();
|
|
stack.pop();
|
|
|
|
switch(expression->getRelationType()) {
|
|
case storm::ir::expressions::BinaryRelationExpression::EQUAL:
|
|
stack.push(new ADD(leftResult->Equals(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryRelationExpression::NOT_EQUAL:
|
|
stack.push(new ADD(leftResult->NotEquals(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryRelationExpression::LESS:
|
|
stack.push(new ADD(leftResult->LessThan(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL:
|
|
stack.push(new ADD(leftResult->LessThanOrEqual(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryRelationExpression::GREATER:
|
|
stack.push(new ADD(leftResult->GreaterThan(*rightResult)));
|
|
break;
|
|
case storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL:
|
|
stack.push(new ADD(leftResult->GreaterThanOrEqual(*rightResult)));
|
|
break;
|
|
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Unknown boolean binary operator: '" << expression->getRelationType() << "'.";
|
|
}
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::BooleanConstantExpression* expression) {
|
|
if (!expression->isDefined()) {
|
|
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Boolean constant '" << expression->getConstantName() << "' is undefined.";
|
|
}
|
|
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
stack.push(new ADD(*cuddUtility->getConstant(expression->getValue() ? 1 : 0)));
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::BooleanLiteralExpression* expression) {
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsBool(nullptr) ? 1 : 0)));
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::DoubleConstantExpression* expression) {
|
|
if (expression->isDefined()) {
|
|
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Double constant '" << expression->getConstantName() << "' is undefined.";
|
|
}
|
|
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
stack.push(new ADD(*cuddUtility->getConstant(expression->getValue())));
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::DoubleLiteralExpression* expression) {
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsDouble(nullptr))));
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::IntegerConstantExpression* expression) {
|
|
if (!expression->isDefined()) {
|
|
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Integer constant '" << expression->getConstantName() << "' is undefined.";
|
|
}
|
|
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
stack.push(new ADD(*cuddUtility->getConstant(static_cast<double>(expression->getValue()))));
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::IntegerLiteralExpression* expression) {
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
stack.push(new ADD(*cuddUtility->getConstant(static_cast<double>(expression->getValueAsInt(nullptr)))));
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::UnaryBooleanFunctionExpression* expression) {
|
|
expression->getChild()->accept(this);
|
|
|
|
ADD* childResult = stack.top();
|
|
stack.pop();
|
|
|
|
switch (expression->getFunctionType()) {
|
|
case storm::ir::expressions::UnaryBooleanFunctionExpression::NOT:
|
|
stack.push(new ADD(~(*childResult)));
|
|
break;
|
|
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Unknown boolean unary operator: '" << expression->getFunctionType() << "'.";
|
|
}
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::UnaryNumericalFunctionExpression* expression) {
|
|
expression->getChild()->accept(this);
|
|
|
|
ADD* childResult = stack.top();
|
|
stack.pop();
|
|
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
ADD* result = cuddUtility->getConstant(0);
|
|
switch(expression->getFunctionType()) {
|
|
case storm::ir::expressions::UnaryNumericalFunctionExpression::MINUS:
|
|
stack.push(new ADD(result->Minus(*childResult)));
|
|
break;
|
|
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
|
|
<< "Unknown numerical unary operator: '" << expression->getFunctionType() << "'.";
|
|
}
|
|
|
|
}
|
|
|
|
virtual void visit(storm::ir::expressions::VariableExpression* expression) {
|
|
storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
|
|
|
|
std::vector<ADD*> const& variables = variableToDecisionDiagramVariableMap[expression->getVariableName()];
|
|
|
|
ADD* result = cuddUtility->getConstant(0);
|
|
if (expression->getType() == storm::ir::expressions::BaseExpression::bool_) {
|
|
cuddUtility->setValueAtIndex(result, 1, variables, 1);
|
|
} else {
|
|
storm::ir::Module const& module = program.getModule(program.getModuleIndexForVariable(expression->getVariableName()));
|
|
storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(expression->getVariableName());
|
|
int64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr);
|
|
int64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr);
|
|
|
|
for (int_fast64_t i = low; i <= high; ++i) {
|
|
cuddUtility->setValueAtIndex(result, i - low, variables, static_cast<double>(i));
|
|
}
|
|
}
|
|
|
|
stack.push(result);
|
|
}
|
|
|
|
private:
|
|
storm::ir::Program const& program;
|
|
std::stack<ADD*> stack;
|
|
std::unordered_map<std::string, std::vector<ADD*>>& variableToDecisionDiagramVariableMap;
|
|
};
|
|
|
|
} // namespace adapters
|
|
|
|
} // namespace storm
|
|
|
|
#endif /* STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_ */
|