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

  1. /*
  2. * SymbolicExpressionAdapter.h
  3. *
  4. * Created on: 27.01.2013
  5. * Author: Christian Dehnert
  6. */
  7. #ifndef STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_
  8. #define STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_
  9. #include "src/ir/expressions/ExpressionVisitor.h"
  10. #include "src/exceptions/ExpressionEvaluationException.h"
  11. #include "cuddObj.hh"
  12. #include <stack>
  13. #include <iostream>
  14. namespace storm {
  15. namespace adapters {
  16. class SymbolicExpressionAdapter : public storm::ir::expressions::ExpressionVisitor {
  17. public:
  18. SymbolicExpressionAdapter(storm::ir::Program const& program, std::unordered_map<std::string, std::vector<ADD*>>& variableToDecisionDiagramVariableMap) : program(program), stack(), variableToDecisionDiagramVariableMap(variableToDecisionDiagramVariableMap) {
  19. }
  20. ADD* translateExpression(std::unique_ptr<storm::ir::expressions::BaseExpression> const& expression) {
  21. expression->accept(this);
  22. return stack.top();
  23. }
  24. virtual void visit(storm::ir::expressions::BinaryBooleanFunctionExpression* expression) {
  25. expression->getLeft()->accept(this);
  26. expression->getRight()->accept(this);
  27. ADD* rightResult = stack.top();
  28. stack.pop();
  29. ADD* leftResult = stack.top();
  30. stack.pop();
  31. switch(expression->getFunctionType()) {
  32. case storm::ir::expressions::BinaryBooleanFunctionExpression::AND:
  33. stack.push(new ADD(leftResult->Times(*rightResult)));
  34. break;
  35. case storm::ir::expressions::BinaryBooleanFunctionExpression::OR:
  36. stack.push(new ADD(leftResult->Plus(*rightResult)));
  37. break;
  38. default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  39. << "Unknown boolean binary operator: '" << expression->getFunctionType() << "'.";
  40. }
  41. // delete leftResult;
  42. // delete rightResult;
  43. }
  44. virtual void visit(storm::ir::expressions::BinaryNumericalFunctionExpression* expression) {
  45. expression->getLeft()->accept(this);
  46. expression->getRight()->accept(this);
  47. ADD* rightResult = stack.top();
  48. stack.pop();
  49. ADD* leftResult = stack.top();
  50. stack.pop();
  51. switch(expression->getFunctionType()) {
  52. case storm::ir::expressions::BinaryNumericalFunctionExpression::PLUS:
  53. stack.push(new ADD(leftResult->Plus(*rightResult)));
  54. break;
  55. case storm::ir::expressions::BinaryNumericalFunctionExpression::MINUS:
  56. stack.push(new ADD(leftResult->Minus(*rightResult)));
  57. break;
  58. case storm::ir::expressions::BinaryNumericalFunctionExpression::TIMES:
  59. stack.push(new ADD(leftResult->Times(*rightResult)));
  60. break;
  61. case storm::ir::expressions::BinaryNumericalFunctionExpression::DIVIDE:
  62. stack.push(new ADD(leftResult->Divide(*rightResult)));
  63. break;
  64. default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  65. << "Unknown boolean binary operator: '" << expression->getFunctionType() << "'.";
  66. }
  67. }
  68. virtual void visit(storm::ir::expressions::BinaryRelationExpression* expression) {
  69. expression->getLeft()->accept(this);
  70. expression->getRight()->accept(this);
  71. ADD* rightResult = stack.top();
  72. stack.pop();
  73. ADD* leftResult = stack.top();
  74. stack.pop();
  75. switch(expression->getRelationType()) {
  76. case storm::ir::expressions::BinaryRelationExpression::EQUAL:
  77. stack.push(new ADD(leftResult->Equals(*rightResult)));
  78. break;
  79. case storm::ir::expressions::BinaryRelationExpression::NOT_EQUAL:
  80. stack.push(new ADD(leftResult->NotEquals(*rightResult)));
  81. break;
  82. case storm::ir::expressions::BinaryRelationExpression::LESS:
  83. stack.push(new ADD(leftResult->LessThan(*rightResult)));
  84. break;
  85. case storm::ir::expressions::BinaryRelationExpression::LESS_OR_EQUAL:
  86. stack.push(new ADD(leftResult->LessThanOrEqual(*rightResult)));
  87. break;
  88. case storm::ir::expressions::BinaryRelationExpression::GREATER:
  89. stack.push(new ADD(leftResult->GreaterThan(*rightResult)));
  90. break;
  91. case storm::ir::expressions::BinaryRelationExpression::GREATER_OR_EQUAL:
  92. stack.push(new ADD(leftResult->GreaterThanOrEqual(*rightResult)));
  93. break;
  94. default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  95. << "Unknown boolean binary operator: '" << expression->getRelationType() << "'.";
  96. }
  97. }
  98. virtual void visit(storm::ir::expressions::BooleanConstantExpression* expression) {
  99. if (!expression->isDefined()) {
  100. throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  101. << "Boolean constant '" << expression->getConstantName() << "' is undefined.";
  102. }
  103. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  104. stack.push(new ADD(*cuddUtility->getConstant(expression->getValue() ? 1 : 0)));
  105. }
  106. virtual void visit(storm::ir::expressions::BooleanLiteralExpression* expression) {
  107. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  108. stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsBool(nullptr) ? 1 : 0)));
  109. }
  110. virtual void visit(storm::ir::expressions::DoubleConstantExpression* expression) {
  111. if (expression->isDefined()) {
  112. throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  113. << "Double constant '" << expression->getConstantName() << "' is undefined.";
  114. }
  115. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  116. stack.push(new ADD(*cuddUtility->getConstant(expression->getValue())));
  117. }
  118. virtual void visit(storm::ir::expressions::DoubleLiteralExpression* expression) {
  119. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  120. stack.push(new ADD(*cuddUtility->getConstant(expression->getValueAsDouble(nullptr))));
  121. }
  122. virtual void visit(storm::ir::expressions::IntegerConstantExpression* expression) {
  123. if (!expression->isDefined()) {
  124. throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  125. << "Integer constant '" << expression->getConstantName() << "' is undefined.";
  126. }
  127. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  128. stack.push(new ADD(*cuddUtility->getConstant(static_cast<double>(expression->getValue()))));
  129. }
  130. virtual void visit(storm::ir::expressions::IntegerLiteralExpression* expression) {
  131. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  132. stack.push(new ADD(*cuddUtility->getConstant(static_cast<double>(expression->getValueAsInt(nullptr)))));
  133. }
  134. virtual void visit(storm::ir::expressions::UnaryBooleanFunctionExpression* expression) {
  135. expression->getChild()->accept(this);
  136. ADD* childResult = stack.top();
  137. stack.pop();
  138. switch (expression->getFunctionType()) {
  139. case storm::ir::expressions::UnaryBooleanFunctionExpression::NOT:
  140. stack.push(new ADD(~(*childResult)));
  141. break;
  142. default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  143. << "Unknown boolean unary operator: '" << expression->getFunctionType() << "'.";
  144. }
  145. }
  146. virtual void visit(storm::ir::expressions::UnaryNumericalFunctionExpression* expression) {
  147. expression->getChild()->accept(this);
  148. ADD* childResult = stack.top();
  149. stack.pop();
  150. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  151. ADD* result = cuddUtility->getConstant(0);
  152. switch(expression->getFunctionType()) {
  153. case storm::ir::expressions::UnaryNumericalFunctionExpression::MINUS:
  154. stack.push(new ADD(result->Minus(*childResult)));
  155. break;
  156. default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
  157. << "Unknown numerical unary operator: '" << expression->getFunctionType() << "'.";
  158. }
  159. }
  160. virtual void visit(storm::ir::expressions::VariableExpression* expression) {
  161. storm::utility::CuddUtility* cuddUtility = storm::utility::cuddUtilityInstance();
  162. std::vector<ADD*> const& variables = variableToDecisionDiagramVariableMap[expression->getVariableName()];
  163. ADD* result = cuddUtility->getConstant(0);
  164. if (expression->getType() == storm::ir::expressions::BaseExpression::bool_) {
  165. cuddUtility->setValueAtIndex(result, 1, variables, 1);
  166. } else {
  167. storm::ir::Module const& module = program.getModule(program.getModuleIndexForVariable(expression->getVariableName()));
  168. storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(expression->getVariableName());
  169. int64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr);
  170. int64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr);
  171. for (int_fast64_t i = low; i <= high; ++i) {
  172. cuddUtility->setValueAtIndex(result, i - low, variables, static_cast<double>(i));
  173. }
  174. }
  175. stack.push(result);
  176. }
  177. private:
  178. storm::ir::Program const& program;
  179. std::stack<ADD*> stack;
  180. std::unordered_map<std::string, std::vector<ADD*>>& variableToDecisionDiagramVariableMap;
  181. };
  182. } // namespace adapters
  183. } // namespace storm
  184. #endif /* STORM_ADAPTERS_SYMBOLICEXPRESSIONADAPTER_H_ */