/** * 此方法,将root涉及到的符号变量初始化为约束求解中的基本变量 * * @param root */ public void updateVariableAndPrintExpression(ExpressionNode root) { HashMap<ExpressionOperator, String> expression_operator = new HashMap<>(); expression_operator.put(ExpressionOperator.div, "\\"); expression_operator.put(ExpressionOperator.plus, "+"); expression_operator.put(ExpressionOperator.minus, "-"); expression_operator.put(ExpressionOperator.multi, "*"); if (root != null) { // if(root.operator!=null){ if (root.getType() == ExpressionType.expression) { print("("); updateVariable(root.getLeft()); // print(root.getOperator()); print(expression_operator.get(root.getOperator())); updateVariable(root.getRight()); print(")"); } else { print(root.getValue()); if (root.getType() == ExpressionType.single_variable) { String variableName = root.getValue(); if (!envVariableValueHashMap.containsKey(variableName)) { envVariableValueHashMap.put(variableName, Choco.makeIntVar(variableName)); } } } } }
// replace every x in tree by (x - vx) // i.e. replace fVar with (fvar - vx) private void translateX(ExpressionNode en, double vx, int varNo) { ExpressionValue left = en.getLeft(); ExpressionValue right = en.getRight(); // left tree if (left == fVars[varNo]) { try { // is there a constant number to the right? MyDouble num = (MyDouble) right; double temp; switch (en.getOperation()) { case ExpressionNode.PLUS: temp = num.getDouble() - vx; if (Kernel.isZero(temp)) { expression = expression.replaceAndWrap(en, fVars[varNo]); } else if (temp < 0) { en.setOperation(ExpressionNode.MINUS); num.set(-temp); } else { num.set(temp); } return; case ExpressionNode.MINUS: temp = num.getDouble() + vx; if (Kernel.isZero(temp)) { expression = expression.replaceAndWrap(en, fVars[varNo]); } else if (temp < 0) { en.setOperation(ExpressionNode.PLUS); num.set(-temp); } else { num.set(temp); } return; default: en.setLeft(shiftXnode(vx, varNo)); } } catch (Exception e) { en.setLeft(shiftXnode(vx, varNo)); } } else if (left instanceof ExpressionNode) { translateX((ExpressionNode) left, vx, varNo); } // right tree if (right == fVars[varNo]) { en.setRight(shiftXnode(vx, varNo)); } else if (right instanceof ExpressionNode) { translateX((ExpressionNode) right, vx, varNo); } }
/** * 对一个ExpressionNode建立其表达式变量并返回 * * @param root the root of a expression tree which provided by symbolic execution environment * @return */ public IntegerExpressionVariable constraintVariableModeling(ExpressionNode root) { IntegerExpressionVariable result = null; ExpressionType type = root.getType(); if (type == ExpressionType.expression) { ExpressionOperator operator = root.getOperator(); ExpressionNode leftPart = root.getLeft(); ExpressionNode rightPart = root.getRight(); ExpressionType leftType = leftPart.getType(); ExpressionType rightType = rightPart.getType(); /* * 下述步骤是将表达式递归的构建成IntegerExpressionVariable,以提供给最后的Constraint、 * 主要思路是针对左右两部分不同的类型进行表达式变量的构建,对int,variable和expression进行各种组合 * 需要注意的是在组合中没有(int, int),这是因为如果两个子节点都是int具体数值的话,那么这个表达式将是可以 * 被计算出来的,其将会被计算结果代替。这一步的工作可能在符号执行过程中完成,也可能通过一个函数对表达式树进行 * 后序遍历来完成 */ switch (operator) { case minus: { // int and variable if (leftType == ExpressionType.single_int && rightType == ExpressionType.single_variable) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); print((IntegerVariable) envVariableValueHashMap.get(rightPart.getValue())); result = Choco.minus(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.single_variable) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); print((IntegerVariable) envVariableValueHashMap.get(leftPart.getValue())); result = Choco.minus(leftValue, rightValue); } // int and expression else if (leftType == ExpressionType.single_int && rightType == ExpressionType.expression) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.minus(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.expression) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.minus(leftValue, rightValue); } // expression and variable else if (leftType == ExpressionType.expression && rightType == ExpressionType.single_variable) { IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.minus(leftValue, rightValue); } else if (rightType == ExpressionType.expression && leftType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.minus(leftValue, rightValue); } // both are expression else if (leftType == ExpressionType.expression && rightType == ExpressionType.expression) { IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.minus(leftValue, rightValue); } // both are variable else if (leftType == ExpressionType.single_variable && rightType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.minus(leftValue, rightValue); } break; } case plus: { // int and variable if (leftType == ExpressionType.single_int && rightType == ExpressionType.single_variable) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.plus(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.single_variable) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); result = Choco.plus(leftValue, rightValue); } // int and expression else if (leftType == ExpressionType.single_int && rightType == ExpressionType.expression) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.plus(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.expression) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.plus(leftValue, rightValue); } // expression and variable else if (leftType == ExpressionType.expression && rightType == ExpressionType.single_variable) { IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.plus(leftValue, rightValue); } else if (rightType == ExpressionType.expression && leftType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.plus(leftValue, rightValue); } // both are expression else if (leftType == ExpressionType.expression && rightType == ExpressionType.expression) { IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.plus(leftValue, rightValue); } // both are variable else if (leftType == ExpressionType.single_variable && rightType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.plus(leftValue, rightValue); } break; } case multi: { // int and variable if (leftType == ExpressionType.single_int && rightType == ExpressionType.single_variable) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.mult(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.single_variable) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); result = Choco.mult(leftValue, rightValue); } // int and expression else if (leftType == ExpressionType.single_int && rightType == ExpressionType.expression) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.mult(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.expression) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.mult(leftValue, rightValue); } // expression and variable else if (leftType == ExpressionType.expression && rightType == ExpressionType.single_variable) { IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.mult(leftValue, rightValue); } else if (rightType == ExpressionType.expression && leftType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.mult(leftValue, rightValue); } // both are expression else if (leftType == ExpressionType.expression && rightType == ExpressionType.expression) { IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.mult(leftValue, rightValue); } // both are variable else if (leftType == ExpressionType.single_variable && rightType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.mult(leftValue, rightValue); } break; } case div: { // int and variable if (leftType == ExpressionType.single_int && rightType == ExpressionType.single_variable) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.div(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.single_variable) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); result = Choco.div(leftValue, rightValue); } // int and expression else if (leftType == ExpressionType.single_int && rightType == ExpressionType.expression) { int leftValue = Integer.parseInt(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.div(leftValue, rightValue); } else if (rightType == ExpressionType.single_int && leftType == ExpressionType.expression) { int rightValue = Integer.parseInt(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.div(leftValue, rightValue); } // expression and variable else if (leftType == ExpressionType.expression && rightType == ExpressionType.single_variable) { IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); result = Choco.div(leftValue, rightValue); } else if (rightType == ExpressionType.expression && leftType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.div(leftValue, rightValue); } // both are expression else if (leftType == ExpressionType.expression && rightType == ExpressionType.expression) { IntegerExpressionVariable leftValue = constraintVariableModeling(leftPart); IntegerExpressionVariable rightValue = constraintVariableModeling(rightPart); result = Choco.div(leftValue, rightValue); } // both are variable else if (leftType == ExpressionType.single_variable && rightType == ExpressionType.single_variable) { IntegerVariable leftValue = (IntegerVariable) envVariableValueHashMap.get(leftPart.getValue()); IntegerVariable rightValue = (IntegerVariable) envVariableValueHashMap.get(rightPart.getValue()); result = Choco.div(leftValue, rightValue); } break; } } } else if (type == ExpressionType.single_variable) { result = (IntegerVariable) envVariableValueHashMap.get(root.getValue()); } else if (type == ExpressionType.single_int) { System.out.println("Try to make a integer into a variable: " + root.getValue()); } else { System.out.println("can't generate the cp variable" + type); } /* * 被注释掉的这段应该是用不着的 */ return result; }