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

/*
* 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_ */